资讯专栏INFORMATION COLUMN

Dart基础系统学习

stackvoid / 2255人阅读

摘要:中所有的基础类型类等都继承,默认值是,自带和,而如果是或者的话,那么它只有一个方法。断言失败则程序立刻终止检查是否为空字符串检查是否小于等于检查是否为检查是否为字符串中,支持类型。类继承类,通过关键字调用类的构造函数。泛型全面支持泛型。

目录介绍

01.变量声明

1.1 var声明变量

1.2 变量和常量

1.3 dynamic和Object

02.数据类型

2.1 基本数据类型

2.2 String字符串

2.3 List数组

2.4 Map集合

03.Dart函数和运算符

3.1 Dart函数介绍

3.2 命名参数

3.3 参数默认值

3.4 void无返回值

3.5 匿名函数

3.6 运算符介绍

04.Dart流程控制

4.1 流程控制语句

4.2 if和else

4.3 for循环

4.4 while循环

4.5 break和continue

4.6 switch和case

4.7 assert断言

05.Dart面向对象

5.1 类简单介绍

5.2 构造函数

5.3 继承类

5.4 重载和重写

5.5 抽象类

5.6 访问权限

5.7 静态方法

5.8 泛型

06.Dart异步解读

6.1 Future简单介绍

6.1.1 普通异步案例

6.1.2 耗时异步案例

6.2 async/await介绍

6.3 看一个案例

07.Dart异常捕获

7.1 异常处理形式

7.2 抛出异常

7.3 捕获异常

7.4 Finally讲解

08.Dart枚举

8.1 枚举使用

8.2 元数据

8.3 自定义注解

09.Dart字符串

9.1 String简单介绍

9.2 单双引号互相嵌套

9.3 字符串拼接方式

想换个工作,渴望同行内推我

个人信息

姓名:杨充【26岁】

邮箱:yangchong211@163.com

微信:13667225184

GitHub:https://github.com/yangchong211

博客汇总:https://github.com/yangchong2...

干活集中营:Android端技术博客和开源项目审核员

目前工作情况:在职状态

技术项目和博客:GitHub项目7k以上star,follower1.1k以上,发表博客100多篇。

热爱技术:开源项目和博客多次被鸿洋,郭霖,Android技术周刊,干活集中营等等推荐。

学历:武汉软件工程职业学院,大专学历

工作年限:3年多

工作地点:北京

关于近期投递简历一点感想

从进入Android这个行业以来,前两次几乎都是朋友内推,面试机会相对容易,都是一个App一个人做或者两个人做,用户相对来说并不多。这次想着离职,主要是想进入一个较大的平台,大概可以理解为Android端有个至少四五人,可以进行技术交流,渴望自己能够在技术上突破,这就像自己平时独自跑步,和跟着一群跑马拉松的人跑步,那种紧张感肯定是不一样的。

近段时间,尝试着向一些较大的公司投递简历,大概在拉钩上投了15个左右(不喜欢海投),发现绝大多数简历到不了技术那里,就被人事说学历不够,经验不够,工作不匹配等情况回绝。不过也可以理解,看简历无非就是学历和经验,貌似自己的履历是差了一点。

这大概是第一次在网上发一个主动希望同行内推的介绍,如果你的公司有Android方面的招聘,能否内推一下我这个小人物,感谢。

01.变量声明 1.1 var声明变量

类似于kotlin中的var,它可以接收任何类型的变量,但最大的不同是Dart中var变量一旦赋值,类型便会确定,则不能再改变其类型,如:

var t;
t="yc";
// 下面代码在dart中会报错,因为变量t的类型已经确定为String,
// 类型一旦确定后则不能再更改其类型。
t=1000;

最大的不同是Dart中var变量一旦赋值,类型便会确定,则不能再改变其类型。因为Dart本身是一个强类型语言,任何变量都是有确定类型的,在Dart中,当用var声明一个变量后,Dart在编译时会根据第一次赋值数据的类型来推断其类型,编译结束后其类型就已经被确定。

思考一下,dart在编译时是如何确定数据的类型呢?

1.2 变量和常量
1.2.1 变量

变量如下所示

var curPage = 0;
var title = "潇湘剑雨:小杨逗比";

