直接開始幹,沒有爲何~html
首先來個很重要的註釋,代碼沒有註釋,命名又不規範,那將極度糟糕。Dart 分單行、多行、文檔註釋三種。express
//我是單行註釋
複製代碼
/*
多行註釋
多行註釋
多行註釋
*/
複製代碼
在一段文檔註釋中,Dart 編譯器忽略全部除括號內的文本。你可使用括號來引用類、方法、屬性、頂級變量、函數和參數。括號中的名字會在被文檔化程序元素的詞法範圍內解析。json
/// A domesticated South American camelid (Lama glama).
///
/// Andean cultures have used llamas as meat and pack
/// animals since pre-Hispanic times.
class Llama {
String name;
/// Feeds your llama [Food].
///
/// The typical llama eats one bale of hay per week.
void feed(Food food) {
// ...
}
/// Exercises your llama with an [activity] for
/// [timeLimit] minutes.
void exercise(Activity activity, int timeLimit) {
// ...
}
}
複製代碼
var name = 'jk'; //定義了字符串 name 賦予初值 jk
int _age = 25; //定義了整數 age 賦予初值 25
int sex; //定義了整數 sex 默認初值 null
複製代碼
敲黑板api
const String name = 'jk'; // 聲明字符串常量 name 賦予初值 jk
final String api = 'www.baidu.com'; 聲明字符串常量 api 賦予初值 www.baidu.com
static const port = '8080'; // 聲明字符串靜態常量 port 賦予初值 8080
複製代碼
敲黑板數組
Dart 僅有2種數字類型bash
在Dart中,數組是List對象,所以它們都稱爲列表。markdown
// 如下都能定義一個列表
var list = [];
List list = List();
// 靜態常量列表
var constantList = const [1, 2, 3];
// constantList[1] = 1; // 取消註釋將會報錯
複製代碼
敲黑板dom
a. Dart 2.3 增長操做符 ... 和 ...? ,提供一種將多個元素插入 List 的簡便方法異步
//經過 ... 把 list 中全部元素 add 到 list2
var list = [1, 2, 3];
var list2 = [0, ...list];
assert(list2.length == 4);
//若是 list 可能爲 null ,則經過 ...? 把 list 中全部元素 add 到 list2
var list;
var list2 = [0, ...?list];
assert(list2.length == 1);
複製代碼
b. Dart 2.3 還可使用 if 和 for 來構建列表async
// 使用 if 建立3個或4個元素的列表
var nav = [
'Home',
'Furniture',
'Plants',
if (promoActive) 'Outlet'
];
// 使用 for 來建立列表
var listOfInts = [1, 2, 3];
var listOfStrings = [
'#0',
for (var i in listOfInts) '#$i'
];
assert(listOfStrings[1] == '#1');
複製代碼
Dart中的 Set 存放的是一組無序的惟一的元素,在Dart2.2 Set 引入 literals
// 定了一個 Set,推斷爲 Set<String>,若是添加其餘類型將報錯
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
// 建立空 Set
var names = <String>{}; // Set<String>
// Set<String> names = {}; // Set<String>
// var names = {}; // Map<dynamic, dynamic>
複製代碼
敲黑板
Dart 2.3 增長操做符 ... 和 ...? ,提供一種將多個元素插入 Set 的簡便方法
// 如下都能定義一個圖
var maps = {
// 鍵 值
'a' : '123456'
};
Map maps = Map();
maps[a] = '123456';
複製代碼
敲黑板
Dart 2.3 增長操做符 ... 和 ...? ,提供一種將多個元素插入 Map 的簡便方法
感受不多用 就不看了...
// 聲明返回類型 bool
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
// 能夠不聲明類型
isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
// 僅有一個表達式能夠這樣寫
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
複製代碼
每一個應用程序都必須具備頂級main()函數,該函數用做應用程序的入口點。 main()函數返回void,併爲參數提供可選的List 參數。
void main() {
querySelector('#sample_text_id')
..text = 'Click me!'
..onClick.listen(reverseText);
}
複製代碼
敲黑板 代碼中的..語法稱爲級聯。使用級聯,能夠對單個對象的成員執行多個操做。
函數可選參數能夠是可選命名參數,也能夠是可選位置參數,但不能2者都有
// 函數的時候,使用{param1, param2, ...}來聲明有命名的參數
// 定義
enableFlags({bool bold, bool hidden}) {
// ...
}
// 調用
enableFlags(hidden : true);
// 命名參數雖然是可選的,咱們依然能夠經過 @required 註解要求必傳
const Scrollbar({Key key, @required Widget child})
複製代碼
// 把函數的參數放在[]以內,能夠把它們標記爲可選位置參數
// 定義
String say(String from, String msg, [String device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
// 調用
say('Bob', 'Howdy', 'smoke signal');
複製代碼
敲黑板
Dart 中擁有其餘語言常見操做符。
這裏說幾個不同的:
可使用如下任何一種方式來控制你的Dart代碼流:
dart 使用經典的try-catch處理異常,使用關鍵字throw拋出一個異常
// 拋異常
throw new IntegerDivisionByZeroException("分母不能爲0");
// 也能夠拋出任意對象
throw 'Out of llamas!';
//處理異常
try {
divide(10, 0);
} on IntegerDivisionByZeroException {
// 具體類型用 on
} catch (e) {
// 非具體類型或要使用異常對象
} finally {
//...
}
複製代碼
Dart 是一種面嚮對象語言,包含類和基於 mixin 的繼承兩部分。每一個對象是一個類的實例,而且 Object 是全部類的父類。基於 mixin 的繼承指的是每一個類(除了 Object )都只有一個父類,類體還能夠在多個類繼承中被重用。
若是類沒有聲明構造函數,將默認無參構造函數。子類不會繼承父類構造函數,若子類沒有聲明構造函數,將也僅默認無參構造函數
class Person {
String name;
int age;
//默認構造方法,賦值給name和tag
Person(this.name, this.age);
//命名構造函數,返回一個空的Person
Person.empty();
//命名構造函數,返回設置了name的Person
Person.forName(this.name);
}
// 常量構造函數 全部實例變量須要時 final
// 常量構造函數產生的對象永遠不會改變
class ImmutablePoint {
static final ImmutablePoint origin =
const ImmutablePoint(0, 0);
final num x, y;
const ImmutablePoint(this.x, this.y);
}
// 工廠構造函數
class Logger {
final String name;
bool mute = false;
// _cache 是個私有的 Map,僅僅由於標註了 _
static final Map<String, Logger> _cache =
<String, Logger>{};
factory Logger(String name) {
return _cache.putIfAbsent(
name, () => Logger._internal(name));
}
Logger._internal(this.name);
void log(String msg) {
if (!mute) print(msg);
}
}
複製代碼
class Person {
String firstName;
Person.fromJson(Map data) {
print('in Person');
}
}
class Employee extends Person {
// Person 沒有默認無參構造函數;
// 必須調用 super.fromJson(data).
Employee.fromJson(Map data) : super.fromJson(data) {
print('in Employee');
}
}
複製代碼
class Point {
num x;
num y;
Point(this.x, this.y);
// 初始化列表在構造函數運行前設置實例變量。
Point.fromJson(Map jsonMap)
: x = jsonMap['x'],
y = jsonMap['y'] {
print('In Point.fromJson(): ($x, $y)');
}
}
複製代碼
全部實例變量都生成一個隱式getter方法。非 final 實例變量也會生成隱式setter方法。
class Point {
num x; // 定義實例變量x 初始化值 null
num y; // 定義實例變量y 初始化值 null
num z = 0; // 定義實例變量z 初始化值 0
// 自定義get set
num get x => y + z;
set x(num value) => x = value;
}
複製代碼
每一個類都隱式定義一個接口,該接口包含該類的全部實例成員及其實現的任何接口。若是要在不繼承B實現的狀況下建立支持B類API的A類,則A類應實現B接口。
// 一個 person ,包含 greet() 的隱式接口。
class Person {
// 在這個接口中
final _name;
// 不在接口中,由於這是個構造函數。
Person(this._name);
// 在這個接口中。
String greet(who) => 'Hello, $who. I am $_name.';
}
// Person 接口的一個實現。
class Imposter implements Person {
// 咱們不得不定義它,但不用它。
final _name = "";
String greet(who) => 'Hi $who. Do you know who I am?';
}
複製代碼
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);
}
void main() {
final v = Vector(2, 3);
final w = Vector(2, 2);
assert(v + w == Vector(4, 5));
assert(v - w == Vector(0, 1));
}
複製代碼
這個很nice,做用是在代碼嘗試使用不存在的方法或實例變量時檢測或作出反應,您能夠覆蓋noSuchMethod()
class A {
// 複寫這個方法,使用不存在的成員將不會收到NoSuchMethodError
@override
void noSuchMethod(Invocation invocation) {
print('You tried to use a non-existent member: ' +
'${invocation.memberName}');
}
}
複製代碼
在枚舉中每一個值都有一個 index getter 方法,它返回一個在枚舉聲明中從 0 開始的位置。
enum Color {
red,
green,
blue
}
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);
//要獲取枚舉中全部值的列表
List<Color> colors = Color.values;
assert(colors[2] == Color.blue);
複製代碼
Dart 2.1中引入了對mixin關鍵字的支持,早期版本中的代碼一般使用抽象類。
Mixins是一種在多個類層次結構中重用類代碼的方法。使用mixin,則使用with關鍵字後跟一個或多個mixin名稱。
class Musician extends Performer with Musical {
// ···
}
class Maestro extends Person with Musical, Aggressive, Demented {
Maestro(String maestroName) {
name = maestroName;
canConduct = true;
}
}
複製代碼
要實現mixin,請建立一個擴展Object的類,而且不聲明構造函數。除非您但願mixin可用做常規類,不然請使用mixin關鍵字而不是class。例如:
mixin Musical {
bool canPlayPiano = false;
bool canCompose = false;
bool canConduct = false;
void entertainMe() {
if (canPlayPiano) {
print('Playing piano');
} else if (canConduct) {
print('Waving hands');
} else {
print('Humming to self');
}
}
}
複製代碼
要指定只有某些類型可使用mixin - 例如,可使用on來指定所需的超類,使你的mixin能夠調用它沒有定義的方法:
mixin MusicalPerformer on Musician {
// ···
}
複製代碼
當你須要使用 Future 的結果時,你有兩個選擇。
使用async和await的代碼是異步的,但它看起來很像同步代碼。要使用await,代碼必須位於異步函數中,標記爲async的函數。如:
Future checkVersion() async {
var version = await lookUpVersion();
// Do something with version
}
複製代碼
在await表達式中,表達式的值一般是Future;若是不是,那麼該值將自動包裝在Future中。await表達式使執行暫停,直到該對象可用。
使用try,catch,最後在使用await的代碼中處理錯誤和清理:
try {
version = await lookUpVersion();
} catch (e) {
// React to inability to look up the version
}
複製代碼
定義異步函數,使用 async 包裹函數體
Future<String> lookUpVersion() async => '1.0.0';
Future<String> lookUpVersion() async {
//...
}
複製代碼
當您須要從Stream獲取值時,您有兩個選擇:
await for (varOrType identifier in expression) {
// Executes each time the stream emits a value.
}
複製代碼
表達式 的值必須有Stream 類型(流類型)。執行過程以下:
若是要中止監聽 stream ,你可使用 break 或者 return 語句,跳出循環並取消來自 stream 的訂閱 。
可見性經過 _ 控制,前面已經說過了
導入的惟一必需參數是指定庫的URI。
//對於內置庫
import 'dart:html';
//對於其餘庫,你可使用文件系統路徑或package:scheme
import 'dart:io';
import 'package:test/test.dart';
複製代碼
若是導入兩個具備衝突標識符的庫,則能夠爲一個或兩個庫指定前綴。
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// 使用lib1裏的元素
var element1 = Element();
// 使用lib2裏的元素
var element2 = lib2.Element();
複製代碼
若是隻想使用庫的一部分,則能夠有選擇地導入庫。
// 僅導入 foo.
import 'package:lib1/lib1.dart' show foo;
// 導入全部 除了 foo.
import 'package:lib2/lib2.dart' hide foo;
複製代碼
只有dart2js支持延遲加載。Flutter,Dart VM和dartdevc不支持延遲加載。 因此不看了