语言特征
dart 中一切皆对象dart这个特征和java很像,所有变量、方法都是对象,那怕仅仅是个数字或字符串
入口函数
在dart项目中,必须声明一个入口函数main,这也很java,程序从main函数开始运行(习惯使用js的需要注意这一点)。
void main(){ print('hello dart!') }
变量声明
- 一般声明变量必须明确类型,类型明确后不能改变,未赋值默认值都是null
int i = 2; i = '3' ; // error:i为int类型,不能赋值字符串类型
- var 可以声明任意类型的变量,赋值后类型不能再改变
var i; i = 2; i = 3; i = '4'; // error: var 变量赋值后,类型不能再改变
- dynamic 可以声明动态类型的变量,每次赋值类型不受限制
dynamic d = 1; d = '123'; // 变量类型确定后还可以再赋值其他类型
- final 变量只能赋值一次,声明时必须初始化
final a = 1; a = 2; // error: final变量只能赋值一次,再次赋值报错 final b = [2]; b[0] = 1; b.add(2); // final 虽然不能再次赋值,但是可以改变他成员变量的值
- const 变量是编译时常量,是一种特殊的final变量
const a = 1; a = 2; // error: const变量只能在初始化时赋值 const b = [2]; b.add(2); // error: const 变量中的成员变量也不可再次改变
方法
- 一般定义方法须明确入参个数、类型及出参的类型
// 方法定义,明确入参和出参,编译时可以做类型校验,提前发现一些错误 int add(int m, int n) { return m + n; } void main() { int a = add(50, 30); String b = add('50', 30); // error: 入参类型和出参类型不正确,编译不通过 }
- 如果不明确定义方法入参和出参参数类型,编译时无法进行类型检查
// 出参和入参的类型可以忽略,如果忽略,编译时无法进行类型检查 add( m, n) { return m + n; } void main() { int a = add(50, 30); String b = add('50', 30); // 可以通过编译,但在运行时会报异常 }
- 方法入参也可以使用基于命名或位置的可选参数
// 可选位置参数 // 可选参数后面不能再有参数 int add(int m, [int n]) { int sum = m; if (n != null) { sum += n; } return sum; } void main() { print(add(1)); print(add(1, 2)); }
// 可选命名参数 int add({int m, int n}) { int sum = 0; if (m != null) { sum += m; } if (n != null) { sum += n; } return sum; } void main() { print(add()); print(add(m: 1)); print(add(n: 2)); print(add(m: 1, n: 2)); }
- 定义方法入参时可以定义可选参数的默认值,默认值必须是编译时常量
// 默认参数值 // 默认值只能给可选参数设置 // 位置可选参数匹配顺序是从左到右的,即便有默认参数值 int add(int m, [int n = 0, int i]) { var sum = m + n; if (i != null) { sum += i; } return sum; } void main() { print(add(1)); print(add(1, 2)); }
- 箭头函数只能跟一个表达式,不能使用语句和代码块(前端开发人员要特别注意,和js的箭头函数不同)
// => 函数 void main() { var add = (int m, int n) => m + n; var sub = (int m, int n) => return m - m; // error: ruturn 是代码语句,箭头函数不能使用代码语句 add(1 , 2); }
- 当方法作为参数传递给高阶方法时,可以使用匿名方法
// 匿名函数 void main() { var list = ['apples', 'oranges', 'grapes', 'bananas', 'plums']; list.forEach((i) { print(list.indexOf(i).toString() + ': ' + i); }); }
- 也可以使用箭头函数为高阶方法传参
// 匿名函数 void main() { var list = ['apples', 'oranges', 'grapes', 'bananas', 'plums']; // 转换为箭头函数时,要去掉语句后面的分号, // 有分号就是语句,没有分号就变成了表达式,符合箭头函数要求 list.forEach((i) => {print(list.indexOf(i).toString() + ': ' + i)}); // 或 list.forEach((i) => print(list.indexOf(i).toString() + ': ' + i)); }
- Dart是静态作用域语言,编译时变量的作用域就已经确定(这点也和js不同,前端开发人员需注意)
// 静态作用域 int a = 5; class Test { int a = 6; int getA() { return a; } } void main() { var obj = new Test(); print(obj.getA()); // 6 var fun = obj.getA; print(fun()); // 6 }