目录
- 变量声明
- 数据类型
- 关键字与运算符
- 流程控制语句
- 函数
变量声明
1. var
- var 类似于JavaScript中的var,它可以接收任何类型的变量,但最大的不同是Dart中var变量一旦赋值,类型便会确定,则不能再改变其类型
var t;
t = "hi world";
// 下面代码在dart中会报错,因为变量t的类型已经确定为String,
// 类型一旦确定后则不能再更改其类型。
t = 1000;
2. dynamic和Object
- object 是Dart所有对象的根基类,也就是说所有类型都是Object的子类(包括Function和Null),所以任何类型的数据都可以赋值给Object声明的对象.
- dynamic与var一样都是关键词,声明的变量可以赋值任意对象。
- dynamic与Object相同之处在于,他们声明的变量可以在后期改变赋值类型。
- dynamic与Object不同的是,dynamic声明的对象编译器会提供所有可能的组合, 而Object声明的对象只能使用Object的属性与方法, 否则编译器会报错。如:
dynamic a;
Object b;
main() {
a = "";
b = "";
print(a.length);
print(b.length); // 报错 (object中没有length属性)
}
3. final和const
- 如果定义的变量不会变化,则可以使用 final 或 const 来声明。两者区别在于:const 变量是一个编译时常量,final变量在第一次使用时被初始化。
final username = '张三'; // 定义了一个常量
username = 'isyang'; // 报错
const pi = 3.1415926;
const area = pi * 100 * 100;
- 可以通过const 来创建常量的值,就是说const[]本身是构造函数,示例:
final stars = const [];
const buttons = const [];
数据类型
- Number (包括两类: int整形, doble浮点型)
- String (可以使用三个单引号,单个单引号,双引号来定义多好的String类型)
var s1 = '''
多行文本
多行文本
''';
- Boolean (bool类型的值必须是true才被认为是true,0,1则不能编译正常通过)
- List (类似于JS的数组Array对象)
var list = [1, 2, 3]
- Map (键值对,Key必须是唯一的)
var test1 = {
't1': '测试1',
't2': '测试2',
't3': '测试3',
}
var test2 = new Map()
test2['t1'] = '测试1';
test2['t2'] = '测试2';
关键字与运算符