Dart 不需要给变量设置 setter getter 方法, 这和 kotlin 等类似。Dart 中所有的基础类型、类等都继承 Object ,默认值是 NULL, 自带 getter 和 setter ,而如果是 final 或者 const 的话,那么它只有一个 getter 方法。

1.2.2 常量

const 的值在编译期确定,final 的值要到编译时才确定。

Dart 中 final 表示常量

//final 表示常量
final title = "潇湘剑雨:小杨逗比";

static const 组合代表了静态常量

//static const 组合代表了静态常量
static const String complete = "COMPLETE";

final和const区别

两者区别在于:const 变量是一个编译时常量,final变量在第一次使用时被初始化。被final或者const修饰的变量,并且变量类型可以省略。

注意点

const变量同时也是final变量,实例变量可以为final但不能是const。

编译错报错,原因final变量只能赋值一次!

//定义初始化一个变量
final double number = 13.14;
number = 520;
//调用打印数字方法
printNumber(number);

1.2.3 注意+

在Java中可以直接通过 + 号将字符串和int类型拼接,但是在Dart中是不行的。

//在Java中,下面操作可行
ToastUtils.showRoundRectToast("二维码扫描"+1000);

//在dart中,下面错误操作,编译不通过,直接会有红色提示
int yc = 0;
print("潇湘剑雨" + yc);

//在dart中,下面正确操作
int yc = 0;
print("潇湘剑雨" + yc.toString());

1.3 dynamic和Object

Object 是dart所有对象的根基类,也就是说所有类型都是Object的子类(包括Function和Null),所以任何类型的数据都可以赋值给Object声明的对象.

dynamicvar一样都是关键词,声明的变量可以赋值任意对象.而dynamicObject相同之处在于,他们声明的变量可以在后期改变赋值类型.

dynamic t;
Object x;
t = "hi world";
x = "Hello Object";
//下面代码没有问题
t = 1000;
x = 1000;

dynamicObject不同的是,dynamic声明的对象编译器会提供所有可能的组合,而Object声明的对象只能使用Object的属性与方法, 否则编译器会报错. 如:

 dynamic a;
 Object b;
 main() {
     a = "";
     b = "";
     printLengths();
 }   

 printLengths() {
     // no warning
     print(a.length);
     // warning:
     // The getter "length" is not defined for the class "Object"
     print(b.length);
 }

变量a不会报错, 变量b编译器会报错

dynamic的这个特性与Objective-C中的id作用很像.

dynamic的这个特点使得我们在使用它是需要格外注意,这很容易引入一个运行时错误.

02.数据类型 2.1 基本数据类型

var 可以定义变量,同时 Dart 属于动态类型语言,支持闭包。

Dart 中 number 类型分为 int 和 double ,其中 java 中的 long 对应的也是 Dart 中的 int 类型。Dart 中没有 float 类型。

//int类型   这里没有long类型
var positionIndex = 0;

//double类型   这里没有float类型
var time = 1993.03;

这里提个小建议,声明变量的时候,可以选择加上具体类型。添加类型可以更加清晰表达你的意图。

//定义初始化一个变量
double number = 13.14;

Dart 下只有 bool 型可以用于 if 等判断,不同于 JS 这种使用方式是不合法的 var g = "null"; if(g){} 。

以bool代表布尔值,只有两个对象是布尔类型的,那就是true和false所创建的对象,这两个对象都是编译时常量。

//类似Java中的布尔类型
bool mIsLogin = false;

if (!mIsLogin) {
  //没有登陆
  print("没有登陆");
} else {
  //已经登陆
  Navigator.of(context).push(new MaterialPageRoute(builder: (context) {
    return new CollectPage();
  }));
}

注意,下面这种情况会报错

String name ="yc";
//报错 因为name不是bool类型
if(name){
  print(name);
}

可以使用的是先式的检查值。assert是语言内置的断言的函数,仅在检查模式有效,在开发过程中,除非条件为真,否则会引发异常。(断言失败则程序立刻终止)

// 检查是否为空字符串
var fullName = "doubi";
assert(fullName.isEmpty);

// 检查是否小于等于0
var hitPoints = 0;
assert(hitPoints <= 0);

// 检查是否为 null.
var unicorn;
assert(unicorn == null);

// 检查是否为 NaN.
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN);

2.2 String字符串

Dart 中,switch 支持 String 类型。后面会多带带拿出来讲解一下。

//字符串
var title = "潇湘剑雨:小杨逗比";

2.3 List数组

声明一个list非常的简单,可以简单使用方括号[]定义list。下面是list的常用操作。

main(List args) {
  //或者
  List arr1 = [1,2,3,4];
  var arr2 = [1,2,3,4];
 
  print(list); //Output: [1, 2, 3, 4]
  //Length 长度
  print(list.length);
 
  //Selecting single value 获取单个值
  print(list[1]);    //Outout: 2
 
  //Adding a value 添加值到list
  list.add(10);
 
  //Removing a single isntance of value 删除单个值
  list.remove(3);
 
  //Remove at a particular position 删除指定位置的值
  list.removeAt(0);
}

注意:第一个元素索引是0,最后一个元素是length-1

如果你想定义一个编译时常量list,例如,list的内容是不可改变的,可以使用关键字const

var list = const [1,2,3,4];   

2.4 Map集合

定义map也很简单。可以使用花括号{}定义map。

  void test() {
    var map = {
      "key1": "value1",
      "key2": "value2",
      "key3": "value3"
    };
    //Fetching the values 获取值
    print(map["key1"]);    //Output: value1
    print(map["test"]);    //Output: null

    //Add a new value 添加值
    map["key4"] = "value4";

    //Length   获取长度
    print(map.length);

    //Check if a key is present 检查是否存在
    var containsKey = map.containsKey("value1");
    print(containsKey);

    var entries = map.entries;
    var values = map.values;
  }

打印日志

2019-06-20 17:22:39.200 4281-4329/com.hwmc.auth I/flutter: value1
2019-06-20 17:22:39.200 4281-4329/com.hwmc.auth I/flutter: null
2019-06-20 17:22:39.200 4281-4329/com.hwmc.auth I/flutter: 4
2019-06-20 17:22:39.200 4281-4329/com.hwmc.auth I/flutter: false

也可以使用map构造函数定义map。

可以发现map可以存储多种类型的数据

var squares = new Map();
squares["a"] = 1;
squares["b"] = 2;
squares["c"] = 3.0;
squares["d"] = [1,2];
squares["e"] = "yc逗比";

print(squares["a"]);    
print(squares["e"]);

打印日志

2019-06-20 17:27:32.841 4281-4329/com.hwmc.auth I/flutter: 1
2019-06-20 17:27:32.841 4281-4329/com.hwmc.auth I/flutter: yc逗比

03.Dart函数和运算符 3.1 Dart函数介绍

dart中的函数和JavaScript中有点类似。你需要定义就是函数的名字、返回值(有返回值或者void)、参数。

  void test(){
    var name = fullName("杨充", "逗比");
    print(name);
  }

  String fullName(String firstName, String lastName) {
    return "$firstName $lastName";
  }

3.2 命名参数

dart有个叫命名参数的东西。当你调用函数的时候,你必须指定参数的名字。要使用命名参数,可以将函数的参数包括在花括号{}内。

如果你在调用命名参数的函数时,没有指定参数的名字,则会提示红色报错,无法通过编译。

  void test(){
    var name = fullName("杨充", "逗比");
    print(name);
  }

  String fullName(String firstName, String lastName) {
    return "$firstName $lastName";
  }

3.3 参数默认值

你可以给函数的命名参数一个默认值。下面的例子给lastName一个默认值。

  void test(){
    var name = fullName("杨充", "逗比");
    print(name);
  }

  fullName(String firstName, String lastName) {
    return "$firstName $lastName";
  }

3.4 void无返回值

大多数都是void无返回值的函数,这个跟java中类似。没什么好讲的……

3.5 匿名函数

在dart中函数比较灵活,例如,你可以将函数当参数传递给另一个函数。

  void test(){
    out(printOutLoud);
  }

  out(void inner(String message)) {
    inner("Message from inner function");
  }

  printOutLoud(String message) {
    print(message.toUpperCase());
  }

这里定义一个函数名字为out,需要一个函数参数。然后我定义一个名为printOutLoud的函数,他所做的就是将字符串以大写的形式打印。

