安裝 Dart
windows
C:> choco install dart-sdk # Windows
linux
執行以下一次性設置
$ sudo apt-get update
$ sudo apt-get install apt-transport-https
$ wget -qO- https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo gpg --dearmor -o /usr/share/keyrings/dart.gpg
$ echo 'deb [signed-by=/usr/share/keyrings/dart.gpg arch=amd64] https://storage.googleapis.com/download.dartlang.org/linux/debian stable main' | sudo tee /etc/apt/sources.list.d/dart_stable.list
安裝 Dart SDK
$ sudo apt-get update
$ sudo apt-get install dart
mac
$ brew tap dart-lang/dart
$ brew install dart
hello.dart
// 應用執行開始的頂級函數
void main() {
print("Hello World!"); // 打印到控制臺
}
每個應用程序都有一個 main() 函數
Windows
$ dart compile exe hellow.dart
$ time ./hello.exe
Hello World!
變量
int x = 2; // 顯式鍵入
var p = 5; // 類型推斷 - 具有類型推斷的通用var
dynamic z = 8; // 變量可以采用任何類型
z = "cool"; // cool
// 如果您從不打算更改變量,請使用 final 或 const
// 像這樣的東西:
final email = "temid@gmail.com";
// 與 var 相同,但不能重新分配
final String email = "temid@gmail.com";
// 你不能改變價值
const qty = 5; // 編譯時常數
數據類型
// 整數,范圍 -2^63 到 2^63 - 1
int age = 20;
// 浮點數字
double height = 1.85;
// 您還可以將變量聲明為 num
// x 可以同時具有 int 和 double 值
num x = 1;
num += 2.5;
print(num); // 打印: 3.5
String name = "Nicola";
bool isFavourite = true;
bool isLoaded = false;
注釋
// 這是一條正常的單行注釋
/// 這是一個文檔注釋,用于文檔庫,
/// 類及其成員。 IDE 和 dartdoc 等工具
/// doc 特別注釋。
/* 也支持此類注釋 */
字符串插值
// 可以對字符串類型使用單引號或雙引號
var firstName = 'Nicola';
var lastName = "Tesla";
// 可以用 $ 將變量嵌入到字符串中
String fullName = "$firstName $lastName";
// 與 + 連接
var name = "Albert " + "Einstein";
String upperCase = '${firstName.toUpperCase()}';
print(upperCase); // 打印: NICOLA
導入 Imports
// 導入核心庫
import 'dart:math';
// 從外部包導入庫
import 'package:test/test.dart';
// 導入文件
import 'path/to/my_other_file.dart';
操作符
算術運算符
print(2 + 3); // 打印: 5
print(2 - 3); // 打印: -1
print(2 * 3); // 打印: 6
print(5 / 2); // 打印: 2.5 - 結果是 double
print(5 ~/ 2); // 打印: 2 - 結果是n int
print(5 % 2); // 打印: 1 - 余
int a = 1, b;
// 增
b = ++a; // 前增量 - 在 b 獲得其值之前增加 a
b = a++; // 后增量 - 在 b 獲得它的值之后增加 a
// 遞
b = --a; // 前減量 - 在 b 獲得它的值之前減少 a
b = a--; // 后減量 - 在 b 獲得它的值之后遞減 a
邏輯運算符
// !expr 反轉表達式(將 false 更改為 true,反之亦然)
// || 邏輯或
// && 邏輯與
bool isOutOfStock = false;
int quantity = 3;
if (!isOutOfStock && (quantity == 2 || quantity == 3)) {
// ...Order the product...
}
等式和關系運算符
print(2 == 2); // 打印: true - 平等的
print(2 != 3); // 打印: true - 不相等
print(3 > 2); // 打印: true - 比...更棒
print(2 < 3); // 打印: true - 少于
print(3 >= 3); // 打印: true - 大于或等于
print(2 <= 3); // 打印: true - 小于或等于
控制流:條件
if 和 else if
if(age < 18){
print("Teen");
} else if( age > 18 && age <60){
print("Adult");
} else {
print("Old");
}
switch case
enum Pet {dog, cat}
Pet myPet = Pet.dog;
switch(myPet){
case Pet.dog:
print('My Pet is Dog.');
break;
case Pet.cat:
print('My Pet is Cat.');
break;
default:
print('I don't have a Pet');
}
// 打印: My Pet is Dog.
控制流:循環
while 循環
while (!dreamsAchieved) {
workHard();
}
循環迭代之前的 while 循環檢查條件
do-while 循環
do {
workHard();
} while (!dreamsAchieved);
do-while 循環在執行循環內的語句后驗證條件
for 循環
for(int i=0; i< 10; i++){
print(i);
}
var numbers = [1,2,3];
// 列表的 for-in 循環
for(var number in numbers){
print(number);
}
Collections
Lists
// 有序的對象組
var list = [1, 2, 3];
print(list.length); //Print: 3
print(list[1]); //Print: 2
// 列表聲明和初始化的其他方式
List<String> cities = <String>["New York", "Mumbai", "Tokyo"];
// 創建一個編譯時常量的列表
const constantCities = const ["New York", "Mumbai", "Tokyo"];
Maps
// 映射是關聯鍵和值的對象
var person = Map<String, String>();
// 要初始化地圖,請執行以下操作:
person['firstName'] = 'Nicola';
person['lastName'] = 'Tesla';
print(person);
// 打印: {firstName:Nicola, lastName:Tesla}
print(person['lastName']);
// 打印: Tesla
var nobleGases = {
// Key: Value
2: 'helium',
10: 'neon',
18: 'argon',
};
Sets
// Dart 中的集合是唯一項的無序集合
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
// 創建一個空集
var names = <String>{};
Set<String> names = {}; // 這也有效
//var names = {}; // 創建地圖,而不是集合
函數
函數示例
// dart 中的函數是對象并且有一個類型
int add(int a, int b){
return a+b;
}
// 函數可以分配給變量
int sum = add(2,3); // 回報:5
// 可以作為參數傳遞給其他函數
int totalSum = add(2, add(2,3)); // 返回:7
箭頭語法 (=>)
// 只包含一個表達式的函數,您可以使用簡寫語法
bool isFav(Product product) => favProductsList.contains(product);
Anonymous (lambda) functions
// 沒有名字的小單行函數
int add(a,b) => a+b;
// lambda 函數大多作為參數傳遞給其他函數
const list = [
'Apples', 'bananas', 'oranges'
];
list.forEach(
(item) =>
print('${list.indexOf(item)}: $item')
);
// 打印: 0: apples 1: bananas 2: oranges
類和對象
類 Class
class Cat {
String name;
// 方法
void voice(){
print("Meow");
}
}
對象 Object
// 類的實例
// 在 myCat 下面是 Cat 類的對象
void main(){
Cat myCat = Cat();
myCat.name = "Kitty";
myCat.voice(); // 打印: Meow
}
構造函數
class Cat {
String name;
Cat(this.name);
}
void main(){
Cat myCat = Cat("Kitty");
print(myCat.name); // 打印: Kitty
}
抽象類
// 抽象類——不能實例化的類
// 這個類被聲明為抽象的,因此不能被實例化
abstract class AbstractContainer {
// 定義構造函數、字段、方法...
void updateChildren(); // 抽象方法
}
Getters Setters
// 提供對對象屬性的讀寫訪問
class Cat {
String name;
// getter
String get catName {
return name;
}
// setter
void set catName(String name){
this.name = name;
}
}
隱式接口
一個基本的界面
// 一個人。隱式接口包含 greet()。
class Person {
// 在接口中,但僅在此庫中可見。
final String _name;
// 不在接口中,因為這是一個構造函數。
Person(this._name);
// 在接口中
String greet(String who) => 'Hello, $who. I am $_name.';
}
// Person 接口的實現。
class Impostor implements Person {
String 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')));
// 打印: Hello, Bob. I am Kathy.
print(greetBob(Impostor()));
// 打印: Hi Bob. Do you know who I am?
}
擴展類
class Phone {
void use(){
_call();
_sendMessage();
}
}
// 使用 extends 創建子類
class SmartPhone extends Phone {
void use(){
// 使用 super 來引用超類
super.use();
_takePhotos();
_playGames();
}
}
異常
Throw
// 拋出 throws 或引發 raises 和異常 exception
throw IntegerDivisionByZeroException();
// 你也可以拋出任意對象
throw "Product out of stock!";
Catch
try {
int c = 3/0;
print(c);
} on IntegerDivisionByZeroException {
// 一個特定的異常
print('Can not divide integer by 0.')
} on Exception catch (e) {
// 任何其他異常情況
print('Unknown exception: $e');
} catch (e) {
// 沒有指定類型,處理所有
print('Something really unknown: $e');
}
Finally
// 確保某些代碼無論是否拋出異常都能運行
try {
cookFood();
} catch (e) {
print('Error: $e'); // 先處理異常
} finally {
cleanKitchen(); // 然后清理
}
Futures
Async Await
// 異步函數:它們在設置可能耗時的操作后返回
// async 和 await 關鍵字支持異步編程
Future<String> login() {
String userName="Temidjoy";
return
Future.delayed(
Duration(seconds: 4), () => userName
);
}
// 異步
main() async {
print('Authenticating please wait...');
print(await userName());
}
各種各樣的
Null 和 Null 感知
int x; // 任何對象的初始值為 null
// ?? 空感知運算符
x ??=6; // ??= 賦值運算符,僅當變量當前為 null 時才為其賦值
print(x); // 打印: 6
x ??=3;
print(x); // 打印: 6 - 結果仍然是 6
print(null ?? 10); // 打印: 10。如果不為空,則顯示左側的值,否則返回右側的值
三元運算符
// 條件 ? 條件如果為真 : 條件如果為假
bool isAvailable;
isAvailable ? orderproduct() : addToFavourite();
條件屬性訪問
userObject?.userName
// 上面的代碼片段等效于以下代碼:
(userObject != null) ? userObject.userName : null
// 您可以將 ? 的多種用途鏈接起來。一起在一個表達式中
userObject?.userName?.toString()
// 如果 userObject 或 userObject.userName 為 null,則前面的代碼返回 null 并且從不調用 toString()
級聯符號 (..)
// 允許您對同一對象進行一系列操作
// 而不是這樣做
var user = User();
user.name = "Nicola";
user.email = "nicola@g.c";
user.age = 24;
// 你可以這樣做
var user = User()
..name = "Nicola"
..email = "nicola@g.c"
..age = 24;
擴展運算符 (...)
// 將多個值插入到集合中
var list = [1, 2, 3];
var list2 = [0, ...list];
print(list2.length); // 打印: 4
更多參考 Dart 官方文檔 (dart.dev