Dart语言速成

/* 15.Dart(Libraries)*/
//  15.1
//  import 'dart:html';
//  15.2
// demo.dart
import './myapp_demoDartStudy.dart';
//  15.3  使用as关键字为导入的某个包设置一个前缀,或者说别名
import './myapp_demoDartStudy.dart' as lib15;
//  15.4你也可以在导入包时使用show hide关键字来导入某个包中的部分功能
// 只导入foo
//  import 'package:lib1/lib1.dart' show foo;

// 导入除了foo的所有其他部分
//  import 'package:lib2/lib2.dart' hide foo;

//  15.5导入包时使用deferred as可以让这个包懒加载,懒加载的包只会在该包被使用时得到加载,而不是一开始就加载
//  import 'package:greetings/hello.dart' deferred as hello;

//  16.异步
import 'dart:async';
//import 'package:http/http.dart' as http;




/* 11.枚举*/
enum Animal {
  cat,
  dog,
  bird
}


main() {
  //1.变量
//变量定义
//以下代码是Dart中定义变量的方法:
  var a = 1;
  int b = 10;
  String s = "hello";
  dynamic c = 0.5;

//你可以明确指定某个变量的类型,如int bool String,也可以用var或 dynamic来声明一个变量,Dart会自动推断其数据类型。

//2.变量的默认值
//注意:没有赋初值的变量都会有默认值null
//
//final和const
//如果你绝不想改变一个变量,使用final或const,不要使用var或其他类型,一个被final修饰的变量只能被赋值一次,
// 一个被const修饰的变量是一个编译时常量(const常量毫无疑问也是final常量)。可以这么理解:final修饰的变量是不可改变的,而const修饰的表示一个常量。
//
//注意:实例变量可以是final的但不能是const的

  var count = 10;
  final Num = count; // final 只能赋值一次
  const Num1 = 10; // const赋值必须是编译时常量

//final和const的区别:
//区别一:final 要求变量只能初始化一次,并不要求赋的值一定是编译时常量,可以是常量也可以不是。而 const 要求在声明时初始化,并且赋值必需为编译时常量。
//
//区别二:final 是惰性初始化,即在运行时第一次使用前才初始化。而 const 是在编译时就确定值了。

//  3.内建数据类型
//  Dart有如下几种内建的数据类型:
//
//  numbers
//  strings
//  booleans
//  lists(或者是arrays)
//  maps
//  runes(UTF-32字符集的字符)
//  symbols
  // numbers
  var a1 = 0;
  int b1 = 1;
  double c1 = 0.1;

  // strings
  var s1 = 'hello';
  String s2 = "world";

  // booleans
  var real = true;
  bool isReal = false;

  // lists
  var arr = [1, 2, 3, 4, 5];
  List<String> arr2 = ['hello', 'world', "123", "456"];
  List<dynamic> arr3 = [1, true, 'haha', 1.0];

  // maps
  /*通常,map是一个关联键和值的对象。键和值都可以是任何类型的对象。
  每个键只出现一次,但是可以多次使用相同的值。Dart对映射的支持由映射文字和映射类型提供*/
  var map = Map();
  map['name'] = 'zhangsan';
  map['age'] = 10;
  Map m = Map();
  m['a'] = 'a';

  var gifts = Map();
  gifts['first'] = 'partridge';
  gifts['second'] = 'turtledoves';
  gifts['fifth'] = 'golden rings';
  print(gifts);
//  修改其他的值和list方式一样
  gifts['fifth'] = '4';
  print(gifts);

//  如果想让Map集合的key-vaule值是规定的数据类型
  var gifts4 = new Map<String, int>();
  gifts4['first'] = 1;
  gifts4['second'] = 2;
  gifts4['fifth'] = 3;
  print(gifts4);
//  想在map中添加一个key-vaule
  gifts = {'first': 'partridge'};// Add a key-value pair,默认是添加在末尾
  gifts['fourth'] = 'calling birds'; // Add a key-value pair,默认是添加在末尾
//  有需求是定义一个常量的也和List一样
  final constantMap = const {
    2: 'helium',
    10: 'neon',
    18: 'argon',
  };
  print(constantMap);//这样的话 它对应的key的值就不能修改了
//  如果查找在Map中不存的就会返回null
  var gifts41 = {'first': 'partridge'};
  print( gifts41['fifth']);
//  获取Map中所有的key和value
  var hawaiianBeaches = {
    'Oahu': ['Waikiki', 'Kailua', 'Waimanalo'],
    'Big Island': ['Wailea Bay', 'Pololu Beach'],
    'Kauai': ['Hanalei', 'Poipu']
  };
  var keys = hawaiianBeaches.keys;
  print(keys);
  var values = hawaiianBeaches.values;
  print(values);
//  Map的遍历方式
  var hawaiianBeaches4 = {
    'Oahu': ['Waikiki', 'Kailua', 'Waimanalo'],
    'Big Island': ['Wailea Bay', 'Pololu Beach'],
    'Kauai': ['Hanalei', 'Poipu']
  };
  hawaiianBeaches4.forEach((k, v) {
    print('k=$k and v= $v');
  });

  //runes,Dart 中 使用runes 来获取UTF-32字符集的字符。String的 codeUnitAt and codeUnit属性可以获取UTF-16字符集的字符
  var clapping = 'u{1f44f}';
  print(clapping); // 打印的是拍手emoji的表情

  // symbols
  print(#s == Symbol("s")); // true

//  4.函数
//  函数的返回值
/*  Dart是一个面向对象的编程语言,所以即使是函数也是一个对象,
也有一种类型Function,这就意味着函数可以赋值给某个变量或者作为参数传给另外的函数。
虽然Dart推荐你给函数加上返回值,但是不加返回值的函数同样可以正常工作,
另外你还可以用=>代替return语句
*/
  print(add(1, 2)); // 3
  print(add2(2, 3)); // 5
  print(add3(1, 2)); // 3

//  5.命名参数、位置参数、参数默认值
//  5.1命名参数

  // 打印 hello, my name is zhangsan
  sayHello(name: 'zhangsan');

  // 打印 hello, my name is wangwu
  sayHello2(name: 'wangwu');
  /*
  可以看到,定义命名参数时,你可以以 {type paramName} 或者 {paramName: type} 两种方式声明参数,
  而调用命名参数时,需要以 funcName(paramName: paramValue) 的形式调用。

  命名参数的参数并不是必须的,所以上面的代码中,如果调用sayHello()不带任何参数,
  也是可以的,只不过最后打印出来的结果是:hello, my name is null
  */
  //@required注解来标识一个命名参数,这代表该参数是必须的,你不传则会报错
  //  const Scrollbar({Key key, @required Widget child});

//  5.2位置参数
//  使用中括号[]括起来的参数是函数的位置参数,代表该参数可传可不传,位置参数只能放在函数的参数列表的最后面

  // hello, this is zhangsan and I am 20 years old
  sayHello3("zhangsan", 20);
  // hello, this is zhangsan and I am 20 years old, my hobby is play football
  sayHello3("zhangsan", 20, "play football");

//  5.3参数默认值
//  你可以为命名参数或者位置参数设置默认值
  var gg = add53(a:2);
  print("5.3这是默认的参数打印值0:$gg");
  print(sum53(1,2));

//  6.main()函数
//  不论在Dart还是Flutter中,必须都需要一个顶层的main()函数,它是整个应用的入口函数,main()函数的返回值是void,还有一个可选的参数,参数类型是List<String>。
//
//  函数作为一类对象
//  你可以将一个函数作为参数传给另一个函数
//  依次打印:
  //  1
  //  2
  //  3
  var arr6 = [1, 2, 3];
  arr6.forEach(printNum);

//  你也可以将一个函数赋值给某个变量
  var f1 = printNum;
  Function f2 = printNum;
  var f3 = (int a) => print("a = $a");
  f1(1);
  f2(2);
  f3(6);
//  匿名函数
//  大多数函数都是有名称的,比如main() printName()等,但是你也可以写匿名函数
  test((param) {
    // 打印hello
    print(param);
  });
//  匿名函数类似于Java中的接口,往往在某个函数的参数为函数时使用到。

//  7.运算符
//  7.1基本运算符,Dart中的运算符与Java中的类似,比如++a a == b b ? a : b,但是也有一些与Java不太一样的运算符
  // 与Java相同的运算符操作

  int a7 = 1;
  ++a7;
  a7++;
  var b7 = 1;
  print(a7 == b7);  // false
  print(a7 * b7); // 3
  bool real7 = false;
  real7 ? print('real7') : print('not real7'); // not real
  print(real7 && a7 == b7); // false
  print(real7 || a7 == 3); // true
  print(a7 != 2); // true
  print(a7 <= b7); // false
  var c7 = 9;
  c7 += 10;
  print("c7 = $c7"); // c = 19
  print(1<<2); // 4

  // 与Java不太一样的运算符操作

  // is运算符用于判断一个变量是不是某个类型的数据
  // is!则是判断变量不是某个类型的数据
  var s7 = "hello";
  print(s7 is String); // true
  var num7 = 6;
  print(num7 is! String); // true
//  is 判断是否是某个类型,返回true或者false。
//  如果a 是b的实现类,那么a is b 就返回true。

  // ~/才是取整运算符,如果使用/则是除法运算,不取整
  int k7 = 1;
  int j7 = 2;
  print(k7 / j7); // 0.5
  print(k7 ~/ j7); // 0

  // as运算符类似于Java中的cast操作,将一个对象强制类型转换
//  (emp as Person).teach();

//  相当于
//  if (emp is Person) {
//  // Type check
//  emp.firstName = 'Bob';
//  }
//  可以简写为:(emp as persion).firstName='Bob';如果emp 不是persion,name就会抛出exception。

  // ??=运算符 如果 ??= 运算符前面的变量为null,则赋值,否则不赋值
  var param71 = "hello", param72 = null;
  param71 ??= "world";
  param72 ??= "world";
  print("param71 = $param71"); // param1 = hello
  print("param72 = $param72"); // param2 = world

  // ?.运算符
  var str71 = "hello world";
  var str72 = null;
  print(str71?.length); // 11
  print(str72?.length); // null
//  print(str72.length); // 报错

//  7.2运算符(级联操作)
  //  依次打印
  //  I am eating...
  //  I am sleeping...
  //  I am studying...
  Person72()
    ..eat()
    ..sleep()
    ..study();
  /*
  可以看到,使用..调用某个对象的方法(或者成员变量)时,返回值是这个对象本身,
  所以你可以接着使用..调用这个对象的其他方法,这不就类似于Java中的建造者模式,每次build某个属性时,都返回一个this对象吗。
   */

//   8.控制流程
//  if / else switch for /while try / catch语句跟Java中都类似,try / catch语句可能稍有不同
  // if else语句
  int score8 = 80;
  if (score8 < 60) {
    print("so bad!");
  } else if (score8 >= 60 && score8 < 80) {
    print("just so so!");
  } else if (score8 >= 80) {
    print("good job!");
  }

  // switch语句
  String a8 = "hello";
  // case语句中的数据类型必须是跟switch中的类型一致
  switch (a8) {
    case "hello":
      print("haha");
      break;
    case "world":
      print("heihei");
      break;
    default:
      print("WTF");
  }

  // for语句
  List<String> list = ["a8", "b8", "c8"];
  for (int i = 0; i < list.length; i++) {
    print(list[i]);
  }
  for (var i in list) {
    print(i);
  }
  // 这里的箭头函数参数必须用圆括号扩起来
  list.forEach((item) => print(item));

  // while语句
  int start8 = 1;
  int sum8 = 0;
  while (start8 <= 100) {
    sum8 += start8;
    start8++;
  }
  print(sum8);

  // try catch语句 抛出和捕捉异常
  try {
    print(1 ~/ 0);
  } catch (e) {
    // IntegerDivisionByZeroException
    print(e);
  }
  try {
    1 ~/ 0;
  } on IntegerDivisionByZeroException { // 捕获指定类型的异常
    print("error 这个异常捕获还不太会用"); // 打印出error
  } finally {
    print("over 这个异常捕获还不太会用"); // 打印出over
  }

//  9.类(class)
//  9.1类的定义与构造方法
//  Dart中的类没有访问控制,所以你不需要用private, protected, public等修饰成员变量或成员函数
//  要调用Person类的成员变量或成员方法,可以用下面的代码
  var p = new Person9("zhangsan", 20, "male");
  p.sayHello(); // hello, this is zhangsan, I am 20 years old, I am a male
  p.age = 50;
  p.gender = "female";
  p.sayHello(); // hello, this is zhangsan, I am 50 years old, I am a female

//  类除了有跟类名相同的构造方法外,还可以添加命名的构造方法
  // 调用Point类的命名构造方法origin()
  var p9 =  Point9.origin();
  var p92 =  Point9(1, 2);

//  9.2
//  9.3

//  10.运算符重载
  Vector10 v101 =  Vector10(1, 2);
  Vector10 v102 =  Vector10(3, 4);
  (v101 - v102).printVec(); // -2, -2
  (v101 + v102).printVec(); // 4, 6
//  可以重载的运算符有:
//
//  <    +    |    []
//  >    /    ^    []=
//  <=    ~/    &    ~
//  >=    *    <<    ==
//  –    %    >>

//  11.枚举
/*
  枚举类型是一种特殊的类,通常用来表示相同类型的一组常量。使用关键字enum定义枚举。
  枚举的每一个值都有一个index属性,index从0开始计数。
  枚举不能被继承,不能创建实例。
*/
  print(Animal.dog.index); // 1
  // 获取所有枚举值
  List<Animal> animals = Animal.values;
  Animal dog = Animal.dog;
  switch (dog) {
    case Animal.cat:
      print("animal is cat");
      break;
    case Animal.dog:
      print("animal is dog");
      break;
    default:
      print("which animal?");
  }

//  12.mixins
  /*
  mixins是给类添加新的特性的方式,也是一种重用类代码的一种方式。
  mixins的关键字是with。详细的使用,可以查看文档。
  with不能单独使用,必须跟着extends使用。
   */
  var bird12 = Bird12();
  bird12.fly(); // flying

//  13.类的静态成员变量和静态成员方法
  Cons13.sayHello(); // hello, this is zhangsan
  print(Cons13.name); // zhangsan

//  14.泛型(Generics)
  /*
  Java和C++语言都有泛型,Dart语言也不例外,使用泛型有很多好处,比如:
  正确指定泛型类型会产生更好的生成代码。
  泛型可以减小代码的复杂度
  Dart内置的数据类型List就是一个泛型数据类型,你可以往List中塞任何你想的数据类型比如整型、字符串、布尔值等
   */

//  15.Dart库(Libraries)
  /* 15.1
  Dart目前已经有很多的库提供给开发者,许多功能不需要开发者自己去实现,
  只需要导入对应的包即可,使用import语句来导入某个包
   */

//  15.2如果你想导入自己写的某个代码文件,使用相对路径即可,例如当前有一个demo.dart文件,跟该文件同级目录下有个myapp_demoDartStudy.dart文件

  print(add15(1, 2));

//  15.3你可以使用as关键字为导入的某个包设置一个前缀,或者说别名

//  15.4你也可以在导入包时使用show hide关键字来导入某个包中的部分功能

//  15.5导入包时使用deferred as可以让这个包懒加载,懒加载的包只会在该包被使用时得到加载,而不是一开始就加载

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

//  下面的代码使用Dart从网络获取数据并打印出来
  getNetData16().then((str) {
    print(str);
  });
}





/* 4.函数 */
// 声明返回值
int add(int a, int b) {
  return a + b;
}

// 不声明返回值
add2(int a, int b) {
  return a + b;
}

// =>是return语句的简写
add3(a, b) => a + b;

/* 5.命名参数、位置参数、参数默认值*/
/* 5.1命名参数*/
sayHello({String name}) {
  print("hello, my name is $name");
}

sayHello2({name: String}) {
  print("hello, my name is $name");
}

/* 5.2位置参数*/
sayHello3(String name, int age, [String hobby]) { // 位置参数可以有多个,比如[String a, int b]
  StringBuffer sb = StringBuffer();
  sb.write("hello, this is $name and I am $age years old");
  if (hobby != null) {
    sb.write(", my hobby is $hobby");
  }
  print(sb.toString());
}

/* 5.3参数默认值*/
// 命名参数的默认值
int add53({int a,int b = 3}) { // 不能写成:int add({a: int, b: int = 3})
  print("5.3这是默认的参数打印值1:$a+$b ");
  print("5.3这是默认的参数打印值2:($a+3) ");
//  print("5.3这是默认的参数打印值2:%ld",&a);
  return a + b ;
}

// 位置参数的默认值
int sum53(int a, int b, [int c = 3]) {
  int dd = a + b + c;
  print("5.3这是默认的参数打印值3:$dd");
  return a + b + c;
}


/* 6.main()函数*/
printNum(int a) {
  print("$a");
}

test(Function callback) {
  callback("hello匿名函数");
}

/* 7.运算符*/
class Person72 {
  eat() {
    print("I am eating...");
  }

  sleep() {
    print("I am sleeping...");
  }

  study() {
    print("I am studying...");
  }
}

/* 9.类(class)*/
/* 9.1类的定义与构造方法*/
class Person9 {
  String name;
  int age;
  String gender;
  Person9(this.name, this.age, this.gender);
  sayHello() {
    print("hello, this is $name, I am $age years old, I am a $gender");
  }
}
/*
上面的Person类中有3个成员变量,一个构造方法和一个成员方法,
看起来比较奇怪的是Person的构造方法,里面传入的3个参数都是this.xxx,
而且没有大括号{}包裹的方法体,这种语法是Dart比较独特而简洁的构造方法声明方式,
它等同于下面的代码:
Person(String name, int age, String gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
}
 */
class Point9 {
  num x, y;
  Point9(this.x, this.y);
  // 类的命名构造方法
  Point9.origin() {
    x = 0;
    y = 0;
  }
}

//Dart中使用extends关键字做类的继承,如果一个类只有命名的构造方法,在继承时需要注意

class Human {
  String name;
  Human.fromJson(Map data) {
    print("Human's fromJson constructor");
  }
}
//Man 继承了 Human
class Man extends Human {
  Man.fromJson(Map data) : super.fromJson(data) {
    print("Man's fromJson constructor");
  }
}

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

//有时候你仅仅只是在某个类的构造方法中,调用这个类的另一个构造方法
class Point91 {
  num x, y;
  Point91(this.x, this.y);
  // 命名构造方法调用了默认的构造方法
  Point91.alongXAxis(num x) : this(x, 0);
}

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

class Rectangle92 {
  num left, top, width, height;

  // 构造方法传入left, top, width, height几个参数
  Rectangle92(this.left, this.top, this.width, this.height);

  // right, bottom两个成员变量提供getter/setter方法
  num get right => left + width;
  set right(num value) => left = value - width;
  num get bottom => top + height;
  set bottom(num value) => top = value - height;
}

/* 9.3抽象类和抽象方法*/

abstract class Doer93 {
  // 抽象方法,没有方法体,需要子类去实现
  void doSomething();
  // 普通的方法
  void greet() {
    print("hello world!");
  }
}

//EffectiveDoer93  继承了 Doer93
class EffectiveDoer93 extends Doer93 {
  // 实现了父类的抽象方法
  void doSomething() {
    print("I'm doing something...");
  }
}

/* 10.运算符重载*/
class Vector10 {
  num x, y;
  Vector10(this.x, this.y);
  Vector10 operator +(Vector10 v) => new Vector10(x + v.x, y + v.y);
  Vector10 operator -(Vector10 v) => new Vector10(x - v.x, y - v.y);
  printVec() {
    print("x10: $x, y10: $y");
  }
}


/* 12.mixins*/

class Fly12{
  fly(){
    print("flying");
  }
}
class Animal12{}

class Bird12 extends Animal12 with Fly12 {
}


/* 13.// 类的静态成员变量和静态成员方法*/

class Cons13 {
  static const name = "zhangsan";

  static sayHello() {
    print("hello13, this is ${Cons13.name}");
  }
}

/* 16.异步*/
Future checkVersion() async {
//  var version = await lookUpVersion();
  // Do something with version
}

Future<String> getNetData16() async{
//  http.Response res = await http.get("http://www.baidu.com");
//  return res.body;
}
原文地址:https://www.cnblogs.com/gaozhang12345/p/12014968.html