dart 也有匿名函数,所以上面的例子中不用预定一个函数,而是传递一个匿名函数。

另一个匿名函数的例子。

3.6 运算符介绍

这部分和java差不多,可以直接看我java部分的博客:运算符

04.Dart流程控制 4.1 Dart流程控制

大概有这么多

if和else

for循环

while循环

break和continue

switch和case

assert断言

4.2 if和else

if-else 和其他语言一样比较简单。

var number = 57;
if (number > 100) {
  print("Large Number");
} else if (number < 100) {
  print("Small Number");
} else {
  print("Number is 100");
}

可以用三元运算符代替if-else

int age = 60;
String status = age < 50 ? "年轻人" : "老年人";

4.3 for循环

for循环和java几乎是一样的,代码如下

  void test() {
    for (int i = 0; i < 10; i++) {
      print("$i");
    }
  }

4.4 while循环

while循环如下所示

  void test() {
    int i = 0;
    while(i < 10) {
      print("$i");
      i++;
    }
  }

The classic for do while loop. 典型的do while循环。

  void test() {
    int i = 0;
    do {
      print("$i");
      i++;
    } while (i < 10);
  }

4.6 break和continue 4.7 switch和case

代码如下所示

  void test() {
    int age = 50;
    switch(age) {
      case 10:
        print("Too Young.");
        break;
      case 20:
      case 30:
        print("Still Young!");
        break;
      case 40:
        print("Getting old.");
        break;
      case 50:
        print("You are old!");
        break;
    }
  }

05.Dart面向对象 5.1 类简单介绍

创建一个类和创建类的实例

void test1(){
  Dog d = new Dog();
}
class Dog {

}


var cat = new Cat("逗比", 12);
class Cat {
  String name;
  int age;

  Cat(String name, int age) {
    this.name = name;
    this.age = age;
  }
}

5.2 构造函数

普通构造函数

var cat = new Cat("逗比", 12);

class Cat {
  String name;
  int age;

  Cat(String name, int age) {
    this.name = name;
    this.age = age;
  }
}

命名构造函数

给构造函数提供了名称,这样做使得不同的构造函数变的更加清晰。

Map map = new Map();
map["name"]= "哈巴狗";
map["age"] = 5;
Dog d = new Dog.newBorn(map);


class Dog {
  String name;
  int age;

  Dog(this.name, this.age);

  Dog.newBorn(Map json) {
    name = json["name"];
    age = json["age"];
  }
}

5.3 继承类

可以使用extends关键字继承其他的类。

Pug 类继承Dog类,通过super关键字调用Dog类的构造函数。

Pug p = new Pug("逗比哈巴狗", 5);
print(p.name);


class Dog {
  String name;
  int age;

  Dog(this.name, this.age);

  Dog.newBorn() {
    name = "Doggy";
    age = 0;
  }
}

class Pug extends Dog {
  Pug(String name, int age): super(name, age);
}

也可以通过this关键字,在冒号之后调用同一个类中的其他构造函数。

定义了两个命名构造函数,他们只需要dog的名字,然后调用Pug的默认构造函数。

Pug p = new Pug.small("傻逼");
print(p.name);

class Dog {
  String name;
  int age;

  Dog(this.name, this.age);

  Dog.newBorn() {
    name = "逗比哈巴狗";
    age = 0;
  }
}

class Pug extends Dog {
  Pug(String name, int age): super(name, age);

  Pug.small(String name): this(name, 1);

  Pug.large(String name): this(name, 3);
}

5.4 重载和重写

方法重写

代码如下,最后打印值是:你真是个逗比

Pug p = new Pug();
print(p.bark());

class Dog {
  bark() {
    print("Bow Wow");
  }
}

class Pug extends Dog {
  @override
  bark() {
    print("你真是个逗比!");
  }
}

方法重载

5.5 抽象类

可以通过abstract关键字声明抽象类

只需要在类声明前添加abstract关键字,方法不需要。方法只需要签名,不需要实现。

abstract class AbstractDog {
  void eat();
  void _hiddenMethod();
}

class SmallDog extends AbstractDog{
  @override
  void _hiddenMethod() {
    
  }

  @override
  void eat() {
    
  }
}

5.6 访问权限

