# 「Flutter」成长笔记 - Dart 基础入门
# 1 / 编写一个 Hello World 并运行
Dart通过 main() 方法作为程序入口
void main(){
print('Hello world') // 控制台打印
};
2
3
# 2 / 变量与常量
# 1 - 变量
通过 var
声明一个变量(这一点与Javascript
很像),然后可以给变量赋值不同的值
若声明后未初始化,默认为
null
❗ 注意: Dart
是一门强类型语言(与Javascript
不同),在第一次赋值时,如果已经确定是字符串类型,则不能更改为别的类型。
如果真的想改变Dart
中的字符串类型,可以使用dynamic
关键字
# 2 - 常量
如果想设置一个常量,即让一个变量不可变,那么可以使用final
或者const
进行修饰,例如
var number;
number = 15;
print('A的年龄是 $number 岁');
number = '20'; // 注意,变量类型是可以变的
print(number);
final c = 30; // final 修饰的变量只能被声明一次
print(c);
const d = 50;
print(d);
2
3
4
5
6
7
8
9
10
11
12
🔺 那么const
与final
的区别是什么?
const 变量是一个编译时常量,而 final 变量在第一次使用时被初始化(const变量是隐式的final)。实例变量可以是 final,但不能是 const。如果常量是类别级的,可以使用
static const
,例如static const PI = 3.1415
# 3 - 内置类型
Dart内置了一下类型:
- Number(数值型)
- String(字符型)
- Boolean(布尔型)
- List(列表)
- Map(键值对)
- Runes(符号字符)
- Symbols(标识符)
# 3.1 - 数值型
数值型分整型(int)和浮点型(double),可以用
num
,int
,double
进行声明
❗ 注意: num
声明的变量加入的是int
型,还可以被改成double
型,但是,反过来int
声明的变量不能再赋值为double
型
// Right
num a = 10;
a = 10.1;
// Wrong
int b = 20;
b = 20.1;
2
3
4
5
6
7
我们看一下源码,就可以理解了
abstract class int extends num
abstract class double extends num
2
# 3.2 - 数值型操作
- 运算符: + 、- 、* 、/、~/ 、%
- 常用属性: isNaN 、isEven 、isOdd 等
- 常用方法:round() 、floor() 、ceil() 、toInt() 、toDouble() 、abs()
在 Dart 2.0里,如果我们声明的是 double 型,且值为int
型时,int
型会自动转换成double
型,例如
double a = 10; // 打印出来为 10.0
也可以通过API来手动转换
print(a.toDouble());
# 3.3 - 字符串
在 Dart 中字符串有以下几种创建方式:
- 使用单引号,双引号创建字符串
- 使用三个引号或双引号创建多行字符串
- 使用 r 创建原始 raw 字符串
# 3.4 - 字符串操作
- 运算符:+ 、* 、== 、[]
- 插值运算符:${expression}
- 常用属性:length 、isEmpty 、isNotEmpty
- 常用方法:contains() 、subString() 、startsWith() 、endsWith() 、indexOf() 、lastIndexOf() 、toLowerCase() 、toUpperCase() 、trim() 、trimLeft() 、trimRight() 、split() 、replaceAll()
关于字符串的一些Api和属性,可以浏览 https://www.jianshu.com/p/3aa5bada902d
❗ 注意: 字符串中单引号里面嵌套单引号,或者双引号里面嵌套双引号,必须在前面加反斜杠进行转意,这个与Javascript
里字符串很像。(建议双引号里面嵌套单引号混合使用)
另外,在 Dart 里,可以进行单行拼接,也可以多行拼接,例如:
String str1 = 'ha' 'ha'; // 单引号空格拼接
String str2 = "ha" "ha"; // 双引号空格拼接
String str3 = 'ha' + 'ha'; // 单引号加号拼接
String str4 = "ha" + "ha"; // 双引号加号拼接
// 使用三引号拼接多行字符串
String str5 = '''
Dart 入门
Dart 进阶
''';
String str6 = """Dart 入门
Dart 进阶""";
2
3
4
5
6
7
8
9
10
11
12
13
最后,介绍一下插值表达式,即 ${expression}
double iphone = 11000.0;
print('最新Iphone价格为 $iphone');
2
# 3.5 - 布尔型
布尔型通常用在if条件判断中
- 使用 bool 表示布尔型
- 布尔值只有 true 和 false
- 布尔值式编译时常量
- 可以在 debug 模式下通过 assert 断言函数判断布尔值。如果不为真,会引发异常并终止程序往下运行,这在开发时非常有用
var a = '';
assert(a.isEmpty);
var nullValue;
assert(nullValue == null);
2
3
4
5
# 3.6 - List / 数组
在Dart中,List表示集合,这其实和数组是同一个概念。创建方法如下:
// 创建 List
var list1 = [1,2,3];
// 通过构造函数创建 List
var list2 = new List();
// 创建一个不可变的 List
var list3 = const[1,2,3];
2
3
4
5
6
7
8
在实际开发中,我们经常需要访问List里面的内容,可以通过
list[]
方式来访问,比如list[1]
。
有的时候也需要改变
List
里面的内容,可以这样写:list[0] = 0
,但是如果试图改变一个不可变的 List,就会报错
List 中的常有方法有:
- length() - 获取集合长度
- add() - 增加一个元素
- insert() - 在指定位置插入元素
- remove()
- clear()
- indexOf() - 获取指定元素位置
- lastIndexOf() - 获取最后一个指定元素位置
- sort() - 排序
- asMap()
- forEach() - 传入一个方法,遍历执行
- shuffle() - 随机打乱 List 元素顺序
# 3.7 - Map
在 Dart 中,Map 以 key-value(键值对)形式存储,键和值都可以是任何类型的对象,每个键只出现一次
- 通过直接声明的方式创建一个
Map
,里面写key
和value
,并且用逗号隔开,例如:
Map game = {
'name': 'Switch',
'company': '任天堂'
};
2
3
4
- 创建一个不可变的
Map
,只需在Map
前面加入const
,例如
Map game = const{
'name': 'Switch',
'company': '任天堂'
};
2
3
4
- 通过构造函数先声明,再赋值,例如
Map game= new Map();
game['name'] = 'Switch';
game['company'] = '任天堂';
2
3
· 以上的代码可以通过 变量名[Key] = value
的形式修改 Map 中的元素(键值)
· 我们也可以通过调用 remove
或 clear
方法来移除元素
game.remove('name'); // 把key为 'name' 的元素移除
game.clear(); // 清空整个 Map 集合
2
# 3.8 - dynamic / Object
在 Dart 里,一切皆对象,而且这些对象的父类都是Object
当没有明确类型时,编译的时候会根据值来明确类型,例如
var name1 = 'abc';
Object name2 = 'def'
dynamic name3 = 'hij'
2
3
以上写法都没有问题,但是 Dart 不建议我们这样做,在实际开发中,我们应尽量为变量确定一个类型,这样做可以提高安全性,加快运行速度
如果不指定类型,则在debug模式下类型会时动态的,所以还是建议以下写法
String a = 'abc';
- dynamic
使用 dynamic 时则是告诉编译器,我们不用做类型检测,并且知道自己在做什么。如果我们调用一个不存在的方法时,会执行
noSuchMethod()
方法。 默认情况下(在 Oject 里实现)它会抛出NoSuchMethodError
。举个例子:
dynamic obj = '小明';
obj['age'] = 18;
2
这段代码编译时可以通过,但实际运行中会抛出NoSuchMethodError
异常
为了在运行时可以对类型进行检测,我们可以使用as
和is
关键字,例如
dynamic obj = <String, int>();
if(obj is Map<String, int>){
obj['age'] = 20
};
var map = obj as Map<String, int>;
2
3
4
5
# 4 - 运算符
计算机语言常用的几个运算符就不多说了,我们看一下 Dart 常用和特有的几个运算符
- 三目运算符
三目运算符在别的计算机语言中也右,在 Flutter 中用得较多,通常与 state 状态管理结合,用来判断组件得状态,其基本用法如下
expression1 ?? expression2 // 如果expression1非空,则返回其值,否则返回expression2的值
// 具体 Demo
int a = 20;
var value = a > 10 ? a : 0;
2
3
4
5
6
- ~/ 除法,返回一个整数结果(取商)
var value = 12~/7;
print(value); // 1
2
- 级联操作符
级联可以对同一个对象执行一系列的操作。除了函数调用,你也可以存取统一对象上的字段。这可以减少创建临时变量的步骤,写出更优美的代码
querySelector('#confirm') // Get an object.
..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
// 等价于
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
2
3
4
5
6
7
8
9
10
- as / is / is!
- as:判断属于某种属性
- is:如果对象具有指定的类型,则为 true
- is!:如果对象具有指定的类型,则为 false
# 5 - 异常捕获
Dart可以抛出任意类型的对象。方式如下
throw Exception('I am Error')
有的时候,我们需要捕获异常,确保程序的健壮性,例如
try{
// 捕获特定类型的异常
}on AuthorizationException catch(e){
// 捕获特定类型的异常,但不需要这个对象
}on Exception{
// 捕获所有异常
}catch(e){
// ...
}finally{
// ...
}
2
3
4
5
6
7
8
9
10
11