一个最基础的Dart程序1
2
3
4
5
6
7
8
9
10
11
// 定义一个函数
printInterger(int aNumber, int bNumber) {
print('the number is $aNumber and ${bNumber}'); // $aNumber or ${bNumber} 都可以在字符串中使用变量
}
// 程序初始运行的函数
main()
var number = 42; // 声明与初始化变量
printInterger(number);
}
重要概念:
- 所有变量都可以看成是一个
object
,所有的object
都是通过Object
class实例化出来的。这点和js一样 - Dart是强类型语言,累心注释是可选的,因为Dart可以推断类型,如果想要定义一个没有类型的可以使用
dynamic
类型。如- Dart是强类型语言,累心注释是可选的,因为Dart可以推断类型,如果想要定义一个没有类型的可以使用`dynamic`类型。如
- Dart是强类型语言,累心注释是可选的,因为Dart可以推断类型,如果想要定义一个没有类型的可以使用dynamic
类型。如- Dart是强类型语言,累心注释是可选的,因为Dart可以推断类型,如果想要定义一个没有类型的可以使用
dynamic
类型。如var list= <dynamic>[1]
- Dart的私有方法,都是以
_
下划线开头的,不像java直接写关键字private
.
变量
声明变量
1 | // 声明与初始化一个String类型的变量 |
变量默认值
和js
不一样的是,如果在Dart
里面声明一个变量,但是不赋值的话,他的默认值是null
而不是undefined
.
这也从另一个角度说明在Dart
中,万物皆对象.1
2
3
4int lineCount;
var line;
assert(lineCount == null);
assert(line == null);
final && const
Dart
里面的常量用 final
和const
声明。
final
表示单个赋值,一旦赋值,就不能被改变。const
表示编译时确定的值,并且对象会被冻结而完全不可变。
1 | const a = 1+2; |
内置类型
- numbers
- strings
- booleans
- lists(Array)
- sets
- maps
- runes (Unicode characters in a string)
- symbols
可以通过x.runtimeType
来获取对象的类型
number
Dart的number有两种类型: int
和 double
简单的区分,小的整数用int
,浮点数用double
。一般直接用var
声明的话,会根据你声明时的类型做推断,所以如果声明和后面使用不一样的话,建议显式声明.例
1 | var x = 1; // 这里Dart会推断是int类型 |
字符串转数字
在Dart里面,如果字符串和数字相加,会报错,这一点和js隐式转换不同。
1 | var one = int.parse('1'); // String 2 int |
Strings
可以用'
或"
来表示字符串。
字符串内部的变量可以用$value
或者${value}
,一般来说如果是变量,直接用$value
表示,表达式用${value}
,例:
1 | var a = 'String1'; |
如果要创建多行的字符串,则可以用'''
或"""
,1
2
3
4
5var s1 = '''
hi
I'm Jsonz
'''
var s2 = '
Booleans
Dart
里面if
与assert
都只会对 bool
做判断,这点同样与js的隐式转换不同。1
2
3
4
5
6
7
8
9var fullName = '';
assert(fullName); // error
assert(fullName.isEmpty);
var hitPoints = 0;
assert(hitPoints <= 0);
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN);
Lists (既js里面的数组)
1 | var list = [1,2,3, '4']; // 普通list |
Sets
Sets
会根据初始化推断类型,比如下面的例子halogens
会判断为String
类型,这时候添加其他类型的值就会报错。
1 | var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'}; |
Set
通过add
或者addAll
添加item
。
可以通过const
关键字创建编译常量1
2
3
4
5
6
7
8
9
10
11
12
// add 与 addAll
var el = <String>{};
var el2 = {'a', 'b'};
el.add('c');
el.addAll(el2);
assert(el.length == 3);
// const
final constantSet = const {
'a', 'b',
}
Maps(相当于js的对象)
Dart
的Map
不限制key
的类型,意味着如果是number
类型,不需要和js
一样,用[]
包着。
Map
也会推断key
和value
的类型,比如下面的 map1
就是key
为int
类型,value
为string
类型的map
.
如果获取某个map
没有的value
,则value
默认是null
。这点和js
的undefined
不同,可以对比变量初始化的情况类推。
map
也有length
属性,类比js
的Object.keys(obj).length
.
1 | // map的key可以是任意类型 |
Runes
emmm 这个我的理解是UTF-32编码的字符串,简单理解就是可以支持更多类型的字符串,比如emoji,工作用到再去查。
比如'\u{1f44f}';
是👏
,\u2665
是♥
。
Symbols (类比js的Symbol)
对Symbol
的理解可以直接看阮一峰的ES6-Symbol,基本的作用是一样的。
Dart
的Symbol
是compoile-time constants
,就是编译时常量。
使用也很简单,直接在标识前面加个#
1 | const symbol = #symbol; |
Function
Dart是面向对象的语言,所以函数也是一种Function
类型的对象。
参数的默认值都为null
。
1 | // 基本用法 |
main 函数
每个app都需要在最顶层提供一个main
函数用于入口函数,main
函数提供一个void返回值与List<String>
参数(参数指的是命令行传入的参数)。
函数为第一公民
和js一样,Dart也支持将函数作为参数传给另一个函数(高阶函数)。1
2
3
4
5
6void printE(int e) {
print(e);
}
var list = [1,2,3];
list.forEach(printE);
匿名函数、作用域与闭包
这几个和js是一样的,没啥好说
对词法作用域和动态作用域有疑问的可以看这篇
1 | // 匿名函数 |
函数类型(Testing functions for equality)
看着自己理解一下就好1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32void foo() {} // A top-level function
class A {
static void bar() {} // A static method
void baz() {} // An instance method
}
void main() {
var x;
// Comparing top-level functions.
x = foo;
assert(foo == x);
// Comparing static methods.
x = A.bar;
assert(A.bar == x);
// Comparing instance methods.
var v = A(); // Instance #1 of A
var w = A(); // Instance #2 of A
var y = w;
x = w.baz;
// These closures refer to the same instance (#2),
// so they're equal.
assert(y.baz == x);
// These closures refer to different instances,
// so they're unequal.
assert(v.baz != w.baz);
}
函数返回值
函数都会返回一个值,如果没有指定的话,则会返回null。Dart
里面没有undefined
的概念,目前看来所有对于js的undefined
都可以替换成null
1 | foo() {} |
运算符
类型测试运算符
as
、is
、is!
类似 instanceof
1 | class Person { |
分配运算符
1 | a = value; // 直接把value分配给a |
三目运算符
1 | // condition? expr1: expr2 |
Cascade notation
Cascade(..)
有点像链式写法的语法糖,允许您对同一对象进行一系列操作,不得不说这些语法糖真骚…
1 | // .. 写法 |
其他操作符
()
函数调用[]
list.
属性?.
一般用于属性赋值,比如 person?.name = 'jsonz'
(如果person不为null, 则设置person.name为jsonz,避免左边person为null时报错)。
控制流程语句
这里只会挑与js不同的来讲
if..else
不同点是Dart
不会隐式转换,所以判断的内容只能是布尔值1
2
3
4
5
6
7if (false) {
} else if (false) {
} else {
}
loop
for
for in
1 | var collection = ['a', 'b', 'c']; |
while && do-while
break && continue
break 停止循环
continue跳过当前次,进行下一次循环
Switch && case
switch 可以对比 string
、number
、bool
但是不能混着用。
Assert(断言)
写过单元测试的应该对assert
不陌生,如果布尔条件为false
则assert
会中断执行。
不过只会在开发模式起作用,生产环境不会执行。
Other
Throw 抛错
1 | throw FormatException('expected at least 1 section'); |
catch
1 | try { |
finally
1 | try { |