99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

泛型

2020-02-03 23:38 更新

在 API 文檔中你會(huì)發(fā)現(xiàn)基礎(chǔ)數(shù)組類型 List 的實(shí)際類型是 List<E> 。 <…> 符號(hào)將 List 標(biāo)記為 泛型 (或 參數(shù)化) 類型。 這種類型具有形式化的參數(shù)。 通常情況下,使用一個(gè)字母來(lái)代表類型參數(shù), 例如 E, T, S, K, 和 V 等。


為什么使用泛型

在類型安全上通常需要泛型支持, 它的好處不僅僅是保證代碼的正常運(yùn)行:

  • 正確指定泛型類型可以提高代碼質(zhì)量。
  • 使用泛型可以減少重復(fù)的代碼。

如果想讓 List 僅僅支持字符串類型, 可以將其聲明為 List<String> (讀作“字符串類型的 list ”)。 那么,當(dāng)一個(gè)非字符串被賦值給了這個(gè) list 時(shí),開發(fā)工具就能夠檢測(cè)到這樣的做法可能存在錯(cuò)誤。 例如:

var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
names.add(42); // 錯(cuò)誤

另外一個(gè)使用泛型的原因是減少重復(fù)的代碼。 泛型可以在多種類型之間定義同一個(gè)實(shí)現(xiàn), 同時(shí)還可以繼續(xù)使用檢查模式和靜態(tài)分析工具提供的代碼分析功能。 例如,假設(shè)你創(chuàng)建了一個(gè)用于緩存對(duì)象的接口:

abstract class ObjectCache {
  Object getByKey(String key);
  void setByKey(String key, Object value);
}

后來(lái)發(fā)現(xiàn)需要一個(gè)相同功能的字符串類型接口,因此又創(chuàng)建了另一個(gè)接口:

abstract class StringCache {
  String getByKey(String key);
  void setByKey(String key, String value);
}

后來(lái),又發(fā)現(xiàn)需要一個(gè)相同功能的數(shù)字類型接口 … 這里你應(yīng)該明白了。

泛型可以省去創(chuàng)建所有這些接口的麻煩。 通過(guò)創(chuàng)建一個(gè)帶有泛型參數(shù)的接口,來(lái)代替上述接口:

abstract class Cache<T> {
  T getByKey(String key);
  void setByKey(String key, T value);
}

在上面的代碼中,T 是一個(gè)備用類型。 這是一個(gè)類型占位符,在開發(fā)者調(diào)用該接口的時(shí)候會(huì)指定具體類型。


使用集合字面量

List , Set 和 Map 字面量也是可以參數(shù)化的。 參數(shù)化字面量和之前的字面量定義類似, 對(duì)于 List 或 Set 只需要在聲明語(yǔ)句前加 <type> 前綴, 對(duì)于 Map 只需要在聲明語(yǔ)句前加 <keyType, valueType> 前綴, 下面是參數(shù)化字面量的示例:

var names = <String>['Seth', 'Kathy', 'Lars'];
var uniqueNames = <String>{'Seth', 'Kathy', 'Lars'};
var pages = <String, String>{
  'index.html': 'Homepage',
  'robots.txt': 'Hints for web robots',
  'humans.txt': 'We are people, not machines'
};


使用泛型類型的構(gòu)造函數(shù)

在調(diào)用構(gòu)造函數(shù)的時(shí),在類名字后面使用尖括號(hào)(<...>)來(lái)指定泛型類型。 例如:

var nameSet = Set<String>.from(names);

下面代碼創(chuàng)建了一個(gè) key 為 integer, value 為 View 的 map 對(duì)象:

var views = Map<int, View>();


運(yùn)行時(shí)中的泛型集合

Dart 中泛型類型是 固化的,也就是說(shuō)它們?cè)谶\(yùn)行時(shí)是攜帶著類型信息的。 例如, 在運(yùn)行時(shí)檢測(cè)集合的類型:

var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
print(names is List<String>); // true

提示: 相反,Java中的泛型會(huì)被 擦除 ,也就是說(shuō)在運(yùn)行時(shí)泛型類型參數(shù)的信息是不存在的。 在Java中,可以測(cè)試對(duì)象是否為 List 類型, 但無(wú)法測(cè)試它是否為 List<String> 。


限制泛型類型

使用泛型類型的時(shí)候, 可以使用 extends 實(shí)現(xiàn)參數(shù)類型的限制。

class Foo<T extends SomeBaseClass> {
  // Implementation goes here...
  String toString() => "Instance of 'Foo<$T>'";
}

class Extender extends SomeBaseClass {...}

可以使用 SomeBaseClass 或其任意子類作為通用參數(shù):

var someBaseClassFoo = Foo<SomeBaseClass>();
var extenderFoo = Foo<Extender>();

也可以不指定泛型參數(shù):

var foo = Foo();
print(foo); // Instance of 'Foo<SomeBaseClass>'

指定任何非 SomeBaseClass 類型會(huì)導(dǎo)致錯(cuò)誤:

var foo = Foo<Object>();


使用泛型函數(shù)

最初,Dart 的泛型只能用于類。 新語(yǔ)法_泛型方法_,允許在方法和函數(shù)上使用類型參數(shù):

T first<T>(List<T> ts) {
  // Do some initial work or error checking, then...
  T tmp = ts[0];
  // Do some additional checking or processing...
  return tmp;
}

這里的 first (<T>) 泛型可以在如下地方使用參數(shù) T :

  • 函數(shù)的返回值類型 (T).
  • 參數(shù)的類型 (List<T>).
  • 局部變量的類型 (T tmp).

關(guān)于泛型的更多信息,參考使用泛型函數(shù)

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)