Flutter笔记二之Dart(2.16.2)基础语法

之后使用的dart都是2.16.2

main函数

hello world
void main(List<String> args) {
    print("Hello world!!!");
}

main函数是入口,语句结束要加;

声明变量

明确的声明

类型+变量名
String name = "Steven";

类型推导

关键字var同swift里的var,
final同swift里的let,
const同oc里的const上述关键字一旦确认类型不可改变,
dynamic任意类型,确认类型后还可以更改类型,调用方法时,编译不会报错,存在隐患
Object任意类型,确认类型后还可以更改类型,调用方法时,编译会报错

数据类型

int,num,double,bool
其中String的使用同Python,进行拼接则使用${},如果只是变量,则可省略{}
String->num int.parse(变量) double.parse(变量)
str.isEmpty 是否是空字符串
num.isNaN 是否为空num
num->String 变量.toString()

集合

list同数组,set同集合,map同字典

枚举

关键词enum,使用固定的值,类型安全

void main(List<String> args) {
  final s = sex.man;
  switch (s) {
    case sex.man:
      print("man");
      break;
    case sex.woman:
      print("woman");
      break;
  }
  print(sex.values);
  print(sex.man.index);
}

enum sex { man, woman }

函数

返回类型(可省略,但不推荐) + 函数名 + (必选参数 + [位置可选参数]或{命名可选参数}) { 函数体 }
eg:

void sayHello1(String name, [int age = 10]) {
  print("$name : $age");
}

void sayHello2(String name, {int age = 12}) {
  print("$name : $age");
}
函数作为参数

使用Function修饰,但不建议,建议直接写函数表达式
eg:

void main(List<String> args) {
//匿名函数
  test((a, b) {
    print(a + b);
    return a + b;
  });
}

typedef Calculate = int Function(int a, int b);
void test(Calculate cal) {
  var res = cal(2, 3);
  print(res);
}
函数作为返回值

eg:

void main(List<String> args) {
//d1是Calculate类型的函数,需要传入a,b两个参数
  var d1 = demo();
  print(d1(3, 5));
}
typedef Calculate = int Function(int a, int b);
//返回类型Calculate,返回了一个匿名函数
Calculate demo() {
  return ((a, b) {
    return a * b;
  });
}
箭头函数

函数体只有一行代码
() => {print("这是箭头函数")};{}可以省略

匿名函数

无函数名 (参数) { 函数体},参见上面注释

特殊运算符

赋值运算符

??=当赋值的变量不为空时不赋值,当变量为空时才执行
??同Swift,符号前面的值不为空时使用前面的值,为空时使用后面的值

级联运算符

..对一个对象的操作可以通过级联运算符连接,语句结束加;即可

循环

for,for in同oc,switf

类的构造函数

常规的都可以,也可以通过KVC模式构造
eg:

void main(List<String> args) {
  var cat = Animal.fromMap({"name": "kitty", "age": 2, "male": true});
  //toString()可以省略
  print(cat.toString());
  var dog1 = Animal("dog", 12);
  var dog2 = Animal("dog2", 15, male: true);
  print(dog1);
  print(dog2);
}

class Animal {
  String? name;
  int? age;
  bool? male;
  // 语法糖 初始化列表
  Animal(this.name, this.age, {male}) : this.male = male ?? false;
  Animal.fromMap(Map<String, dynamic> map, {String}) {
    this.name = map["name"];
    this.age = map["age"];
    this.male = map["male"];
  }
  @override
  String toString() {
    return "name:$name,age:$age,male:$male";
  }
}
重定向构造函数

关键字_internal

void main(List<String> args) {
  var s = Student("Bob");
  print(s.age);
}
class Student {
  String name;
  int age;
  Student(String name) : this._internal(name, 20);
  Student._internal(this.name, this.age);
}
常量构造函数
void main(List<String> args) {
  const s1 = Student("name");
  const s2 = Student("name");
  //对比得出s1与s2指向同一块内存,是一个对象
  print(identical(s1, s2));
}

class Student {
  final String name;
  const Student(this.name);
}
工厂构造函数