默认类中的所有属性和方法是public的。在dart中,可以在属性和方法名前添加“_”使私有化。现在让我们使name属性私有化。

可以发现,调用私有化变量或者方法的时候会出现红色警告

  void test() {
    Dog d = new Dog("哈巴狗", 5);
    //这个报错
    print(d.name);
    print(d.age);
  }

Dog代码如下所示

class Dog {
  String _name;
  int age;

  Dog(this._name, this.age);

  String get respectedName {
    return "Mr.$_name";
  }

  set respectedName(String newName) {
    _name = newName;
  }

  Dog.newBorn() {
    _name = "哈巴狗";
    age = 0;
  }

  bark() {
    print("Bow Wow");
  }

  _hiddenMethod() {
    print("I can only be called internally!");
  }
}

5.7 静态方法

如果想让方法或者属性静态化,只需要在声明前添加static关键字。

void test() {
  Dog.bark();
}


class Dog {
  static bark() {
    print("Bow Wow");
  }
}

5.8 泛型

dart全面支持泛型。假设你想在你定义的类中,想持有任意类型的数据。如下是怎样使用泛型定义这样的类。

DataHolder dataHolder = new DataHolder("Some data");
print(dataHolder.getData());
dataHolder.setData("New Data");
print(dataHolder.getData());
//下面这个会报错,因为dataHolder对象在创建的时候就已经限制为String类型
dataHolder.setData(123);
print(dataHolder.getData());


class DataHolder {
  T data;

  DataHolder(this.data);

  getData() {
    return data;
  }

  setData(data) {
    this.data = data;
  }
}

06.Dart异步解读 6.1 Future简单介绍

async 库中有一个叫Future的东西。Future是基于观察者模式的。如果你熟悉Rx或者JavaScript的Promises,你就很容易明白了。

首先先看一下下面的案例,看看它们之间有什么区别?

  void testA() async{
    new Future(() {
      return "This is a doubi";
    });
  }

  Future testB() async{
    return new Future(() {
      return "This is a doubi";
    });
  }

  Future testC() {
    return new Future(() {
      return "This is a doubi";
    });
  }

6.1.1 普通异步案例

Future是支持泛型的,例如Future,通过T指定将来返回值的类型。

定义了一个叫getTest的函数,返回值为Future.你可以通过new关键字创建一个Future。Future的构造函数,需要一个函数作为参数,这个函数返回T类型的数据。在匿名函数中的返回值就是Future的返回值。

当调用了getTest方法,他返回Future.我们通过调用then方法订阅Future,在then中注册回调函数,当Future返回值时调用注册函数。同时注册了catchError方法处理在Future执行之间发生的异常。这个例子中不会发生异常。

  void test() {
    getTest().then((value) {
      print("测试----------"+value);
    }).catchError((error) {
      print("测试----------Error");
    });
  }

  Future getTest() {
    return new Future(() {
      return "This is a doubi";
    });
  }
  
  //打印结果
  2019-06-21 17:11:12.941 16501-16583/com.hwmc.auth I/flutter: 测试----------This is a doubi

下面这个案例会发生异常

  void test() {
    getTest().then((value) {
      print("测试----------"+value);
    }).catchError((error) {
      print("测试----------Error");
    });
  }

  Future getTest() {
    return new Future(() {
      return "This is a doubi";
    });
  }
  
  //打印结果
  2019-06-21 17:18:46.896 16501-16583/com.hwmc.auth I/flutter: 测试----------Error

6.1.2 耗时异步案例

在生产环境中都是一些耗时的操作,例如,网络调用,我们可以使用Future.delayed()模仿。

现在如果你运行,你将需要2秒,才能返回结果。

  void test() {
    getTest().then((value) {
      print("测试----------"+value);
    }).catchError((error) {
      print("测试----------Error");
    });
  }

  Future getTest() {
    return new Future.delayed(new Duration(milliseconds: 2000),() {
      return "This is a doubi";
    });
  }

