參見: Dart Operators
在dart中提供基本程式語言邏輯的運算元,包含常見的一元、二元運算元、計算運算符、關係運算、與其他運算符符等。其中,我們挑選比較特別的「類型檢查運算符」與「條件表達式(三元運算符)」進行介紹!
參見: Dart Operators: 支援運算符與優先層級
參見: Dart Operators: 支援計算運算符
參見: Dart Operators: 支援關係運算符
Dart提供三種類型檢查運算符讓我們在runtime時檢查變數類型
as
運算符用於進行類型轉換(Type Casting)。在運算為安全的前提下,它允許你將一個對象轉換為特定的類型。若該轉換是不安全的,則會在運行時會拋出異常。
is
運算符用於檢查一個對象是否「屬於」特定的類型,它返回一個boolean值(屬於時回傳true,不屬於則回傳false)。
is!
運算符用於檢查一個對象是否「不屬於」特定的類型,同樣返回一個boolean值(不屬於時回傳true,屬於則回傳false)。
在以下範例中,分別用"as, is, is!"示範了如何達成對變數"employee"的類型轉換與測試,我們可以依據開發的程式段落需求不同而使用相應的不同類型檢查運算符
class Person {
String firstName = '';
}
class Employee extends Person {
// Employee 是 Person 的子類,繼承了 firstName 屬性
// 這個子類還可以有自己的其他屬性和方法
}
void main() {
// 創建一個 Employee 實例
Employee employee = Employee();
// 方法1: 使用 'as' 運算符進行類型轉換(在運行時進行類型檢查)
(employee as Person).firstName = 'Bob'; // 透過類型轉換設置 firstName
// 方法2: 使用 'is' 運算符進行類型檢查(在運行時進行類型檢查)
if (employee is Person) {
employee.firstName = 'Bob'; // 直接設置 firstName,無需類型轉換
}
// 方法3: 使用 'is!' 運算符進行反向類型檢查(在運行時進行類型檢查)
if (employee is! Person) {
// 如果 employee 不是 Person 的實例
// 可以進行相應的處理
print('這個員工不是一個合法的人員'); // 輸出:這個員工不是一個合法的人員
}
// 印出更新後的 firstName
print('員工的名字:${employee.firstName}'); // 輸出:員工的名字:Bob
}
as, is, is!範例
Dart提供兩種運算符可以"簡潔地"表示條件判斷式(等義於if-else效力)
如果 condition 為真,則計算並回傳 expr1 的值;否則,計算並回傳 expr2 的值。拿以下列範例作為說明:
當condition為true則回傳'public'的字串;為false則回傳'private'的字串
void main() {
//-----------condition為true的情況
bool isPublic = true;
var visibility = isPublic ? 'public' : 'private'; //判斷結果為expr1
print('Visibility: $visibility'); // Output: Visibility: public
//-----------condition為false的情況
isPublic = false;
visibility = isPublic ? 'public' : 'private';//判斷結果為expr2
print('Visibility: $visibility');
}
如果 expr1 是非空的,則回傳 expr1 的值;否則計算並回傳 expr2 的值。這個運算符可以用來處理變數「可能為空」的情況。拿以下列範例作為說明:
當name值為"非空"時,便會輸出name,反之則輸出字串'Guest'
String playerName(String? name) => name ?? 'Guest';
void main() {
String player1 = playerName('John'); //name = 'John'
print("player1: " + player1); // 輸出: John
String player2 = playerName(null); //name = null
print("player2: " +player2); // 輸出: Guest
}
在下列程式中我們可以清楚的看到使用三元運算符的條件表達式相較原先if-else的寫法,用更簡潔的方式達到相同效力的功能!
// 使用三元運算符:
String playerName(String? name) => name != null ? name : 'Guest';
// 使用 if-else 語句
String playerName(String? name) {
if (name != null) {
return name;
} else {
return 'Guest';
}
}
Dart提供,“Cascade notation”(串聯表示法)讓我們對同一個物件進行一系列操作。這包括訪問實例成員以及調用該物件的實例方法。使用串聯表示法可以節省創建臨時變數的步驟,方便我們寫出更加流暢的程式碼。以下我們提供兩個範例代表使用前後差距
var paint = Paint();
paint.color = Colors.black;
paint.strokeCap = StrokeCap.round;
paint.strokeWidth = 5.0;
var paint = Paint()
..color = Colors.black
..strokeCap = StrokeCap.round
..strokeWidth = 5.0;
var button = querySelector('#confirm');
button?.text = 'Confirm';
button?.classes.add('important');
button?.onClick.listen((e) => window.alert('Confirmed!'));
button?.scrollIntoView();
querySelector('#confirm') // Get an object.
?..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'))
..scrollIntoView();
參見: Dart: Metadata
在 Dart 中,可以使用元數據(metadata)來給你的程式碼提供額外的信息。元數據通常用於對程式碼進行註解,以提供關於程式碼的一些特殊信息,例如標示某個函數已經被廢棄(deprecated)或者是覆寫了父類的方法(override)等。
通常metadata的註解以 @
字符開頭,後面可以跟著一個指向編譯時期常數的引用(例如 deprecated),或者是調用一個常數構造函數。
以下提供可被所有dart程式代碼使用的三種matadata
本程式中,我們將"activate()"函數用"@Deprecated('Use turnOn instead')"的metadata註記,並且依序呼叫
class Television {
/// metadata表示不再使用activate(),請轉用turnOn()
@Deprecated('Use turnOn instead')
void activate() {
turnOn();
}
/// Turns the TV's power on.
void turnOn() {
print('Television is now turned on.');
}
}
void main() {
var tv = Television();
// 使用 @Deprecated 註解過時的 activate() 方法,編譯器會給出警告
tv.activate();
// 使用 turnOn() 方法來開啟電視
tv.turnOn();
// 使用 @Deprecated 註解過時的 activate() 方法,編譯器會給出警告
// 但實際上仍然會調用 turnOn() 方法來開啟電視
tv.activate();
}
@Deprecated範例
我們也時常透過自行定義 metadata的方式,增強程式的可讀性、維護性和可理解性。除了標記類別、函數、變數等元素,表達有關程式碼的特定信息,如版本號、作者、授權訊息、待辦事項、重要提示之外,也可以讓開發者和工具在開發、測試和維護程式時更容易理解程式碼的邏輯與設計,更能在 IDE 或工具中提供更有用的提示和警告,提高開發效率,並降低出錯的風險。
以下範例提供一個自行定義的metadata:@Todo
,並且在執行到時讀取該metadata所提供的參數訊息。
class Todo {
final String who;
final String what;
const Todo(this.who, this.what);
}
// 自定義 @Todo metadata,在編譯時可獲取所提及的函式參數訊息
@Todo('Dash', 'Implement this function')
void doSomething() {
print('Do something');
}
void main() {
// 呼叫待辦事項函數
doSomething();
}
自行定義metadata範例