簡體   English   中英

Dart Generics - 類型不是子類型

[英]Dart Generics - type is not a subtype

我從 Dart 通用 function 收到運行時錯誤:

 Widget card = widget.cardBuilder(item);

其中產生:

 type '(Contact) => Widget' is not a subtype of type '(DeletableItem) => Widget'

聯系人 class 定義為

class Contact
implements DeletableItem
{

然后我有一個方法:

 class UndoableListView<T extends DeletableItem>
 {
      List<T> children;
      final Widget Function(T item) cardBuilder;

這就是發生運行時錯誤的地方

 Widget buildItem(BuildContext context, int index) {
 T item = children[index];
 Widget card = widget.cardBuilder(item);   <<<<< error thrown here.

我顯然誤解了 generics 的工作原理。

Contact 顯然擴展了 DeleteableItem。

那我做錯了什么?

Contact擴展了DeletableItem ,並且是它的子類型。

函數的參數是逆變的,所以

Widget Function(Contact)

不是的子類型

Widget Function(DeletableItem)

事實上,情況恰恰相反。

函數以這種方式運行,因為子類型化意味着可替換性。 您可以在任何需要DeletableItem的地方使用Contact (因為它實現了整個DeletableItem接口),因此ContactDeletableItem的子類型。

您可以在任何需要Widget Function(Contact) Widget Function(DeletableItem)地方使用 Widget Function(DeletableItem),因為您可以使用任何Contact調用 function(它會按預期返回Widget )。 所以Widget Function(DeletableItem)Widget Function(Contact)的子類型。

Dart generics 是協變的,盡管它並不總是正確的。

這意味着UndoableListView<Contact>UndoableListView<DeletableItem>的子類型。

問題的出現是因為cardBuilder字段在function類型中逆變使用了class類型參數,

      final Widget Function(T item) cardBuilder;

所以,當你這樣做時:

UndoableListView<DeletableItem> list = UndoableListView<Contact>();
var builder = list.cardBuilder;

你得到一個錯誤。 list.cardBuilder表達式有一個static 類型Widget Function(DeletableItem) ,但是一個運行時類型的Widget Function(Contact) ,它不是 static 類型的子類型。 這是一個類型健全性問題,編譯器知道這一點,它會插入一個類型檢查以確保builder變量不會以無效類型的值結束。

那張支票拋出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM