- 原文地址: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、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。