dart 小记

最近在看flutter和dart,记录一下dart和javascript/java等常见语言不同一点特性。

dart 在面向对象和java类似,但是一些异步和动态性上和javascript类似。

字符串

使用三个引号表示多行字符串

  String str2 = ''' kevin
    kang hello 
         word ''';

使用前缀r,输出原始字符串不进行转义

    var s = r'kevin is \n 18'
    print(s)

操作符

?? 操作符

?? 类似于js里面的|| 操作符。a??b这个表达式的值,如果a不为空,那么为a,如果为空,那么为b

    var c;
    print(c ?? 20)

??=操作符

    int d ;
    d ??= 0;

控制语句

switch 语句可以通过continue跳转到某一个特定的条件下

String str = 'c';
  switch(str) {
    A:
    case 'java':
      print('I love java');
      break;
    B:
    case 'c':
      print('I love c');
      continue C;
      break;
    C:
    case 'python':
      print('I love python');
      continue A;
      break;
    D:
    case 'golang':
      print('I love golang');
      break;
  }

函数

dart里面,函数也是对象,函数是一等公民,可以去值可以去的任何地方。

1,函数与数字一样可以存储为变量

    var func = (){print('all too well')} 

2,函数与数字一样可以存储为数组的一个元素

    var arr = []
    Function func = (){
        print('style')
    }
    arr.add(func)

3,函数与数字一样可以作为对象的成员变量

    var obj = {}
    obj['sayHello'] = () {
        print('Hello ,wherever you are')
    }

4, 函数与数字一样可以在使用时直接创建出来[立即执行函数]

  print(42 + (){return 4;}());

5, 函数与数字一样可以被传递给另一个函数

  Function weirdAdd = (n, f) { return n + f(); };
  weirdAdd(42, () { return 42; }); //=>84

6, 函数与数字一样可以被另一个函数返回

 Function getSayHi(){
    return ()=>print('Hi sunshine is coming');
  }

是不是有js内味儿了,是的。

闭包

是的,你没看错,我已经在三个地方看到闭包特性了,js、golang、还有dart。

啥是闭包,回顾一下,闭包的概念:
1,函数 与 对其状态【词法环境】的引用共同构成闭包。------->>>>> 函数可以访问外部函数的作用域。
2,闭包能够访问外部函数的变量,并且持有变量的状态


 Function getPlusFunc() {
    var i = 1;
    return (){
       print(i++);
    }
 }
 var plusFunc = getPlusFunc();
 plusFunc();
 plusFunc();
 plusFunc();

函数的可选参数

命名可选参数

 void setInfo(String name, { int age, String gender }) {}
 
 // 调用的时候这样调用, 可选参数顺序不一定按照定义的来
 setInfo('kevin', gender: 'male', age: 20);

可选位置参数

void setInfo2(String name, [int age, String gender]) {}
// 调用的时候必须按照顺序来
setInfo2('kevin', 20, 'male');
setInfo2('kevin', 'male', 20); // 报错

class 作为声明类的关键字

1,实例化一个对象可以加new 关键字也可以不加。
2,final类型的属性,只能初始化,只读不可写。
3,默认添加getter setter函数

构造函数

普通构造函数

    
    class Person{
      string name;
      int age;
    }
    
    // 有参构造函数 方法一
    class Person{
      String name;
      int age;
      Person(n, g) {
        this.name = n;
        this.age = g;
      }
    }
    // 有参构造函数 方法二,语法糖
    class Person{
      String name;
      int age;
      Person(this.name, this.age);
    }
    // 命名构造函数
    class Person {
      String name;
      int age;
      Person.withName(this.name);
      Person.withAge(this.age);
    }
    

带final变量的构造函数

    class Person {
      String name;
      int age;
      final String gender;
    
      // 完整构造函数, 不能在完整的构造函数给final变量赋值,但是却可以在语法糖里初始化
      // Person(name, age, gender) {
      //   this.name = name;
      //   this.age = age;
      //   this.gender = gender;
      // }
      // note: 构造函数语法糖
      Person(this.name, this.age, this.gender);
   }
    

factory 构造函数 可以有返回值

…略

初始化列表



class Point{
  final num x;
  final num y;
  // 方法一 创建对象的时候初始化
  // Point(this.x, this.y);

  // 方法二 构造函数调用之前,初始化final常量name
  Point(num m, num n): x = m, y = n {}
  Point.withAsset(this.x, this.y): assert(x > 0) {
    print('In Point.withAssert(): ($x, $y)');
  } 
}

对象的操作符

?. 防止空指针异常
is is! 是否是指定类型
..级联操作符

  var pp = new Person();
  pp..name = 'Kev'
    ..age = 20
    ..sayHi();

面向对象

继承

extends 关键字,在实例化对象的时候,会先调用父类构造函数,然后子类构造函数。写法如下。


  class Person{
    String name;
    Person(this.name);
  }
  class Student extends Person{
    int id;
    String name;
    Student(this.id, this.name):super(name);
  } 

重要的一点:实际上在调用构造函数之前,我们已经将值赋值给了name。下面的和上面的声明是等价的。

  class Person{
    String name;
    Person(this.name);
  }
  class Student extends Person{
    int id;
    String name;
    Student(int i, String n): id = i, name = n, super(name);
  } 
    
  // 执行顺序是 id = i, name = n 然后执行super(name)即是调用父类构造函数,然后再执行子类构造函数里面的方法体。


试试下面这个

  class Person{
    String name;
    Person(this.name);
  }
  class Student extends Person{
    int id;
    String name;
    Student(int i, String n): id = i, name = n, super(name) {
        print(id);
        print('执行方法体了');
    }
  } 


多继承

dart 是单继承的,也就是说不能这样 class A extends B,C来写。但是实现多继承我们可以使用mixins混合, 关键字是with。

mixins类比较特殊:
1,mixins类必须继承自Object
2,mixins类不能显示的声明构造函数


class A {
    void run(){
        print('run a');
    }
}
class B {
    void run(){
        print('run b');
    }
}
class C {
    void run() {
        print('run c');
    }
}

class D extends C with A, B {

}

D().run() // 执行结果为 run c // 顺序中最后一个

如果你想将mixin不能被当做常规类来使用,直接使用关键字mixin,这样这个类就不能么被实例化了。

    mixin Person{
        String name;
        Person(this.name)
    }

   class Student with Person {
   }

抽象类

抽象类关键字abstract,不能实例化,包含没有实现的方法,也可以包含有方法体的方法。继承抽象类,必须实现其抽象方法。

== 接口 ==

dart里面接口比较特殊,接口就是类,实现一个接口,使用关键字implements即可。大多数情况下,我们使用抽象类来作为接口,因为抽象类的抽象方法没有方法体。

操作符的重写

操作符重写必须在类里面

oid main() {
  var p1 = new Person(20);
  var p2 = new Person(18);
  print(p1 > p2);
  print(p2['age']);
}

// note: 操作符重写必须在类里面
class Person{
  int age;
  Person(this.age);

  // 尝试重写<> []

  // 重写 >
  // 为什么只有一个参数,咱们执行p1 > p2的时候,p2是参数,p1是调用者
  bool operator > (Person p) {
    return this.age > p.age;
  }

  // 重写[] 传入字符串  获取年龄
  int operator [] (String age) {
    return this.age;
  }

}


异步 操作

… to be continued

你可能感兴趣的:(dart)