Dart基础系统学习
目录介绍
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岁】
- 邮箱:[email protected]
- 微信: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
声明的对象.dynamic
与var
一样都是关键词,声明的变量可以赋值任意对象.而dynamic
与Object
相同之处在于,他们声明的变量可以在后期改变赋值类型.
dynamic t; Object x; t = "hi world"; x = 'Hello Object'; //下面代码没有问题 t = 1000; x = 1000;
dynamic
与Object
不同的是,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<String> 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<String> 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> { 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<String>(() { return "This is a doubi"; }); } Future testB() async{ return new Future<String>(() { return "This is a doubi"; }); } Future<String> testC() { return new Future<String>(() { return "This is a doubi"; }); }
6.1.1 普通异步案例
Future是支持泛型的,例如Future,通过T指定将来返回值的类型。
- 定义了一个叫getTest的函数,返回值为Future<String>.你可以通过new关键字创建一个Future。Future的构造函数,需要一个函数作为参数,这个函数返回T类型的数据。在匿名函数中的返回值就是Future的返回值。
- 当调用了getTest方法,他返回Future<String>.我们通过调用then方法订阅Future,在then中注册回调函数,当Future返回值时调用注册函数。同时注册了catchError方法处理在Future执行之间发生的异常。这个例子中不会发生异常。
void test() { getTest().then((value) { print("测试----------"+value); }).catchError((error) { print('测试----------Error'); }); } Future<String> getTest() { return new Future<String>(() { 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<String> getTest() { return new Future<String>(() { 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<String> getTest() { return new Future<String>.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<String> getTest() { return new Future<String>.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<String> getTest() { return new Future<String>.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<String> loadAppVersion() async => "1.0.2"
- 注意,方法的函数体并不需要使用 Future API。 Dart 会自动在需要的时候创建 Future 对象。
好的代码是这样的
void main() { //调用异步方法 doAsync(); } // 在函数上声明了 async 表明这是一个异步方法 Future<bool> doAsync() async { try { // 这里是一个模拟请求一个网络耗时操作 var result = await getHttp(); //请求出来的结果 return printResult(result); } catch (e) { print(e); return false; } } //将请求出来的结果打印出来 Future<bool> printResult(summary) { print(summary); } //开始模拟网络请求 等待 5 秒返回一个字符串 getHttp() { return new Future.delayed(Duration(seconds: 5), () => "Request Succeeded"); }
不好的写法
void main() { doAsync(); } Future<String> doAsync() async { return getHttp().then((r){ return printResult(r); }).catchError((e){ print(e); }); } Future<String> printResult(summary) { print(summary); } Future<String> 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.关于博客汇总链接
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...
- 邮箱:[email protected]
- 阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV
- segmentfault头条:https://segmentfault.com/u/xi...
- 掘金:https://juejin.im/user/593943...