接下来再看一个案例。在调用函数之后,我们添加了print语句。在这种场景中,print语句会先执行,之后future的返回值才会打印。这是future的预期行为.但是如果我们希望在执行其他语句之前,先执行future。

  void test() {
    getTest().then((value) {
      print("测试----------"+value);
    }).catchError((error) {
      print("测试----------Error");
    });
    print("测试----------逗比是这个先执行吗");
  }

  Future getTest() {
    return new Future.delayed(new Duration(milliseconds: 2000),() {
      return "This is a doubi";
    });
  }
  
  2019-06-21 17:26:16.619 16501-16583/com.hwmc.auth I/flutter: 测试----------逗比是这个先执行吗
  2019-06-21 17:26:17.176 16501-16583/com.hwmc.auth I/flutter: 测试----------This is a doubi

6.2 async/await介绍

思考一下,看了上面的案例,对于future的预期行为,如果我们希望在执行其他语句之前,先执行future,该怎么操作呢?

这就需要用到需要用到async/await。在test函数的花括号开始添加async关键字。我们添加await关键字在调用getTest方法之前,他所做的就是在future返回值之后,继续往下执行。我们将整个代码包裹在try-catch中,我们想捕获所有的异常,和之前使用catchError回调是一样。使用awiat关键字,必须给函数添加async关键字,否则没有效果。

注意:要使用 await,其方法必须带有 async 关键字。可以使用 try, catch, 和 finally 来处理使用 await 的异常!

  Future test() async {
    try {
      String value = await getTest();
      print("测试----------"+value);
    } catch(e) {
      print("测试----------Error");
    }
    print("测试----------逗比是这个先执行吗");
  }

  Future getTest() {
    return new Future.delayed(new Duration(milliseconds: 2000),() {
      return "This is a doubi";
    });
  }
  
  2019-06-21 17:32:37.701 16501-16583/com.hwmc.auth I/flutter: 测试----------This is a doubi
  2019-06-21 17:32:37.702 16501-16583/com.hwmc.auth I/flutter: 测试----------逗比是这个先执行吗

6.3 看一个案例

一个 async 方法 是函数体被标记为 async 的方法。 虽然异步方法的执行可能需要一定时间,但是 异步方法立刻返回 - 在方法体还没执行之前就返回了。

void getHttp async {
    // TODO ---
}

在一个方法上添加 async 关键字,则这个方法返回值为 Future。

例如,下面是一个返回字符串的同步方法:

String loadAppVersion() => "1.0.2"

使用 async 关键字,则该方法返回一个 Future,并且 认为该函数是一个耗时的操作。

Futre loadAppVersion() async  => "1.0.2"

注意,方法的函数体并不需要使用 Future API。 Dart 会自动在需要的时候创建 Future 对象。

好的代码是这样的

void main() {
 //调用异步方法
 doAsync();
}

// 在函数上声明了 async 表明这是一个异步方法
Future doAsync() async {
  try {
    // 这里是一个模拟请求一个网络耗时操作
    var result = await getHttp();
    //请求出来的结果
    return printResult(result);
  } catch (e) {
    print(e);
    return false;
  }
}
//将请求出来的结果打印出来
Future printResult(summary) {
  print(summary);
}

//开始模拟网络请求 等待 5 秒返回一个字符串
getHttp() {
 return new Future.delayed(Duration(seconds: 5), () => "Request Succeeded");
}

不好的写法

void main() {
 doAsync();
}

Future doAsync() async {
    return  getHttp().then((r){
      return printResult(r);
    }).catchError((e){
      print(e);
    });
}

Future printResult(summary) {
  print(summary);
}

Future getHttp() {
 return new Future.delayed(Duration(seconds: 5), () => "Request Succeeded");
}

07.Dart异常捕获 7.1 异常处理形式

dart 使用经典的try-catch处理异常,使用关键字throw抛出一个异常。

7.2 抛出异常

看看如何抛出异常

  void test1(){
    divide(10, 0);
  }

  divide(int a, int b) {
    if (b == 0) {
      throw new IntegerDivisionByZeroException();
    }
    return a / b;
  }

当b变量的值为0的时候,抛出一个内置的异常IntegerDivisionByZeroException。

如何定义异常日志呢?

可以在异常中携带一个字符串信息。

  void test1(){
    divide(10, 0);
  }

  divide(int a, int b) {
    if (b == 0) {
      throw new Exception("逗比,不能为0的");
    }
    return a / b;
  }

7.3 捕获异常

