dynamic 在 dart 中自由度最大。 让 dart 具有充分的灵活性。如果所有变量都用 dynamic,相当于完全放弃类型检查。
以下示例基于 dart sdk 2.15.1 开启空安全
- dynamic 声明的变量如果没有初始化,默认为 null。
dynamic a; print(a); // null print(a.runtimeType) // Null 复制代码
- dynamic 声明的变量如果初始化,则会获得初始值,值和值的类型都是可以修改的。
dynamic a=1; print(a); // 1 print(a.runtimeType) // int a='hello'; print(a); // hello print(a.runtimeType) // String 复制代码
- dynamic 声明的变量可以调用任何属性和方法,不会被警告,因为编译器不会对 dynamic 声明的变量在编译阶段进行检查,直到运行时才会报错。
dynamic a=1; a.b(); // 如果不运行不会看到任何错误提示 print(a.b); // 如果不运行不会看到任何错误提示 复制代码
- dynamic 声明的变量可以赋值给其它变量,但是如果类型不同,运行时会报错
dynamic a=1; int b=2; b=a; print(b); // 1 String s='a'; s=a; // 运行时报错。 复制代码
- 在得知 dynamic 类型后,可以转换。
dynamic a=1; if(a is int) a = a as int; // ok a= a as String //运行时报错; 复制代码
- 函数如果没有定义返回值类型,返回的类型为 dynamic, 值为 null 。 dynamic 写不写都一样。
a(){} dynamic a(){} 复制代码
- 对于类中的方法也是一样的,默认返回 dynamic
abstract class Animal{ eat(); } class Dog extends Animal{ @override String eat(){return 'meat';} } var dog=Dog(); print(dog.eat()) // meat 复制代码
在 Animal中 方法 eat 返回 dynamic,子类中的 eat 返回 String 是可以的。写上 dynamic 也是可以的。
abstract class Animal{ dynamic eat(); } class Dog extends Animal{ @override String eat(){return 'meat';} } 复制代码
8 函数参数如果没有指定类型也是dynamic
a(val){ return val; } print(a(1)) // 1 print(a('a')) // a 复制代码
总之 dynamic 让 dart 在编译时放弃类型检查,只有在运行时才会做类型判断。如果父类没有定义方法的返回值类型,子类可以随意定义方法的返回值类型。