【量】的修饰符
关键词:var、final、const、dynamic、object、基本数据类型
·var:接收任何类型的变量。
var xVar;
print('${xVar.runtimeType.toString()}'); // Null
xVar = 1; //赋值 int 类型
print('var输出:$xVar, 类型:${xVar.runtimeType.toString()}'); //var输出:1, 类型:int
xVar = 'Hello World!'; // 改变类型:赋值 String 类型
print('var输出:$xVar,类型:${xVar.runtimeType.toString()}'); //var输出:Hello World!,类型:String
注意:var 变量初始化时一旦赋值,类型便会确定,不能再更改为其它类型
var xVar = 1; //初始化被赋值为 int 类型,确定下类型
print('var输出:$xVar, 类型:${xVar.runtimeType.toString()}');
//编译器Error: A value of type 'String' can't be assigned to a variable of type 'int'.
xVar = 'Hello World!'; // error,不可改变其类型
print('var输出:$xVar,类型:${xVar.runtimeType.toString()}');
·final、const: 修饰的【量】不可变;
注意:
final 变量可以在运行时赋值,但只能赋值一次。
const变量在编译时就被确定,不能修改。
const x = "Hello"; //编译时被确定了,不能修改
x = 'Hello World';//error,不能再改变了
const xFinal1 = 10;
const xFinal2 = 11;
const x = xFinal1 + xFinal2; //ok,常量,编译期确定
void test(int a, int b) {
final xFinal = get(xFinal1, xFinal2); //正常,因为可以在运行时赋值一次
print('final输出:$xFinal');
}
String get(int a, int b) {
return '${a + b}';
}
·dynamic、Object:修的【量】可以在后期改变赋值类型。
注意:
dynamic:编译阶段不检查类型。若引用 dynamic 变量上不存在的方法时,编译是能通过的,但在运行时出错。
Object:编译阶段检查类型。若引用 Object 类上不存在的方法时,编译就不能通过。
dynamic x = 1;
x = 'Hello World'; //编译能通过
print('${x.length()}'); //编译能通过,但运行时error,因为没有这个方法
Object x = 42;
x = 'Hello World'; //编译能通过
print('${x.length()}'); //编译不通过
注意2:不要滥用dynamic,一般尽量使用Object
·dynamic 是编译期不检查类型的,这代表着使用ta前得先判断类型(is)然后转换成 所需要的类型,才能使用!
·object 则是编译期检查类型的,不是这个类型,使用不了,提前就警告使用者,避免错误!
那什么时候用dynamic?
·有共同的方法,但不需要判断类型的
类ClassA和ClassB,它们是两个没有任何关系的类,但是它们有两个共同的函数a,那么函数func1就能接受ClassA和ClassB的实例并且在内部调用函数a,而编译器不会对此报错。
class ClassA{
void a(){
}
}
class ClassB{
void a(){
}
}
void func1(dynamic object){
object.toString(); //(1)
object.a(); //(2)
}
void main() {
func1(ClassA());
func1(ClassB());
}
·后续代码自己处理类型判断与转换的情况
dynamic s = 'this is string';
if (s is String) {
print(s); // 打印this is string
}
s = 8;
if (s is int) {
s++; // 自动推断是int类型
print(s.toString()); // 打印9
}
·基本数据类型:Number、String、Boolean、List、Map、Runes、Symbol
-
int: 整数值不大于64位, 具体取决于平台。 在 Dart VM 上, 值的范围从 -2^63 ~ 2^63-1。 Dart 被编译为 JavaScript 时,使用 JavaScript numbers, 值的范围从 -2^53 ~ 2^53。
-
Runes:在字符串中表示 Unicode 字符
var clapping = '\u{1f44f}';
print('Runes输出:$clapping');
print('Runes输出:${clapping.codeUnits}');
print('Runes输出:${clapping.runes.toList()}');
Runes input = new Runes(
'\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print('Runes输出:${new String.fromCharCodes(input)}');
-
Symbol: Dart 程序中声明的操作符或者标识符
对于按名称引用标识符的API非常有用,特别是混淆后的代码, 标识符的名字被混淆了,但是 Symbol 的名字不会改变。
var name = 'zhuanzhuan';
Symbol symbol = #name;
print('Symbol start:---');
print(symbol);
print(#name);
print('Symbol end:---');