变量

  1. var a = 1;
  2. int b = 10;
  3. double c = 0.5;
  4. String s = "hello";
  5. dynamic d = 0.5;
  6. final Num = count; // final 只能赋值一次
  7. const Num1 = 10; // const赋值必须是编译时常量
  8. //区别一:final 要求变量只能初始化一次,并不要求赋的值一定是编译时常量,可以是常量也可以不是。而 const 要求在声明时初始化,并且赋值必需为编译时常量。
  9. //区别二:final 是惰性初始化,即在运行时第一次使用前才初始化。而 const 是在编译时就确定值了。
  10. // numbers
  11. var a = 0;
  12. int b = 1;
  13. double c = 0.1;
  14. // strings
  15. var s1 = 'hello';
  16. String s2 = "world";
  17. // booleans
  18. var real = true;
  19. bool isReal = false;
  20. // lists
  21. var arr = [1, 2, 3, 4, 5];
  22. List<String> arr2 = ['hello', 'world', "123", "456"];
  23. List<dynamic> arr3 = [1, true, 'haha', 1.0];
  24. // maps
  25. var map = new Map();
  26. map['name'] = 'zhangsan';
  27. map['age'] = 10;
  28. Map m = new Map();
  29. m['a'] = 'a';
  30. //runes,Dart 中 使用runes 来获取UTF-32字符集的字符。String的 codeUnitAt and codeUnit属性可以获取UTF-16字符集的字符
  31. var clapping = '\u{1f44f}';
  32. print(clapping); // 打印的是拍手emoji的表情
  33. // symbols
  34. print(#s == new Symbol("s")); // true

函数

  1. // 声明返回值
  2. int add(int a, int b) {
  3. return a + b;
  4. }
  5. // 不声明返回值
  6. add2(int a, int b) {
  7. return a + b;
  8. }
  9. // =>是return语句的简写
  10. add3(a, b) => a + b;
  11. // 无返回值
  12. add4(int a, int b) {
  13. int c= a + b;
  14. print(c);
  15. }
  16. main() {
  17. print(add(1, 2)); // 3
  18. print(add2(2, 3)); // 5
  19. print(add3(1, 2)); // 3
  20. add4(1.2);// 3
  21. }

函数返回值

所有的函数都有返回值,如果没有指定return语句,那么该函数的返回值为null。

命名参数

  1. sayHello({String? name}) {
  2. print("hello, my name is $name");
  3. }
  4. sayHelloRequired({String required name}) {
  5. print("hello, my name is $name");
  6. }
  7. main() {
  8. // 打印 hello, my name is zhangsan
  9. sayHello(name: 'zhangsan');
  10. // 打印 hello, my name is
  11. sayHello();
  12. // 打印 hello, my name is zhangsan
  13. sayHelloRequired(name: 'zhangsan');
  14. //报错
  15. sayHelloRequired();
  16. }

参数默认值

  1. // 命名参数的默认值 b默认为3,
  2. int add({int required a, int b = 3}) {
  3. return a + b;
  4. }

lambda表达式

  1. test(Function callback) {
  2. callback("hello");
  3. }
  4. main() {
  5. test((param) {
  6. // 打印hello
  7. print(param);
  8. });
  9. }

运算符

  1. main() {
  2. // 与Java相同的运算符操作
  3. int a = 1;
  4. ++a;
  5. a++;
  6. var b = 1;
  7. print(a == b); // false
  8. print(a * b); // 3
  9. bool real = false;
  10. real ? print('real') : print('not real'); // not real
  11. print(real && a == b); // false
  12. print(real || a == 3); // true
  13. print(a != 2); // true
  14. print(a <= b); // false
  15. var c = 9;
  16. c += 10;
  17. print("c = $c"); // c = 19
  18. print(1<<2); // 4
  19. // 与Java不太一样的运算符操作
  20. // is运算符用于判断一个变量是不是某个类型的数据
  21. // is!则是判断变量不是某个类型的数据
  22. var s = "hello";
  23. print(s is String); // true
  24. var num = 6;
  25. print(num is! String); // true
  26. // ~/才是取整运算符,如果使用/则是除法运算,不取整
  27. int k = 1;
  28. int j = 2;
  29. print(k / j); // 0.5
  30. print(k ~/ j); // 0
  31. // as运算符类似于Java中的cast操作,将一个对象强制类型转换
  32. (emp as Person).teach();
  33. // ??=运算符 如果 ??= 运算符前面的变量为null,则赋值,否则不赋值
  34. var param1 = "hello", param2 = null;
  35. param1 ??= "world";
  36. param2 ??= "world";
  37. print("param1 = $param1"); // param1 = hello
  38. print("param2 = $param2"); // param2 = world
  39. // ?.运算符
  40. var str1 = "hello world";
  41. var str2 = null;
  42. print(str1?.length); // 11
  43. print(str2?.length); // null
  44. print(str2.length); // 报错
  45. }

级联操作

用..调用某个对象的方法(或者成员变量)时,返回值是这个对象本身

  1. class Person {
  2. eat() {
  3. print("I am eating...");
  4. }
  5. sleep() {
  6. print("I am sleeping...");
  7. }
  8. study() {
  9. print("I am studying...");
  10. }
  11. }
  12. main() {
  13. // 依次打印
  14. // I am eating...
  15. // I am sleeping...
  16. // I am studying...
  17. new Person()..eat()
  18. ..sleep()
  19. ..study();
  20. }

控制流程

if / else, switch, for /while, try / catch语句跟Java中都类似。

  1. main() {
  2. // if else语句
  3. int score = 80;
  4. if (score < 60) {
  5. print("so bad!");
  6. } else if (score >= 60 && score < 80) {
  7. print("just so so!");
  8. } else if (score >= 80) {
  9. print("good job!");
  10. }
  11. // switch语句
  12. String a = "hello";
  13. // case语句中的数据类型必须是跟switch中的类型一致
  14. switch (a) {
  15. case "hello":
  16. print("haha");
  17. break;
  18. case "world":
  19. print("heihei");
  20. break;
  21. default:
  22. print("WTF");
  23. }
  24. // for语句
  25. List<String> list = ["a", "b", "c"];
  26. for (int i = 0; i < list.length; i++) {
  27. print(list[i]);
  28. }
  29. for (var i in list) {
  30. print(i);
  31. }
  32. // 这里的箭头函数参数必须用圆括号扩起来
  33. list.forEach((item) => print(item));
  34. // while语句
  35. int start = 1;
  36. int sum = 0;
  37. while (start <= 100) {
  38. sum += start;
  39. start++;
  40. }
  41. print(sum);
  42. // try catch语句
  43. try {
  44. print(1 ~/ 0);
  45. } catch (e) {
  46. // IntegerDivisionByZeroException
  47. print(e);
  48. }
  49. try {
  50. 1 ~/ 0;
  51. } on IntegerDivisionByZeroException { // 捕获指定类型的异常
  52. print("error"); // 打印出error
  53. } finally {
  54. print("over"); // 打印出over
  55. }
  56. }

类的定义与构造方法

Dart中不需要用private, protected, public等修饰成员变量或成员函数

  1. class Person {
  2. String name;
  3. int age;
  4. String gender;
  5. Person(this.name, this.age, this.gender);
  6. say() {
  7. print("hello, this is $name, I am $age years old, I am a $gender");
  8. }
  9. }
  1. //上述的 Person(this.name, this.age, this.gender);等同于
  2. Person(String name, int age, String gender) {
  3. this.name = name;
  4. this.age = age;
  5. this.gender = gender;
  6. }

要调用Person类的成员变量或成员方法,可以用下面的代码:

  1. var p = new Person("zhangsan", 20, "male");
  2. p.say(); // hello, this is zhangsan, I am 20 years old, I am a male
  3. p.age = 50; // 重新赋值
  4. p.gender = "female"; // 重新赋值
  5. p.say(); // hello, this is zhangsan, I am 50 years old, I am a female

类的继承

Dart中使用extends关键字做类的继承

  1. class Human {
  2. String name;
  3. Human.fromJson(Map data) {
  4. print("Human's fromJson constructor");
  5. }
  6. }
  7. class Man extends Human {
  8. Man.fromJson(Map data) : super.fromJson(data) {
  9. print("Man's fromJson constructor");
  10. }
  11. }

由于Human类没有默认构造方法,只有一个命名构造方法fromJson,所以在Man类继承Human类时,需要调用父类的fromJson方法做初始化,而且必须使用Man.fromJson(Map data) : super.fromJson(data)这种写法,而不是像Java那样将super写到花括号中。

类的成员方法

一个类的成员方法是一个函数,为这个类提供某些行为。上面的代码中已经有了一些类的成员方法的定义,这些定义方式跟Java很类似,你可以为某个类的成员变量提供getter/setter方法。

  1. class Rectangle {
  2. num left, top, width, height;
  3. // 构造方法传入left, top, width, height几个参数
  4. Rectangle(this.left, this.top, this.width, this.height);
  5. // right, bottom两个成员变量提供getter/setter方法
  6. num get right => left + width;
  7. set right(num value) => left = value - width;
  8. num get bottom => top + height;
  9. set bottom(num value) => top = value - height;
  10. }

mixins(with 关键字)

mixins是一个重复使用类中代码的方式

  1. class A {
  2. a() {
  3. print("A's a()");
  4. }
  5. }
  6. class B {
  7. b() {
  8. print("B's b()");
  9. }
  10. }
  11. // 使用with关键字,表示类C是由类A和类B混合而构成
  12. class C = A with B;
  13. main() {
  14. C c = new C();
  15. c.a(); // A's a()
  16. c.b(); // B's b()
  17. }

异步

Dart提供了async await等异步操作,这种异步操作在Flutter开发中会经常遇到,比如网络或其他IO操作,文件选择等都需要用到异步的知识。
async和await往往是成对出现的,如果一个方法中有耗时的操作,你需要将这个方法设置成async,并给其中的耗时操作加上await关键字,如果这个方法有返回值,你需要将返回值塞到Future中并返回。

  1. Future<int> checkVersion() async {
  2. int version = await lookUpVersion();
  3. return version;
  4. }
  5. main() {
  6. checkVersion().then((version) {
  7. print('$version');
  8. });
  9. }