本文目录:
一、注释
二、关键字(56个)
三、变量和常量
四、特殊数据类型
五、运算符
六、控制流程语句
七、异常
本文代码同步发布在Github: https://github.com/AweiLoveAndroid/Flutter-learning/tree/master/projects/dart_demo
怎么运行代码?
如果你使用IDEA或者Android Studio:
打开IDEA或者Android Studio,新建一个Flutter项目,然后在test目录运行我的代码;或者里面去写你自己的
dart
文件,然后右键run
就可以运行了。(注意:需要连接手机或者模拟器)。
如果你使用vscode:
打开vscode,执行菜单栏
运行
,就可以了(确保只有一个dart文件,免得运行的文件不是你想要的,就很尴尬了,vscode也可以设置默认运行的文件是哪个,但是新手不建议去设置,很麻烦。因为你们想最快的运行效果,所有建议只有一个dart文件是最好的)。
一、注释
Dart的注释分为3种:单行注释、多行注释、文档注释。
1、单行注释以
//
开头。Dart编译器会忽略//和行尾之间的所有内容。
例如:// todo:待完成
2、多行注释以
/*
开头,以*/
结尾。介于/*
和*/
两者之间的内容会被编译器忽略(除非该注释是一个文档注释)。多行注释可以嵌套。
例如:/* todo:待完成 */
3、文档注释以
///
或者/**
开头。可以通过dartdoc
命令导出文档。
文档注释的使用,例如:/// todo:待完成
文档的导出如图所示:
文档的导出
导出的结果在我的工程根路径的/doc/api/
文件夹里面,如图所示:
导出的结果
然后浏览器打开index.html
就可以看到文档了。如图所示:
本地的文档
二、关键字(56个)
33个保留字(不能使用保留字作为标识符)
关键字 | - | - | - |
---|---|---|---|
if | superdo | switch | assert |
else | in | this | enum |
is | throw | true | break |
new | try | case | extends |
null | typedef | catch | var |
class | false | void | const |
final | rethrow | while | continue |
finally | return | with | for |
default | - | - | - |
其中内置标志符有:(17个)
关键字 | - | - | - |
---|---|---|---|
abstract | deferred | as | dynamic |
covariant | export | external | factory |
get | implements | import | library |
operator | part | set | static |
typedef |
其中Dart2相对于Dart1新增的,支持异步功能的关键字有:(6个)
关键字 | - | - | - |
---|---|---|---|
async | async* | await | sync* |
yield | yield* |
跟java相比,Dart特有的关键字有:(25个)
关键字 | - | - | - |
---|---|---|---|
deferred | as | assert | dynamic |
sync* | async | async* | in |
is | await | export | library |
external | typedef | factory | operator |
var | part | const | rethrow |
covariant | set | yield | get |
yield* |
三、变量和常量
(一)变量的声明,可以使用 var、Object 或 dynamic 关键字。
创建变量并初始化变量实例:
变量存储引用。
使用Object或dynamic关键字
调用的变量name包含对String值为“张三” 的对象的引用。
name推断变量的类型是String,但可以通过指定它来更改该类型。
如果对象不限于单一类型(没有明确的类型),请使用Object或dynamic关键字
显式声明将被推断的类型
比如String,int等。
这个类型有很多,具体在下文有介绍。
(二)默认值
未初始化的变量的初始值为null(包括数字),因此数字、字符串都可以调用各种方法。
(三)Final 和 Const的用法
如果您从未打算更改一个变量,那么使用 final 或 const,不是var,也不是一个类型。
一个 final 变量只能被设置一次;const 变量是一个编译时常量。(Const变量是隐式的final。)
final的顶级或类变量在第一次使用时被初始化。
1、被final或者const修饰的变量,变量类型可以省略。
2、被 final 或 const 修饰的变量无法再去修改其值。
3、注意:flnal 或者 const 不能和 var 同时使用,
4、常量如果是类级别的,请使用 static const
5、常量的运算
6、const关键字不只是声明常数变量。您也可以使用它来创建常量值,以及声明创建常量值的构造函数。 任何变量都可以有一个常量值。
7、只要任何插值表达式是一个计算结果为null或数字,字符串或布尔值的编译时常量,那么文字字符串就是编译时常量。(关于$表达式和不同的数据类型后面会讲解。)
四、特殊数据类型
Dart支持以下特殊类型:
numbers 数字
strings 字符串
booleans 布尔
lists list集合(也称为数组)
maps map集合
runes 字符(用于在字符串中表示Unicode字符)
(一)num数字类型
num是数字类型的父类,有两个子类 int
和 double
。
num类型包括基本的运算符,如+,-,/和*,位运算符,如>>,在int类中定义。如果num和它的子类没有你要找的东西,math库可能会找到。比如你会发现abs(),ceil()和floor()等方法。
(1)int类型
int
表示整数,int默认是64位二进制补码整数,int的取值不大于64位,具体取决于平台。编译为JavaScript时,整数仅限于valus,可以用双精度浮点值精确表示。可用的整数值包括-253和253之间的所有整数,以及一些幅度较大的整数。这包括一些大于2^63的整数。 因此,在编译为JavaScript的Dart VM和Dart代码之间,int类中的运算符和方法的行为有时会有所不同。例如,当编译为JavaScript时,按位运算符将其操作数截断为32位整数。
示例如下:
判断一个int值需要多少bit(位),可以使用bitLength
,例如:
(2)double类型
Dart的double是IEEE 754标准中规定的64位浮点数。double的最大值是:1.7976931348623157e+308
,double类里面有一个常量maxFinite
,我们通过语句print(double. maxFinite)
可以得到double的最大值
。
如果一个数字包含一个小数,那么它就是一个double类型。示例如下:
(3)Dart2.1里面新增特性,当double的值为int值时,int自动转成double。
例如:double test = 12;//打印结果是12.0
(4)Dart2.1,int也有api转成double。
例如:
(5)Dart2.1,double也有api转成int,会把小数点后面的全部去掉。
例如:
(二)String字符串类型
Dart里面的String是一系列 UTF-16代码单元。
(1)您可以使用单引号或双引号来创建一个字符串。
(2)单引号或者双引号里面嵌套使用引号。
单引号里面嵌套单引号,或者//双引号里面嵌套双引号,必须在前面加反斜杠。
(3)多个字符串相邻中间的空格问题:
除了单引号嵌套单引号或者双引号嵌套双引号不允许出现空串之外,其余的几种情况都是可以运行的。
示例如下:
单引号里面有双引号,混合使用运行正常
双引号里面有单引号,混合使用运行正常
(4)您可以使用相邻字符串文字或+ 运算符连接字符串:
直接把相邻字符串写在一起,就可以连接字符串了。
用+把相邻字符串连接起来。
使用单引号或双引号的三引号:
print(connectionStr3)输出结果如下:
print(connectionStr4)的输出结果如下:
(5)关于转义符号的使用
声明raw字符串(前缀为r)
,在字符串前加字符r
,或者在\
前面再加一个\
,
可以避免“\”的转义作用,在正则表达式里特别有用。
举例如下:
(6)使用$
可以获得字符串中的内容,使用${表达式}
也可以将表达式的值放入字符串中。使用${表达式}
时可以使用字符串拼接,也可以使用String
类或者Object
里面的某些方法获得相关字符串属性。
1、使用
$+字符串
2、使用$+字符串,以及字符串拼接
3、这里使用了字符串的拼接,以及使用了String类里面的toUpperCase()函数,把字母全部变成大写。
注:==
操作符测试两个对象是否相等。assert
是断言,如果条件为true,继续进行,否则抛出异常,中端操作。
(三)bool布尔类型
Dart表示布尔值的类型叫做bool
,它有两个值,分别是:true
和false
,它们都是编译时常量。
Dart使用的是显式的检查值,检查值的类型,如下所示:
assert
是Dart语言里的的断言函数
,仅在Debug模式下有效
。
在开发过程中, 除非条件为真,否则会引发异常。(断言失败则程序立刻终止)。
(四)list集合,也成为数组
在Dart中,数组是List对象,因此大多数人只是将它们称为List。
以下是一个简单的Dart的List:
创建一个int类型的list
要创建一个编译时常量const的list,示例如下:
注意事项:
1.可以直接打印list包括list的元素,list也是一个对象。但是java必须遍历才能打印list,java若直接打印list,结果是地址值。
2.和java一样list里面的元素必须保持类型一致,不一致就会报错。
3.和java一样list的角标从0开始。
Dart的list集合给我们提供了很多api,示例如下,api太多就不逐个展示了:
操作 | 代码 | 含义 | 输出结果 |
---|---|---|---|
新增 | list.add(1);print(list); | 把数字1添加到list中,默认是添加到末尾 | [10, 7, 23, 1] |
移除 | list.remove(1);print(list); | 移除数字1 | [10, 7, 23] |
插入 | list.insert(0, 5);print(list); | 在索引为0的地方插入数字5 | [5, 10, 7, 23] |
查找某个索引的值 | int value = list.indexOf(10);print(value); | 查找10在list中的索引 | 1 |
判断元素是否包含 | bool result = list.contains(5);print(result); | 查找list中是否包含数字5 | true |
(五)map集合
Dart中的map
是将键和值相关联的对象。键和值都可以是任何类型的对象。每个键只出现一次,但您可以多次使用相同的值。
(1)创建方式:
直接声明,用{}表示,里面写key和value,每组键值对中间用逗号隔开。
先声明,再去赋值。
要创建一个编译时常量const的map,请在map文字之前添加const:
(2)添加元素。格式: 变量名[key] = value,其中key可以是不同类型。
(3)修改元素。格式:变量名[key] = value
例如:把key为first的元素对应的value改成 alibaba
(4)查询元素
(5)删除元素.可以使用map的remove或者clear方法。
(6)关于map集合的小结:
(六)runes 字符(用于在字符串中表示Unicode字符)
Unicode为世界上所有的书写系统中使用的每个字母,数字和符号定义了唯一的数值。
Dart字符串是UTF-16代码单元的序列,所以在字符串中表达32位Unicode值需要特殊的语法。
Unicode代码点的常用方法是\uXXXX
,其中XXXX
是一个4位十六进制值。
例如,心形字符()是\u2665
。要指定多于或少于4个十六进制数字,请将该值放在大括号中。 例如,笑的表情符号是\u{1f600}
。
String类有几个属性可以用来提取符文信息。 codeUnitAt和codeUnit属性返回16位代码单元。
以下示例说明了符文,16位代码单元和32位代码点之间的关系。
五、运算符
运算符在每一种语言中都很常见,Dart的运算符如下表所示:
我这里不详细去讲解每个运算符的用法,我这里主要讲一下Dart里面比较有代表性的以及有特点的一些运算符相关用法。
(一)?.
像.
一样,但最左边的操作数可以为空。
比如:Test?.funs
从表达式Test中选择属性funs,除非Test为空(当Test为空时,Test?.funs
的值为空)。
(二)..
级联符号..
级联符号..
允许您在同一个对象上进行一系列操作。 除了函数调用之外,还可以访问同一对象上的字段。其实相当于java的链式调用。
例如:
(三)?? 三目运算符的一种形式。
expr1 ?? expr2
表示如果expr1非空,则返回其值; 否则返回expr2的值。
(四)~/ 除法,返回一个整数结果,其实就是取商。
小学都学过:被除数 ÷ 除数 = 商 ... 余数
,在Dart里面A ~/ B = C
,这个C就是商,这个语句相当于Java里面的A / B = C
。Dart与java不同的是,Dart里面如果使用A / B = D
语句,这个结果计算出来的是真实的结果。示例如下:
顺便提一下取模
操作,在Dart里面A % B = E
,这个E就是余数,%
符号表示取模
,例如:
(五)as、is与is!
as
判断属于某种类型is
如果对象具有指定的类型,则为trueis!
如果对象具有指定的类型,则为false
例如:
六、控制流程语句
控制流程语句和Java语言差不多,有这些语句:
(一)if else
(二)for循环
1.简单for循环
例如:
也可以通过for循环内部的闭包获取索引的值。
2.使用foreach循环,一般List和Set都可以使用foreach遍历元素。
如果要迭代的对象是Iterable,或者你不想知道当前的迭代次数,可以使用foreach()
方法。
3.使用for in循环,一般List和Set使用for-in遍历元素。
4.Dart的for循环里面可以使用标记:(比较有特色的地方)
Dart的标记:标记是后面跟着冒号的标识符
。带标记的陈述是以标记 L为前缀的陈述。带标签的case子句是标签L前缀的switch语句中的case子句。标签的唯一作用是为“break”和“continue”声明提供对象。
大多数此功能与其他语言类似,因此以下大部分内容可能对读者来说都很熟悉。Dart的switch声明中处理continue是比较独特的,所以这一部分需要一点时间去阅读和熟悉。
1.循环(Loops)
标签最常用作break
和 continue
内部循环。假设你有嵌套的循环,并要跳转到break
或continue
到外部循环。如果没有标记,这不可能(轻松)实现。
以下示例使用continue 标记名称
从内部循环直接跳转到外部循环的下一轮循环:
此函数在所有list中运行,但只要总和过高,就会停止累加变量。
同理,可以使用break跳出到外部循环:
2.跳出代码块
标记也可以用于跳出代码块。假设我们想要统一处理错误条件,但有多个条件(可能是深度嵌套)来揭示(reveal)错误。标签可以帮助构建此代码。
对代码块的使用break指令,使得Dart继续执行块之后的语句。从某个角度来看,它是一个结构化的goto
,它只允许跳转到当前指令之后的嵌套较少的位置。
虽然声明标签在代码块中最有用,但它们可以用在在每个语句中。
例如,foo: break foo;
是一个有效的声明。
请注意:continue
上面的循环可以通过将循环体包装到带标记的代码块中并使用break来实现。
也就是说,以下两个循环是等效的:
3.Switch中的标记(label)
标记也可以用于switch内部。
Switch中的标记允许continue
使用其它的case
子句。在最简单的形式中,这可以作为一种方式来实现下一个子句:
有趣的是, Dart没有要求continue
的目标子句是当前case
子句之后的子句。
带标记的任何case
子句都是有效的目标。这意味着,Dart的switch
语句实际上是状态机(state machines)。
以下示例演示了这种滥用,其中整个switch
实际上只是用作状态机(state machines)。
这个函数从一个switch子句跳到另一个子句,模拟了狗的生命。
在Dart中,标签只允许在case子句中使用,因此我必须添加一些case永远不会到达的行。
这个功能很酷,但很少使用。由于我们的编译器增加了复杂性,我们经常讨论它的删除。到目前为止,它已经在我们的审查中幸存下来,但我们最终可能会简化我们的规范并让用户自己添加一个while(true)
循环(带有标记)。这个dog的示例可以重写如下:
如果状态值被命名为常量,那么它将与原始版本一样具有可读性,但不需要switch
语句来支持状态机。
(三)while 和do while
(四)break continue
break 停止循环
continue 跳到下一个循环
如果使用Iterable(list或者set)
,则可以使用下面这种方式:
(五)switch case
比较integer, string,编译时常量 使用==。比较对象必须是同一个类的实例(不是其子类的实例),并且该类不能重写==。枚举类型在switch也可以运行。
每一条非空case字子句以break结束,也可以使用其他的方式结束:continue
,throw
或者return
。
(六)assert
如果布尔条件为false,则使用assert语句来中断正常执行。例如:
要将消息附加到断言,请添加一个字符串作为第二个参数。
上例中assert
的第一个参数可以是任何解析为布尔值的表达式。如果表达式的值为true,则断言成功并继续执行。如果为false,则断言失败并抛出异常
七、异常
Dart代码可以抛出并捕获异常。Exception是指示发生意外事件的错误。如果未捕获异常,则会暂停引发异常的isolate ,并且通常会终止isolate及其程序。
与Java相比,Dart的所有异常都是未经检查的异常。方法不会声明它们可能引发的异常,并且您不需要捕获任何异常。
Dart提供了Exception
和Error
类型,以及许多预定义的子类型。当然,您可以定义自己的Exception。但是,Dart程序可以抛出任何非null对象,作为Exception(不仅仅是Exception和Error对象)。
(一)throw
以下是抛出或引发异常的示例:
你也可以抛出任意对象,例如:throw '格式不正确!';
通常在开发中会抛出Error或者Exception类型。
因为抛出异常是一个表达式,所以可以在=>语句中以及允许表达式的任何其他地方抛出异常:
(二)try catch
捕获或捕获异常会阻止异常传递(除非您重新抛出异常)。捕获异常使您有机会处理它:
要处理可能抛出多种类型异常的代码,可以指定多个catch子句
。与抛出对象的类型匹配的第一个catch子句处理异常。如果catch子句未指定类型,则该子句可以处理任何类型的抛出对象。
您可以使用on或catch
或两者兼而有之
。使用on时需要指定异常类型
。使用catch时,你的异常处理程序需要异常对象。
示例:
您可以指定一个或两个参数catch()。第一个是抛出的异常,第二个是堆栈跟踪(StackTrace对象)。
示例:
要部分处理异常,同时允许它传递,请使用rethrow关键字。
示例:
(三)finally
无论是否抛出异常,要确保某些代码运行,请使用finally
子句。如果没有catch子句匹配该异常,则在finally子句运行后传递异常。
示例:
评论