Dart 导航器上then方法的语法问题

Dart 导航器上then方法的语法问题,dart,flutter,Dart,Flutter,我有以下代码片段: \u openEditListingDialog(列表, 函数(列表)onSubmittedCallback(异步){ 领航员 .of(上下文) .推( 新材料路线( 生成器:(BuildContext上下文){ 返回新列表对话框。编辑(列表); }, fullscreenDialog:true, ), ) .然后((列出新条目){ if(newEntry!=null){ newEntry.id=listing.id; onSubmittedCallback(新条目); }

我有以下代码片段:

\u openEditListingDialog(列表,
函数(列表)onSubmittedCallback(异步){
领航员
.of(上下文)
.推(
新材料路线(
生成器:(BuildContext上下文){
返回新列表对话框。编辑(列表);
},
fullscreenDialog:true,
),
)
.然后((列出新条目){
if(newEntry!=null){
newEntry.id=listing.id;
onSubmittedCallback(新条目);
}
});
}
VSCode在上投诉。然后行出现以下错误:

[dart] The argument type '(Listing) -> Null' can't be assigned to the parameter type '(Object) -> FutureOr<Null>'.
[dart]参数类型“(列表)->Null”不能分配给参数类型“(对象)->FutureOr”。
这是什么意思?我该如何纠正?我不熟悉飞镖和颤栗,像这样的错误信息对我来说很神秘。我的代码基于以下示例:。

传递函数

Function(Listing) onSubmittedCallback) async {
  // no return here
});
这意味着Dart推断返回类型
Null

我想把它改成

FutureOr<Null> Function(Listing) onSubmittedCallback) async =>

TBH我不确定为什么VS代码会将其标记为错误-我看不出它有任何实质性的错误,我的VS代码或IntelliJ也没有。我粘贴了你的代码,在添加了一个列表类之后,我一点问题都没有(作为记录,如果你粘贴了足够多的代码,当你遇到问题时,有人可以实际运行一些东西,这会让他们更容易帮助你)

在这种特殊情况下,错误的行号可能非常有用

也许要确保你的VS代码和颤振是最新的(我正在使用主通道/分支,它已经更新到dart 2.0,所以这可能是它的一部分…)

有几件事你可以试试。首先,您的
push
方法似乎没有选择正确的类型-我很确定您看到的错误在
处。然后(…
在它期望和对象的位置,您告诉它是一个列表。您可以将
更改为
。push
以强制它返回列表

接下来,我不太熟悉您对函数(清单)所做的操作。我认为这不是正确的dart,至少不再是。我认为推荐的方法是使用正确的参数类型键入一个方法,即
typedef void ListingCallback(清单清单)
然后使用它作为参数,如果您要使用回调(请参阅后面的答案中的一个更好的替代方法)

另一件你做错了的事,许多人在dart/FLART中一开始似乎都是这样做的,那就是错误地使用了
async
。如果你在方法签名中使用
async
,你不应该使用
。然后使用
,而应该使用
等待
。请看,这是有效的dart的一部分。我已经重新编写了你的代码来实现这一点rly:

//outside class somewhere
typedef void ListingCallback(Listing listing);

...

  _openEditListingDialog(
      Listing listing, ListingCallback onSubmittedCallback) async {
    Listing newEntry = await Navigator.of(context).push<Listing>(
          new MaterialPageRoute<Listing>(
            builder: (BuildContext context) {
              return new ListingDialog.edit(listing);
            },
            fullscreenDialog: true,
          ),
        );

    if (newEntry != null) {
      newEntry.id = listing.id;
      onSubmittedCallback(newEntry);
    }
  }

更改了它,但仍然不好。我不确定是否同意您的解释。我的理解是,push(Route)应该返回Future,在这种情况下,它应该是Future,然后应该接受Future(dynamic onValue(T value)).我真的不理解你的评论。你收到错误消息了吗?你尝试过我的答案的哪些变体?我不认为函数(…)与他遇到的问题有任何关系。谢谢@rmtmckenzie。你的第一个示例非常有效,解决了我的问题。我不必强制推送返回列表,在移动一些换行符后,代码对我来说可读性更强(我来自C#background)。我还对您将来的示例感兴趣,该示例将避免回调。我假定_openEditListingDialog的结果将通过result=wait _openEditListingDialog(…)访问,对吗?是的,这是正确的。只需确保将调用它的函数安全地转换为异步函数-例如,如果将
void initState
更改为
Future(void)initState
,它可能不会显示语法错误,但在运行时会出现问题。(请查看是否遇到此问题)。请注意,即使返回未来,也可以使用
\u openEditListingDialog(…)。然后((listing){..做任何事情)
//outside class somewhere
typedef void ListingCallback(Listing listing);

...

  _openEditListingDialog(
      Listing listing, ListingCallback onSubmittedCallback) async {
    Listing newEntry = await Navigator.of(context).push<Listing>(
          new MaterialPageRoute<Listing>(
            builder: (BuildContext context) {
              return new ListingDialog.edit(listing);
            },
            fullscreenDialog: true,
          ),
        );

    if (newEntry != null) {
      newEntry.id = listing.id;
      onSubmittedCallback(newEntry);
    }
  }
  Future<Listing> _openEditListingDialog(Listing listing) async {
    Listing newEntry = await Navigator.of(context).push<Listing>(
          new MaterialPageRoute<Listing>(
            builder: (BuildContext context) {
              return new ListingDialog.edit(listing);
            },
            fullscreenDialog: true,
          ),
        );

    if (newEntry != null) {
      newEntry.id = listing.id;
    }

    return newEntry;
  }