這是閱讀此問答后的后續問題:
- 通用排序函式接受 T,但要確保 T 具有可比性
我有一個這樣的課程:
class BinarySearchTree<E extends Comparable> { ... }
所以我可以創建一個這樣的實體:
final tree = BinarySearchTree<int>();
我的問題是關于使用Comparablevs Comparable<E>。當我這樣做時:
class BinarySearchTree<E extends Comparable> { ... }
那么型別默認為E extends Comparable<dynamic>. 我通常會盡量避免dynamic,所以為了更明確地說明正在比較的型別,我似乎應該這樣寫:
class BinarySearchTree<E extends Comparable<E>> { ... }
但在這種情況下,我在這里收到錯誤訊息:
final tree = BinarySearchTree<int>();
// 'int' doesn't conform to the bound 'Comparable<int>' of the type parameter 'E'.
// Try using a type that is or is a subclass of 'Comparable<int>'.
這表明我對泛型缺乏了解。我錯過了什么?
uj5u.com熱心網友回復:
在 Dart 中,一個類不能實作通用介面的 2 個不同的具體實體:
abstract class Foo<T> {}
// error: Foo can only be implemented once
class Bar implements Foo<String>, Foo<int> {}
num實作Comparable<num>,因為內置數字型別不具有可比性會有點荒謬。但是,由于int是num( 并且因此繼承) 的子型別,因此Comparable<num>它不能具有Comparable<int>.
這導致了int不實作的稍微奇怪的結果Comparable<int>。
您面臨的問題是,從語言的角度來看,涉及兩種型別:被比較元素的型別,以及被比較元素的型別。
因此,您的型別將需要 2 個型別引數:
class Tree<T extends Comparable<S>, S> {
T get foo;
}
final intTree = Tree<int, num>();
final foo = intTree.foo; // returns an int
誠然,這不是一個超級干凈的解決方案,但如果您使用的是 Dart 2.13 或更高版本,您可以使用 typedefs 使其更好一點:
typedef IntTree = Tree<int, num>;
typedef RegularTree<T> = Tree<T, T>;
final intTree = IntTree();
final stringTree = RegularTree<String>();
intTree.foo // is an int
stringTree.foo // is a String
還有另一種選擇,就是放棄一些型別安全和使用Comparable<dynamic>,但我個人建議不要這樣做。順便說一句,如果您想避免意外丟失型別引數,您可以implicit-dynamic按照此處所述禁用:https : //dart.dev/guides/language/analysis-options#enabling-additional-type-checks
這將在任何時候dynamic從背景關系推斷型別而無需程式員實際鍵入單詞時出錯dynamic
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/331388.html
上一篇:來自鏈接/URL的Dart子字串
下一篇:凍結的建構式初始化器
