Flutter前奏-了解一下Dart

随风 2019-05-29 22:47:13

前世今生

Dart是种编程语言,谷歌儿子之一,目前很火的跨平台开发框架Flutter采用的就是Dart,至于前世今生自行百度/Google即可。

环境搭建

  • 这里我只发出Dart的下载网站,其他的可以看一下网站。https://dart.dev/get-dart

数据类型

  • 入口函数:
void main() {
  var test = 0;
  print(test);
}
  • 定义常量与变量:使用var声明任意类型变量,使用const声明常量,变量未赋值时默认为null,final声明的变量只能赋值一次:
void main() {
    var test = 0;
    const haha = "哈哈哈";
    final heihei = "666";
    print(test);
}
  • 数据类型有:数值型-Number;布尔型-Boolean;键值对-Map;字符串-String;列表-List。
test() {  //返回类型可以省略
  num a = 0;
  int b = 1;
  double c = 1.0;

  //常用运算操作
  a + b;
  a - b;
  a * b;
  b / c;   //整除
  b % c;   //
  b ~/ c;  //除

  //常用方法
  a.isNaN;  //非数字
  a.isOdd;  //是否是奇数
  a.isEven; //是否是偶数

  double d = 1.0;
  d.abs();
  d.round();
  d.floor();
  d.ceil();
  d.toInt();
  b.toDouble();

  //字符串
  var e = 'a';
  var f = "b";
  var g = '''
              apfpafpafpaf
              fakfkas;fk;dfk
              sadfjafjafjs              
          ''';   //多行字符串
  var h = r'hello \n dart'; //是将\n转意符号打印出来 使其不生效  这种叫做raw字符串

  //字符串操作
  e + f;
  e * 3; //3倍的e
  e == f;
  g[1];
  print("e + f = ${e + f}");  //插值操作

  //常用属性
  g.length;
  g.isEmpty;
  g.isNotEmpty;

  //常用方法
  g.contains(e);
  g.substring(10);
  g.toLowerCase();
  g.toUpperCase();
  g.trim();
  g.trimLeft();
  g.trimRight();
  g.replaceXXXXX();   //以replace开发头的部分方法

  g.startsWith(pattern);
  g.endsWith(pattern);
  g.indexOf(pattern);
  g.lastIndexOf(pattern);
  g.split(pattern);

  //布尔型
  bool isTrue = true;
  isTrue = false;

  //List数组
  var list = [1, 2, 3];

  var list1 = const [1, 2, 3];  //不可变list

  var list2 = new List();  //dart中new可以省略

  //常用操作
  list.length;
  list.add(4);
  list.insert(0, 5);
  list.remove(1);
  list.clear();
  list.indexOf(2);
  list.lastIndexOf(3);
  list.sort();
  list.sublist(2);
  list.shuffle();
  list.asMap();
  list.forEach(print);   //这里面传递的是一个方法,比如print

  //Map字典
  var map = {'first':'Dart','second':'php'};
  var map1 = const {'first':'Dart','second':'php'};  //不可变map
  var map2 = Map();

  //常用操作
  map.length;
  map.isEmpty;
  map.isNotEmpty;
  map.keys;
  map.values;
  map.containsKey('first');
  map.containsValue('php');
  map.remove('first');
  map.forEach(print);

  //dynamic关键字
  dynamic j =20;
  j = "javaScript";

  var list3 = List< dynamic >();
  list3.add(1);
  list3.add("hello");
  list3.add(true);
  print(list3);
}

运算符

  • 算术运算符:+ ,- ,* ,/ ,~/ ,% ,++ ,-- 。其实也就 ~/ 比较特殊,就是我们现实中的除法,结果带小数的那种。
  • 关系运算符:==,!=,>,<,>=,<=,==
  • 逻辑运算符:!,&&,||。主要针对布尔类型进行运算
  • 赋值运算符:=,??=,+=,-=,*=,/=,%=,~/=
  • 条件表达式:三目运算符 ?:,??运算符 ??。

控制语句

  • 流程控制语句
