Dart中的FutureOr類型的處理

今天使用Future.delayed這個方法的時候發現第二個參數是FutureOr,而後吧,以爲沒什麼大不了的只是一個普通類而已,可是用的時候發現了區別,測試代碼以下:java

import 'dart:async';

main() {
  test(FutureOr<String> computation()) {}

  test(() async {
    return "aa";
  });

  test(() {
    return "abc";
  });
}
複製代碼

看到沒,test方法的參數是FutureOr<String>類型,可是我能夠返回Future<String>也能夠返回String,是否是對於平時使用java或者kotlin的人來講比較奇怪?而後咱們能夠跳轉到FutureOr類裏看一下這個類上面的文檔描述,會發現這麼一段話,我選重要的貼一下bash

///A type representing values that are either `Future<T>` or `T`.
翻譯:這個類型至關於`Future<T>` 或者 `T`
複製代碼

算了我比較懶。。。我全貼出來本身看吧async

/// A type representing values that are either `Future<T>` or `T`.
///
/// This class declaration is a public stand-in for an internal
/// future-or-value generic type. References to this class are resolved to the
/// internal type.
///
/// It is a compile-time error for any class to extend, mix in or implement
/// `FutureOr`.
///
/// Note: the `FutureOr<T>` type is interpreted as `dynamic` in non strong-mode.
///
/// # Examples
/// ``` dart
/// // The `Future<T>.then` function takes a callback [f] that returns either
/// // an `S` or a `Future<S>`.
/// Future<S> then<S>(FutureOr<S> f(T x), ...);
///
/// // `Completer<T>.complete` takes either a `T` or `Future<T>`.
/// void complete(FutureOr<T> value);
/// ```
///
/// # Advanced
/// The `FutureOr<int>` type is actually the "type union" of the types `int` and
/// `Future<int>`. This type union is defined in such a way that
/// `FutureOr<Object>` is both a super- and sub-type of `Object` (sub-type
/// because `Object` is one of the types of the union, super-type because
/// `Object` is a super-type of both of the types of the union). Together it
/// means that `FutureOr<Object>` is equivalent to `Object`.
///
/// As a corollary, `FutureOr<Object>` is equivalent to
/// `FutureOr<FutureOr<Object>>`, `FutureOr<Future<Object>>` is equivalent to
/// `Future<Object>`.
複製代碼

簡而言之,這個類型能夠當作Future<T>或者T類型,因此在有些時候要注意,在使用FutureOr<T>執行任何有用的操做以前,一般須要檢查是否有Future<T>或明確的T。若是type參數是某個特定類型,如FutureOr<int> ,使用哪一個測試可有可無,是int仍是Future<int>。 二者都有效,由於這兩種類型是不相交的。測試

可是,若是值類型是Object或可能使用Object實例化的類型參數,則兩個分支重疊。 Future<Object>自己實現了Object,所以是Object或者是T,其中T是一些能夠用Object實例化的類型參數,即便對象是future也會返回true。 相反,明確測試Future案例:ui

Future<T> logValue<T>(FutureOr<T> value) async {
  if (value is Future<T>) {
    var result = await value;
    print(result);
    return result;
  } else {
    print(value);
    return value as T;
  }
}

複製代碼

錯誤用法示例:this

Future<T> logValue<T>(FutureOr<T> value) async {
  if (value is T) {
    print(value);
    return value;
  } else {
    var result = await value;
    print(result);
    return result;
  }
}

複製代碼

在這個糟糕的示例中,若是你向它傳遞一個Future,它會錯誤地將其視爲一個簡單的同步值。spa

相關文章
相關標籤/搜索