某种类型的异常可以通过on关键字捕获,如下:

  void test1(){
    try {
      divide(10, 0);
    } on IntegerDivisionByZeroException {
      print("逗比,异常被捕获了");
    }
  }

  divide(int a, int b) {
    if (b == 0) {
      throw new IntegerDivisionByZeroException();
    }
    return a / b;
  }

注意问题,捕获的异常层级要大于抛出的异常,否则捕获会失败

还是会抛出异常"逗比,不能为0的",因为Exception比IntegerDivisionByZeroException层级要高。

  void test1(){
    try {
      divide(10, 0);
    } on IntegerDivisionByZeroException {
      print("逗比,异常被捕获了");
    }
  }

  divide(int a, int b) {
    if (b == 0) {
      throw new Exception("逗比,不能为0的");
    }
    return a / b;
  }

如果你不知道抛出异常的类型,或者不确定,可以使用catch块处理任意类型的异常。

  void test1(){
    try {
      divide(10, 0);
    } on IntegerDivisionByZeroException {
      print("逗比,异常被捕获了");
    } catch (e) {
      print(e);
    }
  }

  divide(int a, int b) {
    if (b == 0) {
      throw new Exception("yc other exception.");
    }
    return a / b;
  }

7.4 Finally讲解

dart也提供了finally块,即是否发生异常这个块都会执行。

  void test1(){
    try {
      divide(10, 0);
    } on IntegerDivisionByZeroException {
      print("逗比,异常被捕获了");
    } catch (e) {
      print(e);
    }finally {
      print("I will always be executed!");
    }
  }

  divide(int a, int b) {
    if (b == 0) {
      throw new Exception("yc other exception.");
    }
    return a / b;
  }

08.Dart枚举 8.1 枚举使用

dart 支持枚举,用法和java一样。

Dog d = new Dog("哈巴狗", 12, CurrentState.sleeping);
print(d.state == CurrentState.sleeping); //Prints "true"


enum CurrentState {
  sleeping,
  barking,
  eating,
  walking
}

class Dog {
  String name;
  int age;
  CurrentState state;

  Dog(this.name, this.age, this.state);

  static bark() {
    print("Bow Wow");
  }
}

8.2 元数据

使用元数据给代码添加额外信息,元数据注解是以@字符开头,后面是一个编译时常量或者调用一个常量构造函数。

有三个注解所有的Dart代码都可使用:@deprecated、@override,@proxy,下面直接上@deprecated的示例:

元数据可以在library、typedef、type parameter、constructor、factory、function、field、parameter、或者variable声明之前使用,也可以在import或者export指令之前使用,使用反射可以再运行时获取元数据信息。

8.3 自定义注解

定义自己的元数据注解。下面的示例定义一个带有两个参数的@toDo注解:

void test1() {
  doSomething();
}


@toDo("seth", "make this do something")
void doSomething() {
  print("do something");
}

class toDo {
  final String who;
  final String what;
  const toDo(this.who, this.what);
}

09.Dart字符串 9.1 String简单介绍

Dart字符串是UTF-16编码的字符序列,可以使用单引号或者双引号来创建字符串:

String str1 = "单引号字符串";
String str2 = "双引号字符串";

print(str1);        //输出:单引号字符串
print(str2);        //输出:双引号字符串

9.2 单双引号互相嵌套

String中单、双引号互相嵌套情况如下所示

String str1 = "单引号中的"双引号"字符串";
String str2 = "双引号中的"单引号"字符串";

print("yc-str1--" + str1);
print("yc-str2--" + str2);

//单引号里面有单引号,必须在前面加反斜杠
String str3 = "单引号中的"单引号"";
String str4 = "双引号里面有双引号,"双引号"";
print("yc-str3--" + str3);
print("yc-str4--" + str4);

打印值

2019-06-21 17:52:07.722 16501-16583/com.hwmc.auth I/flutter: yc-str1--单引号中的"双引号"字符串
2019-06-21 17:52:07.723 16501-16583/com.hwmc.auth I/flutter: yc-str2--双引号中的"单引号"字符串
2019-06-21 17:52:07.723 16501-16583/com.hwmc.auth I/flutter: yc-str3--单引号中的"单引号"
2019-06-21 17:52:07.723 16501-16583/com.hwmc.auth I/flutter: yc-str4--双引号里面有双引号,"双引号"