test() {
  //条件语句
  var a = 10;
  var b = 20;
  if(a == b) {
    print("a=b");
  } else {
    print("a!=b");
  }

  //for循环语句
  var list = [1, 2, 3, 4, 5];
  for(var i = 0; i<  list.length; i++) {
    print(list[i]);
  }

  for (var i in list) {
    print(i);
  }

  //while循环语句
  var j = 0;
  while(j <= 10){
    j++;
  }

  do {
    j--;
  } while (j <= 0);


  //break与continue
  //break:终止循环
  //continue:跳出当前循环


  //switch...case语句
  String language = "Dart";

  switch (language) {
    D:   //定义一个标签,这里面可以使用continue跳转
    case "Dart":
      print("dart");
      break;
    case "php":
      print("php");
      continue D;
      // break;
    case "Java":
      print("Java");
      break;
    default:
      print("default");
  }
}

方法

  • 方法也是对象,并且有具体类型Function,返回值/参数类型都可以省略,箭头语法 => 知识 {return ;} 的缩写,方法都有返回值,如果没有指定,默认返回值是null.
  • 方法定义格式
返回值  方法名 (参数1, 参数2) {
    方法体
    return 返回值
}

printPerson(name, age) {
  print("name = $name, age = $age");
}

person(name, age) => "name = $name, age = $age";
  • 可选参数
personInfo(String name, {int age}) {
  print("name=$name, age=$age");
}

//带默认值的参数
personInfo1(String name, {int age = 10}) {
  print("name=$name, age=$age");
}
  • 方法对象
//方法可作为对象赋值给其他变量
main() {
  var func = printHello();
  func();
}

printHello() {
  print("Hello");
}

//方法可作为参数传递给其他方法
main() {
  var list = ["h","e","l","l","o"];
  print(listTimes(list, times));
}

List listTimes(List list, String times(str)) {
  for(var index = 0; index < list.length; index ++) {
    list[index] = times(list[index]);
  }
  return list;
}

String times(str) {
  return str * 3;
}
  • 匿名方法
main() {
    var func = (str) {
        print(str);
    };
    func(30);
    
    
    
  var list = ["h","e","l","l","o"];
  print(listTimes(list, (str) { return str * 3; } ));
}

List listTimes(List list, String times(str)) {
  for(var index = 0; index < list.length; index ++) {
    list[index] = times(list[index]);
  }
  return list;
}
  • 闭包
//闭包是一个方法,定义再其他方法内部,能够访问外部方法内的局部变量,并持有其状态
main() {
    var func = a();
    func();
    func();
}

a() {
    int count = 0;
    return {
        print(count++);
    }
}

面向对象

  • 使用class声明一个类,使用new创建类的对象,new可以省略,所有类都继承于基类Object;
  • 类中封装了共同特性,叫做属性,默认会生成setter和getter方法,使用final声明的属性只有getter方法,属性和方法通过打点调用,Dart中的方法不能重载;
  • Dart中的可见性以library(库)为单位,默认情况下每个Dart文件就是一个库,使用 _ 开头的属性或者方法是私有性的,使用import导入库。
//类
class Person {
  String _name;
  int age;
  final String address;

  void work(){
    print("name=$_name, age=$age");
  }
}


//计算属性
class Rect {
  num width, height;

  num get area {
    return width * height;
  }
}

//构造方法
//如果没有自定义构造方法,则会有个默认构造方法;如果存在自定义构造方法,则默认构造方法无效;构造方法不能重载。
//使用命名构造方法,可以实现多个构造方法;使用 类名.方法 的形式实现。
//如果类是不可变的状态,可以把对象定义为编译时常量;使用const声明构造方法,并且所有变量都为final;使用const声明对象,可以省略。
//使用factory修饰的是工厂构造方法。
class Person {
  String name;
  int age;
  final String gender;

  //这种构造方法不能给final赋值
  Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  //这种可以,因为这个赋值是走在构造方法之前
  Person(this.name, this.age, this.gender);

  //命名构造函数
  Person.withName(String name) {
      this.name = name;
  }
}