区别:普通的构造函数会返回一个创建的对象,工厂构造函数可以手动返回一个对象。

void main(List<String> args) {
  final s1 = Student.withName("bob");
  final s2 = Student.withName("bob");
  final s3 = Student.withAge("20");
  final s4 = Student.withAge("20");
  //对比得出s1与s2相等
  print(identical(s1, s2));
  //对比得出s3与s4相等
  print(identical(s3, s4));
}

class Student {
  String name;
  String age;
  static final Map<String, Student> _nameCache = <String, Student>{};
  static final Map<String, Student> _ageCache = <String, Student>{};

  factory Student.withName(String name) {
    //putIfAbsent.如果存在[key],则会返回它的值。如果不存在,就会调用后面的函数,生成新值,然后插入,并返回该值。
    return _nameCache.putIfAbsent(name, () => Student(name, "10"));
  }
  factory Student.withAge(String age) {
    return _ageCache.putIfAbsent(age, () => Student("name", age));
  }

  Student(this.name, this.age);
}
setter和getter
void main(List<String> args) {
  var c = Cat();
  c.setName = "cat";
  print(c.getName);
}

class Cat {
  late String name;
  set setName(String name) => this.name = name;
  /*set setName(String name) {
    this.name = name;
  }*/
  String get getName => this.name;
  /*String get getName {
    return this.name;
  }*/
}
继承

关键字extends,只支持单继承

void main(List<String> args) {
  var c = Cat(20, "kitty");
}

class Animal {
  String name;
  Animal(this.name);
}

class Cat extends Animal {
  int age;
  Cat(this.age, String name) : super(name);
}
抽象类

关键字abstract
普通类中的方法必须实现,抽象类中的方法可以不实现;
继承抽象类后,必须实现抽象类的抽象方法
正常情况下抽象类不能实例化(new 类()),除非加工厂构造函数
external:将方法的声明和方法的实现分离,通过@patch实现方法

隐式接口

关键字implements
将一个类作为接口使用时,则实现这个接口的类必须实现这个接口中的所有方法

class Cat {
  void running() {}
}

class Dog {
  void jumping() {}
}

class Animal implements Cat, Dog {
  @override
  void running() {
    // TODO: implement running
  }
  @override
  void jumping() {
    // TODO: implement jumping
  }
}

注:继承可以调用super,实现不可以
继承抽象类和implements区别:

  • 如果要福永抽象类里面的方法,并且要用抽象类方法约束子类的话就继承抽象类
  • 如果只是把抽象类当标准的话就使用implements实现抽象类
mixin混入

关键词mixin定义,with混入.优先级:重写 > 混入 > 继承

mixin Cat {
  void running() {}
}

mixin Dog {
  void jumping() {}
}

class Animal with Cat, Dog {}
  • 作为mixins的类只能继承自Object,不能继承其他类
  • 作为mixins的类不能有构造函数
  • 一个类可以mixins多个mixins类
  • Mixins不是继承,也不是接口,是一个全新的特性。
    class M extends N with A,B(一个类M,继承自类N,混入A,B),其中N,A,B有同一个方法,则使用最后一个混入的类B
类属性和类方法
  • 使用static关键字来实现类级别的变量和函数
  • 静态方法不能访问非静态成员,非静态方法可以访问静态成员
void main(List<String> args) {
  var c = Cat();
  c.name = "mimi";
  Cat.kind = "animal";
  c.running();
  Cat.living();
}

class Cat {
  // 成员属性
  late String name;
  // 类属性
  static String? kind;
  // 成员方法
  void running() {
    print("running");
  }

  // 类方法
  static void living() {
    print("living");
  }
}
extension扩展

extension 扩展名 on 扩展的类 { //扩展内容}

泛型

一般用T作为关键字,作用:解决类,接口,方法等的复用性(冗余),以及对不特定数据类型的支持(校验)
ok,dart的语法基本就到这里了,异步线程啥的要到后面Flutter里再学了。

版权声明:本文为 Crazy Steven 原创出品,欢迎转载,转载时请注明出处!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容