- 原文地址:Dart Features for Better Code: Types and working with parameters
- 原文做者:Andrea Bizzotto
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:EmilyQiRabbit
- 校对者:ArcherGrey
本篇教程将会介绍 Dart 语言的一些基础特性,以及如何将其应用于代码中。前端
正确的使用这些特性,可以让你的代码更加整洁、轻量,而且健壮。android
Dart 编译器可以在变量初始化的时候自动推断它的类型,因此咱们也就没必要声明变量的类型。ios
在代码应用中,也就是咱们能够将这样的代码:git
String name = 'Andrea';
int age = 35;
double height = 1.84;
复制代码
转化为:程序员
var name = 'Andrea';
var age = 35;
var height = 1.84;
复制代码
这段代码之因此能生效,是由于 Dart 能够从表达式右边的值推断出变量的类型。github
咱们能够像这样声明变量:编程
var x;
x = 15;
x = 'hello';
复制代码
在这个例子中,x
声明在前,初始化在后。后端
此时它的类型是动态的,即 dynamic
,这意味着,它能够被多个表达式赋值为不一样的类型。安全
小结less
var
的时候,只要变量的声明和初始化是同时完成的,那么 Dart 将能正确的推断出变量类型。当咱们使用 var 来声明变量的时候,这个变量能够被屡次赋值:
var name = 'Andrea';
name = 'Bob';
复制代码
也就是说:
使用
var
意味着能够屡次赋值
可是若是咱们使用了 final
,就不能给变量屡次赋值了:
final name = 'Andrea';
name = 'Bob'; // 'name' 是一个 final 类型的变量,不能够被再次赋值
复制代码
在 widget 类中,很常见使用 final
声明的属性。例如:
class PlaceholderContent extends StatelessWidget {
const PlaceholderContent({
this.title,
this.message,
});
final String title;
final String message;
// TODO:实现构建方法
}
复制代码
在这段代码中,title
和 message
在这个 widget 内是不能够被修改的,由于:
使用
final
意味着只能一次赋值
因此,使用 var
和 final
的区别就是是否容许屡次或只能一次赋值。如今咱们再来看看 const
:
const
可以定义编译时常量
const
用来定义硬编码值,例如颜色、字体大小和图标等。
同时咱们也能够在定义 widget 类的时候使用 const 构建函数。
这是彻底可行的,由于全部 widget 内部的变量和方法都是编译时常量。例如:
class PlaceholderContent extends StatelessWidget {
const PlaceholderContent({
this.title,
this.message,
});
final String title;
final String message;
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
title,
style: TextStyle(fontSize: 32.0, color: Colors.black54),
),
Text(
message,
style: TextStyle(fontSize: 16.0, color: Colors.black54),
),
],
),
);
}
}
复制代码
若是这个 widget 的构建函数是 const
类型,它就能够被这样构建:
const PlaceholderContent(
title: 'Nothing here',
message: 'Add a new item to get started',
)
复制代码
结果就是,这个 widget 能够被 Flutter 优化为,当它的父级变化时,widget 自己不会重复构建。
小结:
final
意味着变量只能被赋值一次const
用来定义编译时常量const
而不是 final
在 Dart 中,咱们将变量使用大括号({}
)包起来,由此能够定义命名参数:
class PlaceholderContent extends StatelessWidget {
// 使用命名参数的构建函数
const PlaceholderContent({
this.title,
this.message,
});
final String title;
final String message;
// TODO:实现构建方法
}
复制代码
这段代码意味着,咱们能够像这样建立 widget:
PlaceholderContent(
title: 'Nothing here',
message: 'Add a new item to get started',
)
复制代码
还有一种替代方案是,咱们能够在构建函数中将大括号省略,声明位置参数:
// 使用位置参数的构建函数
const PlaceholderContent(
this.title,
this.message,
);
复制代码
结果就是,参数能够经过它们所在的位置来定义:
PlaceholderContent(
'Nothing here', // title 参数位于 0 号位
'Add a new item to get started', // message 参数位于 1 号位
)
复制代码
这彻底行得通,可是当咱们有多个参数的时候,这样很容易引发混乱。
此时命名参数就展露优点了,它们让代码更易写也更易读。
顺便说一句,你还能够将位置参数和命名参数结合起来:
// 位置参数优先,而后是命名参数
void _showAlert(BuildContext context, {String title, String content}) {
// TODO:展现提示信息
}
复制代码
Flutter widget 中随处可见使用一个位置参数,而后使用多个命名参数的方式。Text
widget 就是一个很好的例子。
我写代码的指导思想就是,代码必定要保持整洁、自洽。我会依照此合理选择命名参数和位置参数。
默认状况下,命名参数能够被省略。
省略命名参数就等于给它赋值为
null
。
有时候这会致使没法预期的后果。
在上面的例子中,咱们能够在定义 PlaceholderContent()
时并不传入 title
和 message
参数。
这将会致使错误,由于这样的话咱们会将 null
值传入 Text
widget,但这是不容许的。
咱们能够为任何变量添加 required 注释:
const PlaceholderContent({
@required this.title,
@required this.message,
});
复制代码
这样当咱们忘记传入参数的时候,编译器将会报出警告。
此时若是咱们须要,咱们仍旧能够明确写出传递 null
值:
PlaceholderContent(
title: null,
message: null,
)
复制代码
此时编译器就不会报警告了。
若是想要避免传入 null
值,咱们能够增长一些断言(assert):
const PlaceholderContent({
@required this.title,
@required this.message,
}) : assert(title != null && message != null);
复制代码
这些修改让咱们的代码安全系数更高,由于:
@required
会增长编译时检查assert
会增长运行时检查若是咱们为代码加入断言,那么运行时的错误就更容易改正,由于此时的报错会明确指出致使错误的代码位置。
@required
和 assert
让咱们的代码安全系数更高了,可是它们看上去有些笨重。
若是咱们能够指定对象在编译时不可为空就更好了。
经过使用非空类型咱们能够作到这一点,而它在一开始就内建在 Swift 和 Kotlin 中了。
并且非空类型如今也正计划应用于 Dart 语言。
让咱们祈祷它能够快点到来吧。🤞
有时候,指定合理的默认值也颇有用。
在 Dart 中这很容易就能作到:
const PlaceholderContent({
this.title = 'Nothing here',
this.message = 'Add a new item to get started',
}) : assert(title != null && message != null);
复制代码
使用这种语法,若是 title
和 message
参数被忽略了,那么默认值就会被使用。
顺便提一下,默认值也能够应用于位置参数:
int sum([int a = 0, int b = 0]) {
return a + b;
}
print(sum(10)); // 打印出 10
复制代码
代码是让机器执行的,可是也是要程序员阅读的。
时间宝贵。乖乖的写好代码 😉
编程愉快!
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。