[TOC] ## 变量 ``` var name = 'Bob'; //类型推导出 string 类型 String name = 'Bob'; //显示声明 var v1=1; var v2="hello"; var v3=3.3; var v4=true; var v5=[1, 2, 3]; const c1=1; const c2="hello"; const c3=3.3; const c4=true; const c5 = [1, 2, 3]; ``` ## 默认值 未初始化的变量默认值是 null,数字也是null,因为一切皆对象 ``` int lineCount ; assert(lineCount == null); ``` ## Number int * 整数值不大于64位 * 值的范围从 -263 到 263 - 1 float * 64位(双精度)浮点数 方法 * abs(), ceil(), 和 floor() ``` //生成整数 var x = 1; var hex = 0xDEADBEEF; //浮点数 var y = 1.1; var exponents = 1.42e5; //从 Dart 2.1 int 必要时会转为 float double z = 1; // 相当于 double z = 1.0. ``` ### 位运算 ``` assert((3 << 1) == 6); // 0011 << 1 == 0110 assert((3 >> 1) == 1); // 0011 >> 1 == 0001 assert((3 | 4) == 7); // 0011 | 0100 == 0111 ``` ### 字符串,为数字相互转换 ``` // String -> int var one = int.parse('1'); assert(one == 1); // String -> double var onePointOne = double.parse('1.1'); assert(onePointOne == 1.1); // int -> String String oneAsString = 1.toString(); assert(oneAsString == '1'); // double -> String String piAsString = 3.14159.toStringAsFixed(2); assert(piAsString == '3.14'); ``` ## String UTF-16 单元序列。 字符串通过单引号或者双引号创建 ``` var s1 = 'Single quotes work well for string literals.'; var s2 = "Double quotes work just as well."; var s3=""" hello word """; var s4 ="hello "+"word"; var s = r"hello \n word"; // \b 不转义 ``` ### ${expression} 嵌入字符串 ``` var a ="hello"; print('${a} word'); // hello word print("${a} word"); // hello word ``` ## Boolean 不同类型检查 boo 的方法 ``` // 检查空字符串。 var fullName = ''; assert(fullName.isEmpty); // 检查 0 值。 var hitPoints = 0; assert(hitPoints <= 0); // 检查 null 值。 var unicorn; assert(unicorn == null); // 检查 NaN 。 var iMeantToDoThis = 0 / 0; assert(iMeantToDoThis.isNaN); ``` ## List 数组 ``` var a= [1, 2, 3]; //等效 List<int> a =[1,2,3]; //长度 a.length ``` 常量赋值 ``` var constantList = const [1, 2, 3]; // constantList[1] = 1; // 取消注释会引起错误。 constantList=[1,3,3]; //可以整体替换 ``` ## Set 唯一且无序的值 方法 * add(), addAll() 属性 * .length 实例 ``` var a =<String>{}; a.add("a"); a.addAll({"b","c"}); a.remove("b"); // a.clear(); // 清空所有 print(a.contains("c")); // true 是否包含c print(a.first);//a ``` ``` var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'}; //等效 Set<String> halogens1= {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'}; ``` ### 创建空集 ``` var names = <String>{}; // Set<String> names = {}; // 这样也是可以的。 // var names = {}; // 这样会创建一个 Map ,而不是 Set 。 ``` ### 设置 编译时常量 ``` final constantSet = const { 'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine', }; // constantSet.add('helium'); // Uncommenting this causes an error. ``` ## Map k-v 类型 ``` //类型推导为 Map<String, String> var gifts = { // Key: Value 'first': 'partridge', 'second': 'turtledoves', 'fifth': 'golden rings' }; //类型推导为 Map<int, String> var nobleGases = { 2: 'helium', 10: 'neon', 18: 'argon', }; final constantMap = const { 2: 'helium', 10: 'neon', 18: 'argon', }; ``` 基本操作 ``` //赋值 gifts['first'] = 'calling birds'; // Add a key-value pair //取值 assert(gifts['first'] == 'partridge'); ``` ## Rune Rune 用来表示字符串中的 UTF-32 编码字符,由于 Dart 字符串是一系列 UTF-16 编码单元, 因此要在字符串中表示32位 Unicode 值需要特殊语法支持 ``` main() { var clapping = '\u{1f44f}'; print(clapping); print(clapping.codeUnits); print(clapping.runes.toList()); Runes input = new Runes( '\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}'); print(new String.fromCharCodes(input)); } //output 👏 [55357, 56399] [128079] ♥ 😅 😎 👻 🖖 👍 ``` ## 函数 函数也是对象 ``` add(n) { return n+1; } int add2( int n) { return n+1; } add3(int n)=>n+1; //默认以 return 返回 main() { print(add(2)); // 3 print(add2(2));// 3 print(add3(2));// 3 } ``` ### 可选参数 命名参数或者位置参数,但一个参数只能选择其中一种方式修饰 #### 命名可选参数 ``` echo({int age,String name}){ print(age); print(name); } main() { echo(name:"cc" );// 22 null } ``` #### 位置可选参数 ``` echo(String name,[int age]){ print(name); print(age); } main() { echo("cc");//cc null } ``` ### 默认参数值 命名可选参数 ``` echo({int age=22,String name="cc"}){ print(age); print(name); } main() { echo(name: "dd");// 22 dd } ``` 位置可选参数 ``` echo(String name,[int age=12]){ print(name); print(age); } main() { echo("cc");//cc 12 } ``` list 或map 天界默认值 ``` void doStuff( {List<int> list = const [1, 2, 3], Map<String, String> gifts = const { 'first': 'paper', 'second': 'cotton', 'third': 'leather' }}) { print('list: $list'); print('gifts: $gifts'); } main() { doStuff(); } ``` ### 函数作为参数传入 ``` void printElement(int element) { print(element); } var list = [1, 2, 3]; // 将 printElement 函数作为参数传递。 list.forEach(printElement); ``` ### 匿名函数 ``` var a=["a","b","c"]; a.forEach((item){ print('${a.indexOf(item)}: ${item}'); }); //等价 list.forEach((item) => print('${list.indexOf(item)}: $item')); //output 0: a 1: b 2: c ``` ## 运算符 ``` // 类型判定运算符 print("1" is String); //true if (emp is Person) { // Type check emp.firstName = 'Bob'; } // 缩写 (emp as Person).firstName = 'Bob'; //如果 emp 为null 为报异常 //关系运算符 assert(2 + 3 == 5); assert(2 - 3 == -1); assert(2 * 3 == 6); assert(5 / 2 == 2.5); // 结果是双浮点型 assert(5 ~/ 2 == 2); // 结果是整型 assert(5 % 2 == 1); // 余数 b ??= value; // 如果b为空时,将变量赋值给b,否则,b的值保持不变。 // 条件表达式 var visibility = isPublic ? 'public' : 'private'; ``` ### 级联运算符 实现对同一个对像进行一系列的操 还可以访问同一对象上的字段属性 ``` querySelector('#confirm') // 获取对象。 ..text = 'Confirm' // 调用成员变量。 ..classes.add('important') ..onClick.listen((e) => window.alert('Confirmed!')); //等价于 var button = querySelector('#confirm'); button.text = 'Confirm'; button.classes.add('important'); button.onClick.listen((e) => window.alert('Confirmed!')); ``` ## 控制流程语句 大 ### if ``` if (isRaining()) { you.bringRainCoat(); } else if (isSnowing()) { you.wearJacket(); } else { car.putTopDown(); } ``` ### for 循环 ``` for (var i = 0; i < 5; i++) { ... } ``` 迭代 ``` var collection = [0, 1, 2]; for (var x in collection) { print(x); // 0 1 2 } ``` ### switch ``` var command = 'OPEN'; switch (command) { case 'CLOSED': executeClosed(); break; case 'PENDING': executePending(); break; default: executeUnknown(); } ``` ## 异常 ``` throw FormatException('Expected at least 1 section'); throw 'Out of llamas!'; // 抛出任意的对象 try { throw FormatException("1111"); // throw "222"; } on Exception catch (e) { // 其他任何异常 print('Unknown exception: $e'); //1111 } catch (e) { // 没有指定的类型,处理所有异常 print('Something really unknown: $e'); // 222 } ``` ### 重新抛出异常 ``` try { dynamic foo = true; print(foo++); // Runtime error } catch (e) { print('misbehave() partially handled ${e.runtimeType}.'); rethrow; // Allow callers to see the exception. } ``` ### finally ``` try { throw "222"; } catch (e) { print('Something really unknown: $e'); } finally{ print("end"); //end } //output // Something really unknown: 222 //end ``` ## 类 ``` class person { String name; } void main() { var a = new person(); //等效 var a = asd(); print(a.runtimeType); // person 获取运行时类型 print(a?.name = "cc"); //如果name 为null 则赋值 cc } ``` > 在 Dart 2 中 new 关键字变成了可选的。 ### 构造函数 ``` class person { String name; int age=0; person(String name,this.age){ //this.age 为语法糖 this.name=name; } } void main() { var a = person("cc",23); print(a.name); // cc print(a.age); // 23 } ``` > 构造函数不能够被继承 ### Getter 和 Setter ``` class person { String name; num _age = 0; person(name, this._age) { this.name = name; } num get age1 => _age + 1; num get age2 { return _age + 1; } set age3 (num a)=> _age=_age-10; } void main() { var a = person("cc", 23); print(a.age1); // 24 print(a.age2); // 24 a.age3=123; print(a.age1); // 14 } ``` ### 抽象方法 / 抽象类 实例方法, getter, 和 setter 方法可以是抽象的, 只定义接口不进行实现,而是留给其他类去实现。 抽象方法只存在于 抽象类 中。 ``` abstract class Doer { // 定义实例变量和方法 ... void doSomething(); // 定义一个抽象方法。 } class EffectiveDoer extends Doer { void doSomething() { // 提供方法实现,所以这里的方法就不是抽象方法了... } } ``` ### 扩展类(继承) 使用 extends 关键字来创建子类, 使用 super 关键字来引用父类: ``` class Television { void turnOn() { _illuminateDisplay(); _activateIrSensor(); } // ··· } class SmartTelevision extends Television { void turnOn() { super.turnOn(); _bootNetworkInterface(); _initializeMemory(); _upgradeApps(); } // ··· } ``` ### 重写类成员 ``` class SmartTelevision extends Television { @override void turnOn() {...} // ··· } ``` ### noSuchMethod() 调用不存在的方法触发 ``` class A { // 如果不重写 noSuchMethod,访问 // 不存在的实例变量时会导致 NoSuchMethodError 错误。 @override void noSuchMethod(Invocation invocation) { print('You tried to use a non-existent member: ' + '${invocation.memberName}'); } } ``` ### 类变量和方法 #### 静态变量 静态变量只到它们被使用的时候才会初始化。 ``` class Queue { static const initialCapacity = 16; // ··· } void main() { assert(Queue.initialCapacity == 16); } ``` #### 静态方法 静态方法(类方法)不能在实例上使用,因此它们不能访问 this ``` class person { static echo(String name) { print('hello ${name}'); } } void main() { person.echo('cc'); } ``` ### call() 方法 ``` class WannabeFunction { call(String a, String b, String c) => '$a $b $c!'; } main() { var wf = new WannabeFunction(); var out = wf("Hi","there,","gang"); print('$out'); // Hi there, gang! } ``` ### 元数据 #### @deprecated 被弃用的 若某类或某方法加上该注解之后,表示此方法或类不再建议使用,调用时也会出现删除线 ``` class Television { @deprecated void activate(){ turnOn(); } } ``` #### @override重写 #### @proxy 代理 #### @required 来标记一个参数 * 告诉编译器这个参数必须要传值 * 告诉读代码的人,这个参数必须要填写 ## 泛型 ``` 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 Cache<T> { T getByKey(String key); void setByKey(String key, T value); } ``` ### 限制泛型类型 ``` class Foo<T extends SomeBaseClass> { // Implementation goes here... String toString() => "Instance of 'Foo<$T>'"; } class Extender extends SomeBaseClass {...} // 可以使用 SomeBaseClass 或其任意子类作为通用参数: var someBaseClassFoo = Foo<SomeBaseClass>(); var extenderFoo = Foo<Extender>(); ``` ## 枚举类型 ``` enum Color { red, green, blue } //枚举都有 getter 犯法 assert(Color.green.index == 1); //枚举的 values 常量 List<Color> colors = Color.values; assert(colors[2] == Color.blue); var aColor = Color.blue; switch (aColor) { case Color.red: print('Red as roses!'); break; case Color.green: print('Green as grass!'); break; default: // 没有这个,会看到一个警告。 print(aColor); // 'Color.blue' } ``` ## typedef 声明一种类型 ``` typedef int Compare(int a, int b); int sort(int a, int b) => a - b; main() { print(sort is Compare); //true } ```