變量
聲明變量幾種方式:
1. var name = "Tim"; //自動推倒類型(infer)為string
2. String name = "Tim"; //強類型定義
3. dynamic name = "Tim"; //可以修改變量類型 name = 4.0;
4. final name = "Tim"; //首次使用時執(zhí)行一次
5. const name = "Tim"; //類似全局常量或者static,編譯期間確定值
如果沒有賦初始值,默認變量初始值為null。
內(nèi)置類型
-
Numbers: 編譯期間的數(shù)字類型的常量
- int: 不大于64位,具體取決于平臺
- double: 64位
int 類實現(xiàn)了位移運算符;
支持0x十六進制;
浮點型支持科學計數(shù)法 -
Strings: UTF-16 unicode 編碼
語法跟python類似
- &{express} 可以嵌入變量或者表達式
- ''' ''' 或者 """ """,可以多行顯示
- r'', raw字符串
- In Dart, runes are the UTF-32 code points of a string.
-
Booleans: 同樣是編譯期間常量。
- bool 標識符,true & false
- if (nonbooleanValue) 這樣比較是不行的,必須顯示的比較或者調(diào)用類isEmpty方法。
-
Lists: 數(shù)組
- 如果想要聲明一個編譯期常量的數(shù)組:var constantList = const [1, 2, 3]; //必須指定為const
Maps: 字典 同js
Runes: UTF-32 字符串。比如一些符號,表情等。\uXXXX
Symbols: 不會用到。針對API推斷標識符有用。
函數(shù)
Dart是一個真正的面向?qū)ο缶幊陶Z言,一切都是對象,函數(shù)也是一個對象,它的類型是Function。
跟c語言函數(shù)語法一樣,但是可以省略返回值類型和參數(shù)類型。
也有自己的速寫語法:
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
等價于
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
=> expr 是 { return expr; } 的簡寫。expr只能是一個語句,否則必須用{}方式。
一、參數(shù)
1. 函數(shù)調(diào)用時,可以使用 name:value方式制定參數(shù)。順序可以不是聲明順序。
2. @require 關(guān)鍵字,標示該參數(shù)必須傳入。
3. 可選參數(shù),使用[]擴起來。必須放到參數(shù)的最后位置,且不能存在多個[]的可選位置參數(shù)。
4. 參數(shù)可以設(shè)置默認值,如果沒有設(shè)置默認值,默認為null。
二、.. 操作符,可以看作是鏈式編程的語法。object.func1()..func2()..func3();
三、函數(shù)可以作為參數(shù)傳遞給函數(shù),作用同對象參數(shù)一樣。
四、匿名函數(shù)、lambda表達式、閉包。是一個概念。
五、返回值:所有函數(shù)都有一個返回值,默認返回return null;
運算符
很多操作跟c運算符一致,這里不做過多介紹。下面只介紹特殊運算符:
~/: 除法,返回整數(shù)
as: 類型判斷
is、is!: 類型檢測
..: 嚴格來說,double dot不是操作符,而是Dart的語法。對同一個對象做一系列操作,類似鏈式編程。
??=: 賦值,只有當左值為null的時候,才賦值。
// 只有當b是null的時候,給b賦值value; 否則b保持原值不變
b ??=: value;
??: 條件運算符,簡化if..else語句。expr1 ?? expr2,如果expr1不為null, 返回expr1; 否則返回expr2。
?.: 類似.操作符,獲取成員。問號的作用是標示對象可以是null
控制流
- if..else: 條件必須是boolean類型
- for:
- 傳統(tǒng)for語法
- for-in:可迭代的類或者類型才支持。例如:List, Set等
- While and do-while
- Break and continue
- Switch and case: int和string都可以作為case條件;每個case后必須有break語句;不支持空case;
var command = 'CLOSED';
switch (command) {
case 'CLOSED':
executeClosed();
continue nowClosed;
// Continues executing at the nowClosed label.
nowClosed:
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeNowClosed();
break;
}
- Assert
異常處理
- Throw: 可以拋出非null的任何對象,包括exception和error對象。
- Catch: 語法如下:
on可以捕獲具體類型的exception;catch 可以跟on一起,也可以單獨使用。最多包含兩個參數(shù),e是拋出的異常,s是堆棧信息。
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');
print('Stack trace:\n $s');
}
- rethrow: 再次拋出異常
void misbehave() {
try {
dynamic foo = true;
print(foo++); // Runtime error
} catch (e) {
print('misbehave() partially handled ${e.runtimeType}.');
rethrow; // Allow callers to see the exception.
}
}
void main() {
try {
misbehave();
} catch (e) {
print('main() finished handling ${e.runtimeType}.');
}
}
- Finally: 捕獲異常后后會繼續(xù)執(zhí)行finally中的內(nèi)容。
try {
breedMoreLlamas();
} catch (e) {
print('Error: $e'); // Handle the exception first.
} finally {
cleanLlamaStalls(); // Then clean up.
}
類
- 使用類成員: 使用.運算符引用對象成員和方法。
// If p is non-null, set its y value to 4.
p?.y = 4;
- 使用構(gòu)造函數(shù): Dart 2中new操作符可選。構(gòu)造函數(shù)可以是類名,也可以是類名.標識符。
var p1 = Point(2, 2);
var p2 = Point.fromJson({'x': 1, 'y': 2});
獲取對象類型:使用runtimeType屬性。(Object對象定義,獲取運行時對象類型)
成員變量
沒有public、private、protected關(guān)鍵字。
不需要設(shè)置成員變量默認值,不初始化的變量默認null。
默認會對成員變量生成隱式的get和set方法。構(gòu)造函數(shù)
構(gòu)造函數(shù)可以是跟類名一樣的名字,也可以聲明其他名字。
class Point {
num x, y;
Point(num x, num y) {
// Use this only when there is a name conflict
this.x = x;
this.y = y;
}
// Syntactic sugar for setting x and y
// before the constructor body runs.
// Point(this.x, this.y); 等同于上面的構(gòu)造函數(shù),寫法更簡單
// Named constructor:使用:Point p = Point.origin();
Point.origin() {
x = 0;
y = 0;
}
}
如果不寫構(gòu)造函數(shù),會默認生成一個構(gòu)造函數(shù);默認生成的構(gòu)造函數(shù)跟類同名,沒有參數(shù)。
構(gòu)造函數(shù)不能繼承。默認子類會調(diào)用基類的默認構(gòu)造函數(shù)或者無參數(shù)構(gòu)造函數(shù)。
跟C++一樣,Dart也有初始化列表(initializer list)。初始化列表要寫在調(diào)用基類構(gòu)造函數(shù)之前。
// Initializer list sets instance variables before
// the constructor body runs.
Point.fromJson(Map<String, num> json)
: x = json['x'],
y = json['y'] {
print('In Point.fromJson(): ($x, $y)');
}
重定向構(gòu)造函數(shù):重定向構(gòu)造函數(shù)的函數(shù)體必須為空,通過冒號在后面定向到其他構(gòu)造函數(shù).
class Point {
num x, y;
// The main constructor for this class.
Point(this.x, this.y);
// Delegates to the main constructor.
Point.alongXAxis(num x) : this(x, 0);
}
常量構(gòu)造函數(shù):可以創(chuàng)建一個編譯時的常量對象,對象構(gòu)造函數(shù)參數(shù)必須時常量。用于創(chuàng)建一個不變的對象(內(nèi)部成員不會改變)
class ImmutablePoint {
static final ImmutablePoint origin =
const ImmutablePoint(0, 0);
final num x, y;
const ImmutablePoint(this.x, this.y);
}
工廠構(gòu)造函數(shù):不能直接使用this??梢詮腸ache獲取實例,也可能創(chuàng)建子類型的對象。
class Logger {
final String name;
bool mute = false;
// _cache is library-private, thanks to
// the _ in front of its name.
static final Map<String, Logger> _cache =
<String, Logger>{};
//工廠構(gòu)造函數(shù)
factory Logger(String name) {
if (_cache.containsKey(name)) {
return _cache[name];
} else {
final logger = Logger._internal(name);
_cache[name] = logger;
return logger;
}
}
Logger._internal(this.name);
void log(String msg) {
if (!mute) print(msg);
}
}
- 成員函數(shù)
getter和setter方法,是默認生成用于存取成員變量的成員函數(shù)。也可以顯式聲明(使用get和set關(guān)鍵字)
class Rectangle {
num left, top, width, height;
Rectangle(this.left, this.top, this.width, this.height);
// Define two calculated properties: right and bottom.
num get right => left + width;
set right(num value) => left = value - width;
num get bottom => top + height;
set bottom(num value) => top = value - height;
}
抽象方法:類似C++中的虛基類中的虛函數(shù),基類中沒有實現(xiàn),子類實現(xiàn)。
抽象類:
跟C++不同的是,可以通過工廠構(gòu)造函數(shù)(factory constructor)創(chuàng)建實例。隱含接口(Implicit interfaces):使用implements關(guān)鍵字,可以實現(xiàn)類的方法,可以實現(xiàn)多重繼承。
// A person. The implicit interface contains greet().
class Person {
// In the interface, but visible only in this library.
final _name;
// Not in the interface, since this is a constructor.
Person(this._name);
// In the interface.
String greet(String who) => 'Hello, $who. I am $_name.';
}
// An implementation of the Person interface.
class Impostor implements Person {
get _name => '';
String greet(String who) => 'Hi $who. Do you know who I am?';
}
String greetBob(Person person) => person.greet('Bob');
void main() {
print(greetBob(Person('Kathy')));
print(greetBob(Impostor()));
}
class Point implements Comparable, Location {...}
-
擴展一個類
關(guān)鍵字extends創(chuàng)建子類,使用super指向其基類。
@override 關(guān)鍵字用來覆蓋基類的實現(xiàn)。
covariant 關(guān)鍵字:表示收緊子類型class Animal { void chase(Animal x) { ... } } class Mouse extends Animal { ... } class Cat extends Animal { //只能傳Mouse和其子類 void chase(covariant Mouse x) { ... } }不能訪問一個不存在的成員函數(shù),但是可以通過覆蓋noSuchMethod()方法,使代碼不拋出異常。
-
枚舉類型:可以表示固定的常數(shù)的一種特殊的類。默認值index從0開始。
enum Color { red, green, blue } //使用enum關(guān)鍵字定義枚舉 assert(Color.red.index == 0); assert(Color.green.index == 1); assert(Color.blue.index == 2);枚舉類型使用的限制:
- 不能繼承,混合和實現(xiàn)一個枚舉。
- 不能顯式的實現(xiàn)一個枚舉類。
-
向類中添加特性:使用mixins技術(shù)(類似多重繼承)
關(guān)鍵字withclass T = A with S;
那我們得到的class T是怎么樣的呢?假設(shè)MA表示A中的所有方法,MS表示S中的所有方法,那么T中的方法集合為:MS U (MA - MS)。復(fù)雜一點的情況:
class T = B with A, S;==class T = (B with A) with S; 類成員和方法:同樣使用
static關(guān)鍵字。
泛型
可以在運行時判斷泛型類型內(nèi)容的具體type。其他方面跟java或者c++差不多。
庫和可見性
- 使用import導(dǎo)入要使用的庫。
- 如果導(dǎo)入的多個庫中,有同名類或者函數(shù),可以通過別名區(qū)分。關(guān)鍵字as。類似c++中的namespace。
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// Uses Element from lib1.
Element element1 = Element();
// Uses Element from lib2.
lib2.Element element2 = lib2.Element();
- 也可以僅僅導(dǎo)入庫中的部分內(nèi)容
show和hide關(guān)鍵字
// Import only foo.
import 'package:lib1/lib1.dart' show foo;
// Import all names EXCEPT foo.
import 'package:lib2/lib2.dart' hide foo;
- 懶加載庫
deferred as關(guān)鍵字
import 'package:greetings/hello.dart' deferred as hello;
Future greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
- 如何實現(xiàn)庫。單獨章節(jié)進行講解。
異步支持
關(guān)鍵字async和await支持異步編程。
生成器
參考python中的生成器。
需要后續(xù)加強了解
可調(diào)用的類
Dart 語言中為了能夠讓類像函數(shù)一樣能夠被調(diào)用,可以實現(xiàn)call()方法。
具體使用的場景,需要調(diào)研
隔離
沙盒?
Typedefs
Dart中,函數(shù)也是對象。Function關(guān)鍵字,typedefs 可以給函數(shù)設(shè)置別名。
元數(shù)據(jù)
A metadata annotation begins with the character @, followed by either a reference to a compile-time constant (such as deprecated) or a call to a constant constructor.
Two annotations are available to all Dart code: @deprecated and @override.
注釋
- 單行
// - 多行
/* */ - 文檔注釋
///或者/**