注意点::

单引号嵌套单引号之间不允许出现空串(不是空格),双引号嵌套双引号之间不允许出现空串:

//String str5 = "单引号""""单引号";  //报错了,逗比
String str6 = "单引号"" ""单引号";
String str7 = "单引号""*""单引号";
String str8 = "双引号"" ""双引号";
String str9 = "双引号""*""双引号";
//String str10 = "双引号""""双引号";   //报错了,逗比
print("yc-str6--" + str6);
print("yc-str7--" + str7);
print("yc-str8--" + str8);
print("yc-str9--" + str9);

打印值

2019-06-21 17:56:21.847 16501-16583/com.hwmc.auth I/flutter: yc-str6--单引号 单引号
2019-06-21 17:56:21.847 16501-16583/com.hwmc.auth I/flutter: yc-str7--单引号*单引号
2019-06-21 17:56:21.847 16501-16583/com.hwmc.auth I/flutter: yc-str8--双引号 双引号
2019-06-21 17:56:21.847 16501-16583/com.hwmc.auth I/flutter: yc-str9--双引号*双引号

其他介绍 01.关于博客汇总链接

1.技术博客汇总

2.开源项目汇总

3.生活博客汇总

4.喜马拉雅音频汇总

5.其他汇总

02.关于我的博客

github:https://github.com/yangchong211

知乎:https://www.zhihu.com/people/...

简书:http://www.jianshu.com/u/b7b2...

csdn:http://my.csdn.net/m0_37700275

喜马拉雅听书:http://www.ximalaya.com/zhubo...

开源中国:https://my.oschina.net/zbj161...

泡在网上的日子:http://www.jcodecraeer.com/me...

邮箱:yangchong211@163.com

阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV

segmentfault头条:https://segmentfault.com/u/xi...

掘金:https://juejin.im/user/593943...

博客汇总项目开源地址:https://github.com/yangchong2...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75099.html

相关文章

  • Flutter基础(三)Dart快速入门

    摘要:工具可以报告两种问题警告和错误。警告只是说明代码可能无法正常工作,但不会阻止程序执行。中的是一组无序的集合。其中来指定异常类型,来捕获异常对象。其中代表只导入指定的部分,代表除了指定的部分都导入。 本文首发于微信公众号「刘望舒」 前言 Dart是Flutter SDK指定的语言,因此要学习Flutter,Dart是必须掌握的。关于Dart可以写一本书了,这里用一篇文章来介绍下Dart的精...

    helloworldcoding 评论0 收藏0
  • Flutter是跨平台开发终极之选吗?Android开发该如何快速上手Flutter?

    摘要:月日,谷歌正式发布了的。到底能不能成为跨平台开发终极之选是基于前端诞生的,但是对前端开发来说,的环境配置很麻烦,需要原生的平台知识,还要担心遇上网络问题。现在已经不是曾经的小众框架,这两年里它已经逐步成长为主流的跨平台开发框架之一。 ...

    luckyyulin 评论0 收藏0
  • Flutter基础(二)Flutter最新开发环境搭建和Hello World

    摘要:注释处的方法是程序的入口,使用了符号,这是中单行函数或方法的简写,等价于如下代码方法是框架的入口,如果不返回方法,那么执行的是一个控制台应用。 本文首发于微信公众号「刘望舒」 前言 最近的Google I/O大会上,Flutter1.5 开始支持移动、Web、桌面和嵌入式设备,从不温不火的sky一直进化到如今热门的Flutter,Flutter的发展已经超出很多人的想象。我对跨平台技术一...

    tuomao 评论0 收藏0
  • Flutter终将逆袭!1.2版本发布,或将统一江湖

    摘要:在去年大展上发布首个版后,正式版于年月召开的上正式发布。今天在巴塞罗那召开的发布会上,正式发布了跨平台框架的版本。支持此版本包括,该也于昨天发布。除了,团队还发布了的预览版,这是一套用于和的性能工具。 在去年 MWC 大展上发布首个 Beta 版后,Flutter 1.0 正式版于 2018 年 12 月召开的 Flutter Live 2018 上正式发布。今天在巴塞罗那召开的 MW...

    JayChen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<