//使用的时候使用const修饰,里面的值都不可变
class Person {
  final String name;
  final int age;
  final String gender;

  const Person(this.name, this.age, this.gender);
}

//工厂构造方法
class Logger {
  final String name;

  static final Map< String, Logger > _cache = < String, Logger > {};
  
  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final logger = Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }
  
  Logger._internal(this.name);

  void log(String msg) {
    print(msg);
  }
}


//初始化列表,也是解决final不能赋值的问题(跟c++很像啊)
class Person {
  final String name;
  final int age;
  final String gender;

  const Person(this.name, this.age, this.gender);

  //是因为初始化列表也是在构造函数之前执行的
  Person.withMap(Map map) : name = map["name"], age = map["age"], gender = map["gender"] {
  }
}


//静态成员
class Person {
  static int currentPage = 1;
  //常量要用static const来修饰
  static const int maxPage = 10;

  //不可以访问非静态属性
  static void scrollDown() {
    currentPage = 1;
    print("ScrollDown");
  }

  //可以访问静态属性
  void scrollUp() {
    currentPage++;
    print("ScrollUp");
  }
}


//对象操作符:条件成员访问 ?.  ,类型转换 as,是否指定类型:is,is!,级联操作:..
main() {
  Person person;
  person?.work();

  (person as Person).work();

  if (person is Person) {
    person.work();
  }

  new Person()..name = "哈哈"..age = 20..work();
}


//如果实现了call()方法,则该类的对象可以作为方法调用
class Person {
  String name;
  int age;

  void call() {
    print("name=$name, age=$age");
  }
}

main() {
  var person Person();
  person.name = "111";
  person.age = 10;

  person();
}
  • 继承/多态/抽象类/接口/Mixins/操作符复写
class Person {
  String name;
  
  Person(this.name);

  Person.withName(this.name);
}

class Student extends Person {
  int age;

  final String gender;

  //单继承,子类会继承父类的属性,不继承构造方法,能够复写父类的方法与setter/getter,初始化列表会先于父类的构造方法执行
  //如果父类没有无名无参的构造方法,则子类是需要取显式的去调用父类中的构造方法的
  Student(String name, String g) : gender = g, super.withName(name);
}


//抽象类
abstract class Person {
    void run();
}

//类中如果有抽象方法(只定义了,没有实现)则该类必须由 abstract 来修饰
//抽象类主要用于被子类去继承 有点类似接口的概念
class Student extends Person {
  @override
  void run() {
    print("Hello");
  }
}



//每一个类 都可以被当作接口使用,使用 implements,感觉不太爽啊
class Person {
    String name;
    int get age => 18;
    void run() {
      print("person");
    }
}

class Student implements Person {
  @override
  String name;
  
  @override
  int get age => null;

  @override
  void run() {
      print("student");
    }
}

//Mixins 写法上就是使用 with 关键字,必须要先有extends 才能有with,使用多个 with ,时 当这多个被with的类同时实现了a()方法,则该类真正调用的一定是最后with的那个类的方法,被with的类是不能显示的写构造方法,with 的类只能继承于Object
class Person {
    String name;
    int get age => 18;
    void run() {
      print("person");
    }
}

class A {
  a() {
    print("a");
  }
}

class B {
  a() {
    print("b");
  }
}

class C {
  c() {
    print("c");
  }
}

class D extends Person with A, B, C {

}

//简单写法
class E  = Person with A;


//覆写操作符
class Person {
  int age;
  Person(this.age);

  bool operator > (Person person) {
    return this.age > person.age;
  }

  //对象不支持[]取值,使用操作符覆写可以实现
  int operator [](String str) {
    if ("age" == str) {
      return age;
    }
    return 0;
  }
}

枚举与泛型

//枚举,大家都造
enum Season {
  spring,
  summer,
  autumn,
  winter
}

class Utils {
  void put< T>(T s) {
    print(s);
  }
}

小结

学一门新语言一般也就看这些基础东西,很快就看完了,常用的还是高级一些的API,多看看文档,遇到不明白的文档翻译翻译看看,或者搜一搜,一般就差不多了~