Flutter SQFLITE:请解释一下工厂和这个数据类型 Future<List<Trail>> 是啥意思

Posted

技术标签:

【中文标题】Flutter SQFLITE:请解释一下工厂和这个数据类型 Future<List<Trail>> 是啥意思【英文标题】:Flutter SQFLITE: Please explain what factory and this data type Future<List<Trail>> meansFlutter SQFLITE:请解释一下工厂和这个数据类型 Future<List<Trail>> 是什么意思 【发布时间】:2021-10-02 02:26:52 【问题描述】:

我正试图让 SQFlite 在颤振中工作。

我是 Flutter 的新手,在 null 安全性和我不熟悉的新类型方面存在一些烦人的问题。

最重要的问题..有时它说“列表不是一种类型”,它肯定是。

我自己的代码位于这里 https://github.com/bksubhuti/places

我想将它连接到 futurebuilder 或 listbuilder UI。

这是一个学习应用程序,但也是一个用于以后生产的应用程序。 最终我想基于 SQFlite 和 Flutter 重写读书应用程序(Tipitaka Pali Projector)。

按照有关路径的教程进行操作。代码在github上。 https://github.com/nhandrew/sqflite_app/blob/main/lib/main.dart

它不适用于 null 安全

还有一个狗教程的其他代码,它是flutter sqlite的官方教程..我不明白这个代码 代码位于此链接这里

狗教程也有类似的语法,这对我来说是新的。 https://github.com/flutter/website/blob/master/src/docs/cookbook/persistence/sqlite.md

我对工厂和这个数据类型 Future 感到困惑 我以前从未见过这种东西。

它还必须在 null 安全下工作。

这是这里的这部分..那是混乱

 factory Trail.fromJson(Map<String,dynamic> json)
return Trail(  
  name: json['name'],
  difficulty: json['difficulty'],
  distance: json['distance']
);

 Widget build(BuildContext context) 
return Scaffold(  
  appBar: AppBar(),
  body: FutureBuilder<List<Trail>>(
    future: dbService.getTrails(),
    builder: (context, snapshot) 
      if (!snapshot.hasData) return Center(child: CircularProgressIndicator(),);
      return ListView.builder(
        itemCount: snapshot.data.length,
        itemBuilder: (context, index)
          return ListTile(
            title: Text(snapshot.data[index].name),
            leading: Text(snapshot.data[index].difficulty),
            trailing: Text(snapshot.data[index].distance.toString()),
          );
        );
    
  )
);

  Future<List<Trail>> getTrails() async 
await initDatabase();
List<Map> list = await _db.rawQuery('SELECT * FROM Trails');
return list.map((trail) => Trail.fromJson(trail)).toList();

【问题讨论】:

【参考方案1】:

我建议你阅读 Dart 语言之旅:

https://dart.dev/guides/language/language-tour

您可以在此处找到有关您的问题的详细信息:

https://dart.dev/guides/language/language-tour#factory-constructors

https://dart.dev/guides/language/language-tour#generics

https://dart.dev/guides/language/language-tour#asynchrony-support

https://dart.dev/guides/language/language-tour#lists

我将编辑我的答案,以提供您在评论中提出的答案。

那么,让我们解开这部分:

Future<List<Trail>> getTrails() async 
await initDatabase();
List<Map> list = await _db.rawQuery('SELECT * FROM Trails');
return list.map((trail) => Trail.fromJson(trail)).toList();

首先 - 该函数是异步的(如 async 关键字所示)。这意味着几件事:这个函数将能够与其他事物并行运行。这在技术上不是 100% 正确的,但现在让我们把它留在这个级别。 这种并行运行是通过函数立即返回一个Future 对象,然后将函数值返回到这个Future 对象中来实现的。 (实际上 Future 在第一次命中 await 语句时返回,但现在忽略它)。 可以把它想象成在餐馆点菜:你点了菜,服务员立刻把一个空盘子放在你面前(盘子是 Future 对象)。在等你的晚餐时,你可以做其他事情——去洗手间,喝点饮料等。最终,食物会出现在你的盘子里。食物是未来最终会持有的对象。 我在这里试图简单地解释一个非常复杂的主题 - 你应该单独了解这个,它真的会对你有很大帮助。很多。

所以这有点解释了这意味着什么:Future&lt;List&lt;Trail&gt;&gt;。您的函数将立即返回一个 Future 对象。但不是任何 Future 对象,而是函数完成后将保存特定返回值的对象。该值将是 List 类型:但不是任何 List 类型 - 它将包含一个仅包含 Trail 对象值的列表。因此 List 被定义为 List&lt;Trail&gt;(Trail 对象列表),Future 是 Future&lt;List&lt;Trail&gt;&gt; - 一个保存 Trail 对象列表的 Future。

接下来,您拨打await initDatabase();。您的 initDatabase 本身是异步的,它为您提供了在等待数据库初始化时运行其他一些东西的选项。你可以举个例子:

var i=initDatabase();
print('Doing some work while database is being initialized');
await i; // now I'm done, nothing for me to do until the database initialized, so I'll just wait for that
List<Map> list =...

再一次 - 在这里您确实需要了解您的 async/await 和 Future(或在 javascript 中调用的 Promises)。

其余的应该很容易:

List<Map> list = await _db.rawQuery('SELECT * FROM Trails');

您的 rawQuery 是异步的 - 您决定等待它,因为在查询完成之前您无事可做。该查询将返回一个列表 - 假设这里它将是一个数据库行列表。每个 Row 都以 Map 对象的形式呈现,因此 List 不会是任何列表 - 而是 Map 列表:List&lt;Map&gt;

最后 - 您将查询返回的 List&lt;Map&gt; 转换为 List&lt;Trail&gt; - 因为这是您应该返回的值。记住——函数返回Future&lt;List&lt;Trail&gt;&gt;,所以你的最终return语句需要返回List&lt;Trail&gt;。请记住:调用函数时,Future 已经返回。

【讨论】:

你能用eh尖括号解释数据类型吗? >。 Future> getTrails() async await initDatabase(); List list = await _db.rawQuery('SELECT * FROM Trails'); return list.map((trail) => Trail.fromJson(trail)).toList(); 我用更多细节扩展了我的答案,希望对您有所帮助。 这解释了很多。我很感激.. 我可以理解 List 对象和 Future 类型(似乎类似于 c++ 模板 List),但是编译器抱怨有一个双重类型转换,这让我感到困惑是根本问题。 final List> 这是狗和其他 sqlite 教程从 sqlite.query 调用中接受的内容 项目github.com/nhandrew/sqflite_app 如果您下载并编译它就可以正常工作。但是,有一些 mak 设置(不确定在哪里)导致该项目以低严格度编译。如果我能获得以类似方式执行 sqlite DB 的任何项目,但具有所有空值安全性,那就太好了。如果它不编译,我什么都学不到。如果您查看我发布的 github 问题,如果您只是复制基本文件 yml 文件 lib/assets/,则它不起作用

以上是关于Flutter SQFLITE:请解释一下工厂和这个数据类型 Future<List<Trail>> 是啥意思的主要内容,如果未能解决你的问题,请参考以下文章

使用 Flutter 插入 sqflite 时出现问题

Flutter Provider 和 sqflite 集成

如何在 Flutter 中使用 sqflite 插入特殊字符?

Flutter 应用中提供程序与 sqflite 的集成

Flutter中的Sqflite,使用两个数据库(附件)

Flutter sqflite 打开现有数据库