Dart語法要點彙總
[In]
// main為Dart程式入口 void main() { // 呼叫printNumber方法 var number = 58; printNumber(number); } // 方法返回型別預設時,預設返回型別為dynamic printNumber(int number) { // 1. 字串用單/雙引號均可 // 2. 字串中支援${}表示式, 單字元變數時可簡化為$ print("The number is $number."); }
[Out]
The number is 58.
-
Dart單行註釋用
//
,多行註釋用/**/
(同Java) -
var
是一種不需要指定型別的宣告方式 -
int
是一種資料型別,對應的還有String
、List
和bool
型別 - 字串的標識用單、雙引號均可(同Python、JS)
-
字串中支援
${number}
表示式, 單字元變數時可簡化為$number
(同JS的`${number}`)
當你在學習Dart語言時,你需要清楚這概念:
-
所有的東西都是一個物件,每個物件都是一個class的例項,即使是數字、函式、
null
都是物件,並且所有的物件都整合自Object類。 -
儘管Dart語言是一種強型別語言,但你在型別宣告時仍然可以不指定型別,因為Dart可以自動進行型別推斷。在上面的程式碼中,
number
變數的型別就被推斷為int
,當你並不想顯式地宣告型別時,你可以使用置頂的型別ofollow,noindex">dynamic 來標識。 -
Dart語言同樣支援泛型,如
List<int>
、List<dynamic>
(同Java)。 -
Dart語言支援頂級方法(即不與類繫結的方法,如上的
main
方法),以及繫結類和例項的方法(分別對應靜態方法和例項方法),而且還支援方法巢狀(同Python、JS)。 -
和Java不同的是,Dart語言並不支援
publish
、protected
、private
這些關鍵字,它是通過字首_
來標識為私有域的(同Python),參 。
變數
這是一個建立並初始化變數的例子
var name = 'Bob';
name
變數型別被推斷為String
,你也能更改為制定的型別。如果一個變數的型別並不限制於單一型別,你也可以使用dynamic
或Object
進行宣告,如:
dynamic name = 'Bob';
同樣也可以選擇制定的宣告方式
String name = 'Bob';
但根據Dart推薦的編碼風格,在區域性變數中使用var
要更優於制定的型別宣告。
預設值
Dart中宣告時如果未初始化,會被自動初始化為null
int lineCount; assert(lineCount == null);
注:assert
只在開發環境有效,在實際的生產環境無效
final與const
final
和const
標識該變數只能被賦值一次,區別在於final
是執行時賦值,const
是編譯時賦值。
final String nickname = 'Jack'; // final修飾時, 可省略型別宣告 final name = 'Jack';
const
不僅可以用來宣告變數,還能用來建立常量值,如:
// 此時不能在對列表a進行更新操作 var a = const [1, 2];
內建型別
數字型
包含int
和double
,不包含
float
常用的型別轉換
// String -> int var a = int.parse('1'); assert(a == 1); // String -> double var b = double.parse('1.1'); assert(b == 1.1); // int -> String String c = 1.toString(); assert(c == '1'); // double -> String String d = 3.14159.toStringAsFixed(2); assert(d == '3.14');
字串
-
單引號、雙引號均可
-
字串拼接時,換行可省略加號,如
var a = '123' '456'; print(a); // Out: 123456
-
字串可以用索引,但不支援負值索引(區分於Python),如
var a = 'Jack'; print(a[1]); // Out: a
列表
在Dart語言中,陣列即列表
[In]
void main() { // 初始化 var list = ['a', 'b', 'c']; // 增 list.add('d'); // 刪 list.remove('b'); // 改 list[1] = 'cc'; // 查 var last = list[list.length - 1]; print('list is $list'); print('last is $last'); }
[Out]
list is [a, cc, d] last is d
字典
[In]
void main() { var map = {'a': 1, 'b': 2}; // 增 map['c'] = 3; // 刪 map.remove('a'); // 改 map['b'] = 22; // 查 var cValue = map['c']; print('map is $map'); print('cValue is $cValue'); }
[Out]
map is {b: 22, c: 3} cValue is 3
函式
Dart是一門完全面向物件的語言,即使它的函式也是一個物件,並且有自己的型別——Function
。這就意味著函式可以被賦值為一個變數,或者作為一個引數在其他函式之間傳遞。
對於只包含一個表示式的方法體,你也可以使用=>
的簡寫形式,如:
void say() { print('123'); } // 該寫法與以上有同樣效果 void say2() => print('123');
可選引數
Dart的可選引數分為命名可選引數
和位置可選引數
兩種(兩者之間互斥,即不能同時使用)。
命名可選引數
[In]
void main() { say(age: 27); } void say({String name='Jack', int age=20}) { print('$name\'s age is $age.'); }
[Out]
Jack's age is 27.
位置可選引數
[In]
void main() { say('Tom', 27, 'Love game.'); } void say(String name, int age, [String remark]) { print('$name\'s age is $age.${remark??''}'); }
[Out]
Tom's age is 27.Love game.
預設引數值
引數可用=
宣告預設值,預設值只能是編譯時常量。
注:命名可選引數
的預設引數值可使用:
指定,但對於位置可選引數
不支援,推薦統一使用=
的預設引數指定方式
匿名函式
[In]
[Out]
Android iOS WindowPhone
特殊操作符
-
is
<=> Java的instanceof
-
a?.b
<=>a == null ? null : a.b
-
a??b
<=>a == null ? b : a
-
a ??= b
<=>a = a == null ? b : a
-
a as String
<=> Java的(String) a
-
..
級別操作符var button = querySelector('#confirm'); button.text = 'Confirm'; button.classes.add('important'); button.onClick.listen((e) => window.alert('Confirmed!')); // 該寫法等價上述寫法 querySelector('#confirm') // Get an object. ..text = 'Confirm' // Use its members. ..classes.add('important') ..onClick.listen((e) => window.alert('Confirmed!'));
異常
// 拋異常 throw FormatException('Expected at least 1 section'); throw 'Out of llamas!'; // 捕獲異常 try { breedMoreLlamas(); } on OutOfLlamasException { // A specific exception buyMoreLlamas(); } on Exception catch (e) { // Anything else that is an exception print('Unknown exception: $e'); } catch (e) { // No specified type, handles all print('Something really unknown: $e'); } try { // ··· } on Exception catch (e) { print('Exception details:\n $e'); } catch (e, s) { print('Exception details:\n $e'); // 第二個引數s是一個錯誤堆疊例項 print('Stack trace:\n $s'); } try { dynamic foo = true; print(foo++); // Runtime error } catch (e) { print('misbehave() partially handled ${e.runtimeType}.'); // 關鍵字rethrow重新丟擲異常 rethrow; // Allow callers to see the exception. }
過載操作符
class Vector { final int x, y; Vector(this.x, this.y); Vector operator +(Vector v) => Vector(x + v.x, y + v.y); Vector operator -(Vector v) => Vector(x - v.x, y - v.y); // Operator == and hashCode not shown. For details, see note below. // ··· } void main() { final v = Vector(2, 3); final w = Vector(2, 2); assert(v + w == Vector(4, 5)); assert(v - w == Vector(0, 1)); }
生成器
-
sync* + yield
返回Iterable
物件 -
async* + yield
返回Stream
物件
Iterable<int> naturalsTo(int n) sync* { int k = 0; while (k < n) yield k++; } Stream<int> asynchronousNaturalsTo(int n) async* { int k = 0; while (k < n) yield k++; }
如果生成器返回值是可迭代的,亦可使用yield*
來提高效能,如:
Iterable<int> naturalsDownFrom(int n) sync* { if (n > 0) { yield n; yield* naturalsDownFrom(n - 1); } }
可呼叫的類
給類定義call
方法能使得當前類是Callable的(同Python)
class WannabeFunction { call(String a, String b, String c) => '$a $b $c!'; } main() { var wf = new WannabeFunction(); var out = wf("Hi","there,","gang"); print('$out'); }