类型判断
- is (如果对象是该类型,则返回true):如果person是null或不是一个Person,则不执行判断里的语句
if (person is Person) {
// 执行
}
- as ( 类型转换):如果person是null或不是一个Person,则会抛出异常
(person as Person).firstName = 'Bob';
条件表达式 ??
expr1 ?? expr2 // 如果expr1为非空,则返回其值;否则,计算并返回expr2的值。
级联操作
级联操作用两个点(..)标识,可对统一对象执行一系列操作。类似于JavaScript里的Promise的then处理。主要目的是为了简化代码
new Address.of('Freddy Krueger')
...setStreet('Elm', '13a')
...city = "Carthage"
...state = "Eurasia";
querySelector('#confirm') // Get an object.
..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
等同于
var address = new Address.of('Freddy Krueger');
address.setStreet('Elm', '13a');
address.city = "Carthage";
address.state = "Eurasia";
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
注意:严格来说, 级联的..符号不是操作符。它只是Dart语法的一部分。
流程控制语句
-
if 和 else
-
for (循环)
-
while do-while (循环)
-
break 和 continue
-
switch 和 case
-
try-catch 和 throw
- 抛出异常,示例
throw FormatException('抛出一个FormatException异常'); // 可以抛出任意对象 throw '数据非法';
- 捕获异常,可以指定一个或两个参数来捕获异常(catch),第一个是抛出的异常,第二个是堆栈跟踪(StackTrace对象),示例
try { // ... } on Exception catch(e) { //1. 需要指定异常类型时使用on print('Exception details:\n $e'); } catch (e, s) { // 2. 当需要处理异常对象时,使用catch, e表示异常,s表示调用堆栈 print('Exception details:\n $e'); print('Stack trace:\n $s‘’); } catch (e) { print('Unknown type: $e'); rethrow; // 3. 要部分处理异常,同时允许它传播,请使用rethrow关键字 } finally { //4. 为了确保无论是否抛出异常,一些代码都会运行,请使用finally子句 print("finally block"); }
-
assert (断言)
dart语言通过使用assert语句来中断正常的执行流程,assert判断条件是任何可以转化为boolean类型的对象,如果assert的判断为true,则继续执行下面的语句,反之则抛出一个断言错误异常AssertionError。
assert语句只在检测模式下有效,在生产模式下无任何效果。
fun(int x) {
assert(x >= 0);
return x== 0 ? 1 : x* fun(x-1);
}
类似于
fun(int x) {
if (x >= 0) return x== 0 ? 1 : x* fun(x-1);
else throw new AssertionError();
}
函数
Dart是一种真正的面向对象的语言,所以即使是函数也是对象,并且有一个类型Function。这意味着函数可以赋值给变量或作为参数传递给其他函数,这是函数式编程的典型特征
1. main()函数
每个应用程序都必须有一个顶层main()函数,它可以作为应用程序的入口点。该main()函数返回void并具有List<String>参数的可选参数。
2.函数声明
bool isNoble(int atomicNumber) {
return atomicNumber != null;
}
- 对于只包含一个表达式的函数,可以使用简写语法
bool isNoble (int atomicNumber)=> atomicNumber != null;
- Dart函数声明如果没有显式声明返回值类型时会默认当做dynamic处理,注意,函数返回值没有类型推断:
typedef bool CALLBACK();
//不指定返回类型,此时默认为dynamic,不是bool
isNoble(int atomicNumber) {
return atomicNumber != null;
}
void test(CALLBACK cb){
print(cb());
}
// 参数类型“dynamic Function(int)”不能分配给参数类型“bool Function()”。
test(isNoble);
3. 函数作为变量
var say = (str){
print(str);
};
say("hi world");
4. 函数作为参数传递
void execute(var callback) {
callback();
}
execute(() => print("xxx"))
5. 可选的位置参数
包装一组函数参数,用[]标记为可选的位置参数:
String say(String from, String msg, [String device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
下面是一个不带可选参数调用这个函数的例子:
say('Bob', 'Howdy'); //结果是: Bob says Howdy
下面是用第三个参数调用这个函数的例子:
say('Bob', 'Howdy', 'smoke signal'); //结果是:Bob says Howdy with a smoke signal
6.可选的命名参数
定义函数时,使用{param1, param2, …},用于指定命名参数。例如:
//设置[bold]和[hidden]标志
void enableFlags({bool bold, bool hidden}) {
// ...
}
调用函数时,可以使用指定命名参数。例如:paramName: value
enableFlags(bold: true, hidden: false);
可选命名参数在Flutter中使用非常多。
7.闭包
函数可以定义在表达式的内部。它们被称为函数字面量,或者被更笼统地称为闭包。 与函数声明不同,闭包没有名称,虽然如此,与其他函数一样,它们也有参数列表与函数体。(摘取自Dart编程语言一书)
- 闭包是一个方法(对象)
- 闭包定义在其他方法内部
- 闭包能够访问外部方法内的局部变量,并持有其状态(这是闭包最大的作用,可以通过闭包的方式,将其暴露出去,提供给外部访问)
void main() {
// 获取闭包
var func = a();
for (var i = 0; i < 5; i++) {
// 执行闭包
func();
}
print('-' * 40);
var func1 = b();
for (var i = 0; i < 5; i++) {
func1();
}
}
// 声明一个无返回值类型、无参数的函数
a() {
int count = 0;
// 内部声明一个函数 : 闭包
printCount(){
// 内部可以访问外部方法内的局部变量 count
print(count++);
};
// 返回闭包
return printCount;
}
b(){
int count = 10;
// 将闭包返回
return (){
print(--count);
};
}
网友评论