跳到主要内容
文茂权 / DaftKen
返回

Dart-类型

Dart 类型

Dart 类型的性质在 Dart 2 发布前后使截然不同的,本篇讨论了 Dart 类型的各种性质。

可选类型(Dart 2 之前)

Dart 中的可选类型的特征指的是:

Dart 是动态类型的体现在开发者可以编写完全没有类型注解的程序,而不会有任何区别。

Dart 类型注解不会影响语义。

类型注解

尽管由于可选类型的原因,类型注解不是必须的,但是类型注解仍然有很多好处:

类型推断

分析器可以推断参数的类型,一旦推断类型成为难题时,最终推断为 dynamic 。

尽管类型推断一直存在,但是如果推断的结果与开发者的意图不符合,还是应该使用显示的类型注解。

类型安全

Dart 的类型安全基于静态类型检查和运行时检查,二者确保变量值于变量的类型匹配。

void main() {
  var list = new List<TempFile>.from(
      [new TempFile(), new BankAccount()]);
  cleanUp(list);
}
void cleanUp(List<TempFile> files) =>
    files.forEach((f) => f.delete());
class TempFile {
  void delete() => print('TempFile deleted.');
}
class BankAccount {
  void delete() => print('BankAccount deleted. Whoops!');
}
// 静态分析其无法捕获这个异常

Dart 不支持函数重载

由于 Dart 中类型不会影响语义,也不会改变 Dart 代码的行为,因此函数重载也无法在 Dart 中实现,可选的代替方案是:

  1. 使用 dynamic 类型参数接收并使用 is 语句进行类型检查。
  2. 为每一个不同的函数提供不同的函数名称。
class Foo {
  void bar() => print('bar()');
  void bar(String name) => print('bar($name)');
  void bar(int number) => print('bar($number)');
}

void main() {
  dynamic foo = new Foo();
	

  // OK
  foo.bar();

  // Runtime error: Ambiguous dispatch. 2 or more implementations of `bar` exist.
  foo.bar('Hello');
}

参见 Dart 官方对函数重载的解释 https://github.com/dart-lang/sdk/issues/26488

Dart 的类型声明通常情况下只发挥了注解的功能:能够为阅读代码的人提供类型的的注释

int i ;
int j = 0;
sum(a,b) => a+b;

void main(){
  print(sum(i,j));
}
// These code will cause : NoSuchMethodError: The method '+' was called on null.

这是由于变量 i 在不进行初始化的时候分配了 null 值,此时 Null 类并没有对 + 操作符进行重载。

类型检查

Dart 2 的更新是加入了类型推断机制

通常来讲,一些事件会触发 Dart 的类型检查机制。

class Animal{
}
class Cat extends Animal{
  Cat(this.say);
  String say = "miao";
}

void main(){
  List<Animal> animals = [new Animal(),new Cat("1"),new Cat("2")];
  //  This statement will not cause an exception.
  //  We dont need a cast to state the type of animal[2];  
  Cat cat  = animals[2];
  print(cat.say);
  try{
    Cat anotherCat = animals[0];
  }catch(e){
    print(e.toString());
  }
}

接口类型

Dart 没有声明接口的语法,因为 Dart 类都存在隐式接口,任意一个类都可以使用 implements 关键字来实现一个接口。

实现一个接口可以获得一个类的实例成员,但是并不会继承接口的实现,因此实现一个接口意味着需要同时提供所有接口的具体实现。

// A person. The implicit interface contains greet().
class Person {
  // In the interface, but visible only in this library.
  final _name;

  // Not in the interface, since this is a constructor.
  Person(this._name);

  // In the interface.
  String greet(String who) => 'Hello, $who. I am $_name.';
}

// An implementation of the Person interface.
class Impostor implements Person {
  get _name => '';

  String greet(String who) => 'Hi $who. Do you know who I am?';
}

String greetBob(Person person) => person.greet('Bob');

void main() {
  print(greetBob(Person('Kathy')));
  print(greetBob(Impostor()));
}


上一篇
Dart-泛型
下一篇
Dart final & const