天津网站建设noakj,app开发公司有什么部门,芜湖网页美工设计,响应式网站 模版泛型
如果查看基本数组类型 List 的 API 文档#xff0c;您会发现该类型实际上是 ListE。 … 表示法将 List 标记为泛型#xff08;或参数化#xff09;类型——具有正式类型参数的类型。 按照惯例#xff0c;大多数类型变量的名称都是单字母的#xff0…泛型
如果查看基本数组类型 List 的 API 文档您会发现该类型实际上是 ListE。 … 表示法将 List 标记为泛型或参数化类型——具有正式类型参数的类型。 按照惯例大多数类型变量的名称都是单字母的例如 E、T、S、K 和 V。 Why use generics?
泛型通常是类型安全所必需的但泛型比仅允许代码运行有更多好处
正确指定泛型类型会生成更好的代码。使用泛型来减少代码重复。
如果你打算让一个列表只包含字符串你可以将它声明为 ListString读作“字符串列表”。
var names String[];
names.addAll([Seth, Kathy, Lars]);
names.add(42); // Error
使用泛型的另一个原因是减少代码重复。 泛型允许您在多种类型之间共享单一接口和实现同时仍然利用静态分析。 例如假设您创建了一个用于缓存对象的接口
abstract class ObjectCache {Object getByKey(String key);void setByKey(String key, Object value);
}
需要此接口的特定于字符串的版本因此您创建了另一个接口
abstract class StringCache {String getByKey(String key);void setByKey(String key, String value);
} 通用类型可以省去创建所有这些接口的麻烦。 相反您可以创建一个带有类型参数的接口
abstract class CacheT {T getByKey(String key);void setByKey(String key, T value);
} 在此代码中T 是替代类型。 它是一个占位符您可以将其视为开发人员稍后定义的类型。
Using collection literals 列表、集合和映射文字可以参数化。 参数化文字就像已经看到的文字一样除了在左括号之前添加 type对于列表和集合或 keyType, valueType对于Map。 下面是一个使用类型文字的例子
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
}; Using parameterized types with constructors将参数化类型与构造函数一起使用
var views Mapint, View(); 以下代码创建一个具有整数键和视图类型值的映射
var nameSet SetString.from(names);
void main() {var names [aa, bb, cc, aa];var nameSet SetString.from(names);print(nameSet);
}Log
{aa, bb, cc}
Generic collections and the types they contain通用集合及其包含的类型
Dart 泛型类型是具体化的这意味着它们在运行时携带它们的类型信息。 例如可以测试集合的类型
var names String[];
names.addAll([Seth, Kathy, Lars]);
print(names is ListString); // true 注意相比之下Java 中的泛型使用擦除这意味着在运行时删除泛型类型参数。 在 Java 中你可以测试一个对象是否是一个 List但你不能测试它是否是一个 ListString。 Restricting the parameterized type(限制参数化类型)
在实现泛型类型时您可能希望限制可以作为参数提供的类型以便参数必须是特定类型的子类型。 您可以使用扩展来做到这一点。
一个常见的用例是通过使类型成为 Object 的子类型而不是默认的 Object来确保类型不可为 null。
class FooT extends Object {// Any type provided to Foo for T must be non-nullable.
} 除了 Object 之外还可以将 extends 与其他类型一起使用。 下面是一个扩展 SomeBaseClass 的例子这样 SomeBaseClass 的成员就可以在类型 T 的对象上被调用
class FooT extends SomeBaseClass {// Implementation goes here...String toString() Instance of Foo$T;
}class Extender extends SomeBaseClass {...} 可以使用 SomeBaseClass 或其任何子类型作为泛型参数
var someBaseClassFoo FooSomeBaseClass();
var extenderFoo FooExtender(); 也可以不指定泛型参数
var foo Foo();
print(foo); // Instance of FooSomeBaseClass 指定任何非 SomeBaseClass 类型都会导致错误.
var foo FooObject(); //会报错 Using generic methods 使用泛型方法
方法和函数也允许类型参数
T firstT(ListT ts) {// Do some initial work or error checking, then...T tmp ts[0];// Do some additional checking or processing...return tmp;
} 在这里第一个 (T) 上的泛型类型参数允许在多个地方使用类型参数 T
在函数的返回类型 (T) 中。在参数类型 (ListT) 中。在局部变量 (T tmp) 的类型中。Libraries and visibility
import 和 library 指令可以帮助您创建模块化和可共享的代码库。 库不仅提供 API还是一个隐私单元以下划线 (_) 开头的标识符仅在库内部可见。 每个 Dart 应用程序都是一个库即使它不使用库指令。
可以使用包来分发库。
如果您好奇为什么 Dart 使用下划线而不是访问修饰符关键字如 public 或 private请参阅 SDK 问题 33383。Add public and private access modifiers to language · Issue #33383 · dart-lang/sdk · GitHub Using libraries
使用 import 指定如何在另一个库的范围内使用一个库中的命名空间。
例如Dart web 应用程序通常使用 dart:html 库它们可以像这样导入
import dart:html; import 唯一需要的参数是指定库的 URI。 对于内置库URI 具有特殊的 dart: 方案。 对于其他库您可以使用文件系统路径或 package: 方案。 package: scheme 指定包管理器例如 pub 工具提供的库。 例如
import package:test/test.dart; 注意URI 代表统一资源标识符。 URL统一资源定位符是一种常见的 URI。 Specifying a library prefix
如果导入两个具有冲突标识符的库那么可以为一个或两个库指定一个前缀。 例如如果 library1 和 library2 都有一个 Element 类那么可能有这样的代码
import package:lib1/lib1.dart;
import package:lib2/lib2.dart as lib2;// Uses Element from lib1.
Element element1 Element();// Uses Element from lib2.
lib2.Element element2 lib2.Element(); Importing only part of a library
如果只想使用库的一部分可以有选择地导入库。 例如
延迟加载也称为延迟加载允许 Web 应用程序在需要库时按需加载库。 以下是您可能会使用延迟加载的一些情况
减少web app的初始启动时间。执行 A/B 测试——例如尝试算法的替代实现。加载很少使用的功能例如可选屏幕和对话框。
只有dart compile js支持延迟加载。 Flutter 和 Dart VM 不支持延迟加载。 要了解更多信息请参阅问题 #33118 和问题 #27776。
https://github.com/dart-lang/sdk/issues/33118
https://github.com/dart-lang/sdk/issues/27776
要延迟加载库您必须首先使用 deferred as 导入它。
import package:greetings/hello.dart deferred as hello;
当您需要库时使用库的标识符调用 loadLibrary()。
Futurevoid greet() async {await hello.loadLibrary();hello.printGreeting();
} 等待关键字暂停执行直到加载库。 有关异步和等待的更多信息请参阅异步支持。
可以在库上多次调用 loadLibrary() 而不会出现问题。 该库仅加载一次。
使用延迟加载时请记住以下几点
延迟库的常量不是导入文件中的常量。 请记住这些常量在加载延迟库之前不存在。您不能在导入文件中使用延迟库中的类型。 相反考虑将接口类型移动到由延迟库和导入文件导入的库。Dart 隐式地将 loadLibrary() 插入到您使用 deferred 作为命名空间定义的命名空间中。 loadLibrary() 函数返回一个 Future。
The library directive
要指定库级别的文档注释或元数据注释请将它们附加到文件开头的库声明中。
/// A really great test library.
TestOn(browser)
library; Implementing libraries
有关如何实施库包的建议请参阅创建库包包括Creating packages | Dart
如何组织库源代码。如何使用导出指令。何时使用 part 指令。如何使用条件导入和导出来实现支持多个平台的库。