为什么在输入()=>字符串而不是()=> void时,dart类型系统不会抱怨?

时间:2019-06-07 11:23:41

标签: dart

这绝对不是关键问题,但我仍然想知道为什么会编译并起作用:

String stringReturningHandler() {
  print("clicked");
  return 'crash';
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Test'),
      ),
      body: Center(
          child: OutlineButton(
            child: Text('Click me'),
            onPressed: stringReturningHandler,
          )
      ),
    );
  }
}

考虑到OutlineButtononPressed定义为: @required VoidCallback onPressed,

typedef VoidCallback = void Function();

1 个答案:

答案 0 :(得分:1)

在像C这样的语言中,void函数是一个过程,它不返回任何内容,并且与非void函数不同。在Dart中并非如此。

Dart中的所有函数都返回值,甚至是void函数。这就是动态调用的后果之一:

dynamic something = print;
dynamic result = something("else");

此代码应成功运行,因此调用something(实际上是带有签名print的{​​{1}}函数)的结果必须是一个值。我们不知道哪个,但是一定是某物。 (实际上是void Function(String))。

此外,由于Dart具有泛型,并且您有时想对返回类型进行抽象,因此null在各处都被视为适当的类型,这就是允许void的原因。将来的是对计算结果的抽象-返回值。

因此,类型Future<void>void Function()并不完全不同。 String Function()的含义是“返回不可以使用的值的函数”。换句话说,就是“一个没人在乎的函数”(因为没人会使用它)。

在Dart中,类型void Function()String Function()的子类型。您可以在没人关心返回内容的地方使用返回字符串的函数。 这就是为什么没人抱怨void Function()用于需要零参数的函数,而没人关心它返回什么的原因。

Dart始终允许您在子类中用非stringReturningHandler返回函数覆盖void返回函数,这是另一种查看非{ void返回函数是一个子类型。