dart2(flutter)でasync関数がFutureを返すってところの仕様確認メモ


It is a compile-time error if the declared return type of a function marked async is not a supertype of Future for some type T.

It is a compile-time error if the declared return type of a function marked sync* is not a supertype of Iterable for some type T.

It is a compile-time error if the declared return type of a function marked async* is not a supertype of Stream for some type T.

asyncとマークされた関数の宣言された戻り値の型が、ある型Tに対してFutureのスーパータイプではない場合、コンパイル時エラーとなります。

sync*とマークされた関数の宣言された戻り値の型が、ある種の型Tに対して反復可能のスーパータイプでない場合、コンパイル時エラーとなります。

async*とマークされた関数の宣言された戻り値の型が、いくつかの型Tに対してStreamのスーパータイプではない場合、コンパイル時エラーとなります。

コンパイルエラーになるからそういうもんってことで。

void main() async {
  final ft1 = timeAfter1();
  print("ft1=$ft1");
  ft1.then((t1) {
    print("t1=$t1");
  });

  final ft2 = timeAfter2a();
  print("ft2=$ft2");
  ft2.then((t2) {
    print("t2=$t2");
  });

  final fft3 = timeAfter3b();
  print("fft3=$fft3");
  fft3.then((ft) {
    print("ft=$ft");
    ft.then((t) {
      print("t=$t");
    });
  });
}

Future<String> timeAfter1() {
  Future<String> ft = Future.delayed(Duration(seconds: 1), () {
    return DateTime.now().toIso8601String();
  });
  return ft;
}

Future<String> timeAfter2a() async {
  String t = DateTime.now().toIso8601String();
  return t; // 返り値の型はFuture<String>だけどreturnしている型はString。自動でFuture<T>にラップされる。
}

/*
Future<String> timeAfter2b() {
  String t = DateTime.now().toIso8601String();
  return t; // asyncつけないともちろんだめ
}
*/

/*
Future<Future<String>> timeAfter3a() async {
  Future<String> ft = Future.delayed(Duration(seconds: 1), () {
    return DateTime.now().toIso8601String();
  });

  return ft; // Future<String> -> Future<Future<String>> のようにラップされることはない。
}
*/

Future<Future<String>> timeAfter3b() async {
  Future<Future<String>> fft = Future.delayed(Duration(seconds: 1), () {
    Future<String> ft = Future.delayed(Duration(seconds: 1), () {
      return DateTime.now().toIso8601String();
    });
    return ft;
  });

  return fft;
}
% dart dart_async.dart
ft1=Instance of 'Future<String>'
ft2=Instance of 'Future<String>'
fft3=Instance of 'Future<Future<String>>'
t2=2020-12-17T09:03:22.237512
t1=2020-12-17T09:03:23.243016
ft=Instance of 'Future<String>'
t=2020-12-17T09:03:24.256934