今天使用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