说明:
此篇不对Dart语法进行详细总结(在有编程语言的基础,即学习过其他面向对象语言之上),而对比Java进行一些语法的异同进行总结。
内容:
- 关键字
- 数据类型
- 操作符
- 控制语句
- 方法
- 面向对象
- 枚举与泛型
- 库和可见性
- 异步支持
- 元数据
参考资料:
Dart学习笔记
Flutter与Dart 入门
Dart语法学习
一、关键字
关键字 | |||
---|---|---|---|
abstract [1] | do | import [1] | super |
as [1] | var | continue | dynamic [1] |
assert [2] | else | interface | sync *[2] |
enum | is | implements [1] | export [1] |
async *[2] | this | library [1] | throw |
await | new | covariant | true |
break | null | external [1] | factory [1] |
case | try | extends | typedef [1] |
catch | false | operator [1] | switch |
class | final | finally | void |
const | part [1] | rethrow | while |
in | for | return | with |
mixin | get [1] | set [1] | yield *[2] |
default | if | static [1] | deferred [1] |
带有[1] 的关键字是 内置关键字。避免把内置关键字当做标识符使用。 也不要把内置关键字 用作类名字和类型名字。 有些内置关键字是为了方便把 JavaScript 代码移植到 Dart 而存在的。 例如,如果 JavaScript 代码中有个变量的名字为 factory
, 在移植到 Dart 中的时候,你不必重新命名这个变量。
带有[2] 的关键字,是在 Dart 1.0 发布以后又新加的,用于 支持异步相关的特性。 你不能在标记为 async*
、或者 sync*
的方法体内 使用 async
、 await
、或者 yield
作为标识符。 详情请参考:异步支持。
所以其他单词都是 保留词。 你不能用保留词作为关键字。
二、数据类型
1、变量与常量
- 变量声明与初始化:
1.使用var
声明变量,此时没有明确类型,编译的时候根据值明确类型
2.明确变量类型,来帮助 Dart 去捕获异常以及 让代码运行的更高效
3.未初始化时,变量默认值为null
4.如果对象不限于单一类型(没有明确的类型),请使用Object或dynamic关键字var name = ‘Bob’; Object name1 = '张三'; //动态类型 dynamic name2 = '李四'; // 显示声明将被推断类型, 可以使用String显示声明字符串类型 String name3 = 'Bob' ;
- final and const
1.被final
和const
修饰的变量只能赋值一次,不可更改变量值
2.一个 final 变量只能被初始化一次; const变量是一个编译时常量,(Const变量是隐式的final),如果 const 变量在类中,请定义为 static const。
3.被final或者const修饰的变量,变量类型可以省略,建议指定数据类型。
4.被final修饰的顶级变量或类变量在第一次声明的时候就需要初始化,否则会提示错误:
5.const关键字不只是声明常数变量,您也可以使用它来创建常量值,以及声明创建常量值的构造函数,任何变量都可以有一个常量值。// The final variable 'outSideFinalName' must be initialized. final String outSideFinalName
注意:实例变量可以为 final 但是不能是 const 。// 注意: [] 创建的是一个空的list集合 // const []创建一个空的、不可变的列表(EIL)。 var varList = const []; // varList 当前是一个EIL final finalList = const []; // finalList一直是EIL const constList = const []; // constList 是一个编译时常量的EIL // 可以更改非final,非const变量的值 // 即使它曾经具有const值 varList = ["haha"]; // 不能更改final变量或const变量的值 // 这样写,编译器提示:a final variable, can only be set once // finalList = ["haha"]; // 这样写,编译器提示:Constant variables can't be assigned a value // constList = ["haha"];
2、数据类型(内置类型)
-
num(数值)
1、int:其取值通常位于 -253 和 253 之间
2、double:64-bit (双精度) 浮点数,符合 IEEE 754 标准。
3、数值型操作:- 运算符:
+
、-
、*
、/
、~/
、%
其中~/
为整除 - 常用属性:
isNaN
(是否非数字),isEven
(是否为偶数),isOdd
(是否为奇数) - 常用方法:
abs()
,round()
,floor()
,ceil()
,toInt()
,toDouble()
int a = 1; print(a); double b = 1.12; print(b); // String -> int int one = int.parse('1'); // 输出3 print(one + 2); // String -> double var onePointOne = double.parse('1.1'); // 输出3.1 print(onePointOne + 2); // int -> String String oneAsString = 1.toString(); // The argument type 'int' can't be assigned to the parameter type 'String' //print(oneAsString + 2); // 输出 1 + 2 print('$oneAsString + 2'); // 输出 1 2 print('$oneAsString 2'); // double -> String 注意括号中要有小数点位数,否则报错 String piAsString = 3.14159.toStringAsFixed(2); // 截取两位小数, 输出3.14 print(piAsString); String aString = 1.12618.toStringAsFixed(2); // 检查是否四舍五入,输出1.13,发现会做四舍五入 print(aString);
- 运算符:
-
String(字符串)
1、String的创建:- 使用单引号
''
,双引号""
- 使用三个 引号
'''
或双引号"""
创建多行字符串 - 使用
r
创建原始raw
字符串var s1 = '单引号字符串'; var s2 = "双引号字符串"; var s3 = ''' 单引号多创建的多行的字符串, 第二行 '''; var s4 = """ 双引号多创建的多行的字符串, 第二行 """; //使用r创建原始’raw‘字符串,\n不换行 var s5 = r"使用r创建原始’raw‘字符串,\n不换行";
2、字符串操作:
-
运算符:
+
,*
,==
,[]
,String a = "hello"; String b = a + " Dart!"; //hello Dart! print(b); String c = b*2; //hello Dart!hello Dart! print(c); String d = "hello Dart!"; //true print(d==b); String e = d[0]; //h print(e);
-
插值表达式:
${expression}
int e1 = 1; int e2 = 2; //a = 1 print("a = $a"); //e1 + e2 = 3 print("e1 + e2 = ${e1 + e2}");
-
常用属性:
length
(长度),isEmpty
(是否为空),isNotEmpty
(是否非空) -
常用方法:
contains()
,subString()
,startsWith()
,endsWith()
,indexOf()
,lastIndexOf()
,toLowerCase()
,toUpperCase()
,trim()
,trimLeft()
,trimRight()
,split()
,replaceXxx()
-
更多API详见官网:String class
3、
StringBuffer
:- 使用
StringBuffer
创建字符串,当调用其toString()
函数时,才会创建一个 新的String
对象。 -
write()
:将参数字符串加入StringBuffer
对象中 -
writeAll()
:此函数有一个可选的参数来指定每个字符串的分割符var sb = new StringBuffer(); //这里用到了级联操作符 sb..write('Use a StringBuffer for ') ..writeAll(['efficient', 'string', 'creation'], ' ') ..write('.'); var fullString = sb.toString(); //Use a StringBuffer for efficient string creation. printI(fullString);
- 使用单引号
-
bool(布尔型)
1、使用bool表示布尔型
2、布尔值只有个true
,false
,它们都是编译时常量。
3、Dart的类型安全意味着您不能使用 if(nonbooleanValue) 或 assert(nonbooleanValue) 等代码, 相反Dart使用的是显式的检查值。 -
List(数组、列表)
1、List的创建:- 创建List:
var lvs = [1, 2, 3];
- 创建不可变的List:
//其中的值不能修改 var lcs = const [1, 2, 3]; //报错:unsupported operation: Cannot modify for an unmodifiable list lcs[0] = 5;
- 构造创建:
var lns = new List();
2、常用操作:
-
[]
取值,length
数组长度 -
方法:
add()
添加元素,insert()
在指定位置插入,
remove()
移除元素,clear()
清空数组,
indexOf()
获取指定元素位置,lastIndexOf()
倒序获取指定元素位置,
sort()
排序,sublist()
截取数组,shuffle()
,
asMap()
转换为Map,forEach()
循环遍历,
更多API详见官网:List<E> class//创建一个int类型的list List list = [10, 7, 23]; // 输出[10, 7, 23] print(list); // 使用List的构造函数,也可以添加int参数,表示List固定长度,不能进行添加 删除操作 var fruits = new List(); // 添加元素 fruits.add('apples'); // 添加多个元素 fruits.addAll(['oranges', 'bananas']); List subFruits = ['apples', 'oranges', 'banans']; // 添加多个元素 fruits.addAll(subFruits); // 输出: [apples, oranges, bananas, apples, oranges, banans] print(fruits); // 获取List的长度 print(fruits.length); // 获取第一个元素 print(fruits.first); // 获取元素最后一个元素 print(fruits.last); // 利用索引获取元素 print(fruits[0]); // 查找某个元素的索引号 print(fruits.indexOf('apples')); // 删除指定位置的元素,返回删除的元素 print(fruits.removeAt(0)); // 删除指定元素,成功返回true,失败返回false // 如果集合里面有多个“apples”, 只会删除集合中第一个改元素 fruits.remove('apples'); // 删除最后一个元素,返回删除的元素 fruits.removeLast(); // 删除指定范围(索引)元素,含头不含尾 fruits.removeRange(start,end); // 删除指定条件的元素(这里是元素长度大于6) fruits.removeWhere((item) => item.length >6); // 删除所有的元素 fruits.clear();
-
说明:List 是泛型类型,所以可以指定里面所保存的数据类型
// This list should contain only strings. var fruits = new List<String>(); fruits.add('apples'); var fruit = fruits[0]; assert(fruit is String); // Generates static analysis warning, num is not a string. fruits.add(5); // BAD: Throws exception in checked mode.
- 创建List:
-
Set(无序集合)
1、Dart 中的 Set 是一个无序集合,里面不能保护重复的数据。 由于是无序的,所以无法通过索引来从 set 中获取数据。
2、相关方法:
add()
添加一个元素,addAll()
添加一个数组
contains()
是否包含一个元素,containsAll()
是否包含多个元素
intersection()
获取两个集合的交集
更多API详见官网:Set<E> classvoid main() { var sts = new Set(); sts.add("1"); sts.addAll(['gold', 'titanium', 'xenon']); sts.add("1"); //重复添加相同元素被覆盖 //{1, gold, titanium, xenon} print(sts); //titanium print("" + sts.elementAt(2)); //sts==>{1, gold, titanium, xenon} print("sts==>$sts"); var sts2 = new Set.from(['xenon', 'argon']); //sts2==>{xenon, argon} print("sts2==>$sts2"); var sts3 = sts.intersection(sts2); //sts3==>{xenon} print("sts3==>$sts3"); }
注: List<E>
和Set<E>
都继承自EfficientLengthIterable<T>
,并最终继承Iterable<E>
类。
-
Map(集合)
1、说明:
· map 通常也被称之为 字典或者 hash ,也是一个无序的集合,里面 包含一个 key-value 对。map 把 key 和 value 关联起来可以 方便获取数据。和 JavaScript 不同的是, Dart objects 不是 maps。
· 键和值都可以是任何类型的对象。
· 每个 键 只出现一次, 而一个值则可以出现多次。
2、创建://方式一: var map1 = { "one" : [1, "strValue", true], "two" : "twoValue", }; //创建不可变Map var mapConst = const { "one" : [1, "strValue", true], "two" : "twoValue", }; //方式二:未指定泛型类型 var map2 = new Map(); //方式二:指定泛型类型 var map3 = new Map<int, String>();
3、常用属性/方法:
length
Map长度,keys
返回所有key值,values
返回所有的value值
isEmpty()
是否为空Map,isNotEmpty()
是否为非空Map
[]
新增一个元素,remove()
移除一个元素,并将元素返回
containsKey()
是否包含一个key
putIfAbsent(key, function)
设置 key 的值,但是只有该 key 在 map 中不存在的时候才设置这个值,否则 key 的值保持不变。该函数需要 一个方法返回value
。
forEach()
遍历Mapvar map1 = { "one" : [1, "strValue", true], "two" : "twoValue", }; //null print(map1["x"]); //[1, strValue, true] print(map1["one"]); //true print(map1.containsKey("one")); var result = map1.remove("two"); //result==>twoValue,,map1==>{one: [1, strValue, true]} print("result==>$result,,map1==>$map1"); //提示:the argument type 'int' can't be assigned to be parameter type 'String' //map1[1] = 123; var map11 = { "one" : [1, "strValue", true], "two" : "twoValue", 2 : new List() }; //不会提示错误 map11[1] = 123; //新增一个元素 map1["three"] = "addValue"; var keys = map1.keys; //keys==>(one, three) print("keys==>$keys"); var values = map1.values; //values==>([1, strValue, true], addValue) print("values==>$values"); map1.putIfAbsent("four", ()=> 1+2); map1.putIfAbsent("four", ()=> "返回一个value"); //map1==>{one: [1, strValue, true], three: addValue, four: 3} print("map1==>$map1"); print("=========================="); /* one==>[1, strValue, true] three==>addValue four==>3 */ map1.forEach((key, value)=> { print("$key==>$value") }); print("=========================="); /* one==[1, strValue, true] three==addValue four==3 */ for(var me in map1.entries) { print("${me.key}==${me.value}"); }
说明:
1、从上面的代码可以看出,在map中,如果初始的key值都是同一类型,则在通过[]
方式添加的时候,只能添加相同类型的值作为key。
2、虽然 Map 没有实现 Iterable,但是 Map 的 keys 和 values 属性实现了 Iterable。Iterable<K> get keys; Iterable<V> get values;
3、和Java一样,在Map中也有一个内部类
MapEntry<K, V>
,可以通过其属性entries获取到MapEntry<K, V>
类型的迭代器Iterable
,以此来进行遍历。 -
dynamic(动态类型)
1、注意:
dynamic并非Dart中的内置类型,
没有指定类型的变量的类型为dynamic
,
dynamic
一般在使用泛型时使用
2、示例:dynamic a = 10; //a==>10 print("a==>$a"); a = "六六六"; //a==>六六六 print("a==>$a"); var ls = new List<dynamic>(); ls.add("哈哈"); ls.add(333); //ls==>[哈哈, 333] print("ls==>$ls");
三、操作符
1、算数运算符:
-
+
加、-
减、*
乘、/
除、~/
取整、%
取模(余)、-expr
负数 -
++expr
先递增、expr++
后递增、--expr
先递减、expr--
后递减
2、关系运算符:
-
==
相等、!=
不等、>=
大于等于、>
大于、<=
小于等于、<
小于
3、逻辑运算符:
-
!
取反、&&
并且、||
或者
4、赋值运算符:
-
=
等于、+=
加等于、-=
减等于、
*=
乘等于、/=
除等于、
%=
取模(余)等于、~/=
取整等于
<<=
左移等于、>>=
右移等于
^=
非等于、&=
且等于、|=
或等于
??=
判空等于:如果??=
左边的变量为无值,则将右边的值赋值给变量,否则不赋值int a = 10; int b; a ??= 20; b ??=5; //a = 10 a有值10,所以不会赋值20 print("a = $a"); //b = 5 b无值,则将5赋值给b print("b = $b");
5、位和移位操作符
&
且、|
或、^
非、<<
左移、>>
右移
5、条件表达式
condition ? expr1 : expr2
三目运算符
expr1 ?? expr2
返回其中不为空的表达式执行结果
String a = "Hello";
String b = "";
String c = "Dart";
String d = a ?? b;
String e = b ?? c;
//d = Hello
print("d = $d");
//e = Dart
print("e = $e");
6、类型判定操作符
as
、is
、和 is!
操作符是在运行时判定对象
as
:类型转换
is
:如果对象是指定的类型返回 True
is!
:如果对象是指定的类型返回 False
具体例子参考面向对象的总结
7、其他操作符
-
()
:使用方法。代表调用一个方法 -
[]
:访问 List。访问 list 中特定位置的元素
.
:访问 Member(成员)。访问元素,例如 foo.bar 代表访问 foo 的 bar 成员
?.
:条件成员访问。和.
类似,但是左边的操作对象不能为 null,例如foo?.bar
如果foo
为null
则返回null
,否则返回bar
成员
8、级联操作符
..
:级联操作符 (..) 可以在同一个对象上 连续调用多个函数以及访问成员变量。使用级联操作符可以避免创建临时变量,并且写出来的代码看起来更加流畅。(具体详见面向对象中的例子)
querySelector('#button') // Get an object.
..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
说明:
第一个方法 querySelector()
返回了一个 selector
对象。后面的级联操作符都是调用这个对象的成员,并忽略每个操作所返回的值。
四、控制语句
- if...else,if...else if,if...else if...else
- for,for...in
var list = [1, 2, 3, 4, 5]; for (var item in list) { print(item); }
- while do-while
- break continue
- switch...case
其中可以使用跳转标签(自定义标签名称)
打印结果为:Stirng lang = “Dart"; switch (lang) { D: case "Dart": print("This is Dart!"); break; case "Java": print("This is Java!"); break; case "Flutter": print("This is Flutter!"); continue D; //break; //不需要了 default: print("This is NONE!"); break; }
This is Flutter! This is Dart!
- assert(仅在checked模式有效)
网友评论