一祷嘶、變量
二傀蓉、數(shù)據(jù)類型
三涂邀、函數(shù)
四替久、操作符、運(yùn)算符
五辫呻、流程控制
六清钥、對(duì)象與類
七、異步請(qǐng)求
dart語(yǔ)言簡(jiǎn)易教程一
一個(gè)簡(jiǎn)單的dart 程序
// Define a function.
printNumber(num aNumber) {
print('The number is $aNumber.'); // Print to console.
}
// This is where the app starts executing.
main() {
var number = 42; // Declare and initialize a variable.
printNumber(number); // Call a function.
}
從這個(gè)程序里面我們可以看到如下的東西:
使用//來(lái)注釋放闺。同時(shí)/* ...*/也可以用來(lái)注釋祟昭。
num 是一個(gè)數(shù)據(jù)類型,定義在語(yǔ)言中怖侦。同樣的類型還有String篡悟,int谜叹,bool。
就是說(shuō)Dart語(yǔ)言是有數(shù)據(jù)類型的概念的搬葬。
print() 是顯示輸出的方法荷腊。
'...'(或者"..."),表示是有個(gè) string 類型的數(shù)據(jù)急凰。
var 定義了一個(gè)變量女仰,但是沒有指定特定的數(shù)據(jù)類型。
按照Dart 的編程規(guī)范抡锈,使用2個(gè)空格來(lái)縮進(jìn)疾忍。
這一點(diǎn)與java語(yǔ)言建議的4個(gè)空格不一樣。
一些重要的概念
所有的東西都是對(duì)象床三,無(wú)論是變量一罩,數(shù)字,函數(shù)等撇簿。
所以的對(duì)象都是類的實(shí)例聂渊。
所有的對(duì)像都繼承自內(nèi)置的Object類。程序中指定數(shù)據(jù)類型是為了指出自己的使用意圖补疑,并幫助語(yǔ)言進(jìn)行語(yǔ)法檢查歧沪。但是歹撒,指定類型不是必須的莲组。
Dart 語(yǔ)言是弱數(shù)據(jù)類型。Dart 代碼在運(yùn)行前解析暖夭。
指定數(shù)據(jù)類型和編譯時(shí)的常量锹杈,可以提高運(yùn)行速度。Dart 程序有統(tǒng)一的程序入口: main()迈着。
這一點(diǎn)是C / C++語(yǔ)言相像竭望。Dart 沒有public ,protected裕菠,and private的概念咬清。
但是如果變量或函數(shù)以下劃線(_)開始,則該函數(shù)或變量屬于這個(gè)包私有(private)的方法奴潘。Dart 中變量或函數(shù)以下劃線(_)或字母開始旧烧,后面接上任意組合的下劃線( _ ),數(shù)字或字母画髓。這點(diǎn)與大部分的編程語(yǔ)言是一樣的掘剪。
Dart 的工具可以檢查出警告信息(warning)和錯(cuò)誤(errors)。
警告信息只是表明代碼可能不工作奈虾,但是不會(huì)妨礙程序運(yùn)行夺谁。
錯(cuò)誤可以是編譯時(shí)的錯(cuò)誤廉赔,也可能是運(yùn)行時(shí)的錯(cuò)誤。編譯的錯(cuò)誤將阻止程序運(yùn)行匾鸥,運(yùn)行時(shí)的錯(cuò)誤將會(huì)以exception的方式呈現(xiàn),這點(diǎn)與java捕獲異常類似蜡塌。Dart 使用 ; 來(lái)分割語(yǔ)句這點(diǎn)類似Java / C++
關(guān)鍵字
Dart 語(yǔ)言提供的關(guān)鍵字如下表所示:
1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|
abstract | continue | false | new | this |
as | default | final | null | throw |
assert | deferred | finally | operator | true |
async | do | for | part | try |
async | dynamic | get | rethrow | typedef |
await | else | if | return | var |
break | enum | implements | set | void |
case | export | import | static | while |
catch | external | in | super | with |
class | extends | is | switch | yield |
const | factory | library | sync | yield |
變量(Variable)
變量賦值的例子
// The variable called name contains a reference to a String object with a value of “Bob”.
var name = 'Bob';
默認(rèn)值
沒有初始化的變量都會(huì)被賦予默認(rèn)值 null.
即使是數(shù)字也是如此, 因?yàn)樵贒art 中數(shù)字也是一個(gè)對(duì)象扫腺。
int lineCount;
assert(lineCount == null);
// Variables (even if they will be numbers) are initially null.
```language
注意:assert()調(diào)用在生產(chǎn)模式中被忽略岗照。在檢查模式下,斷言(條件)拋出異常笆环,除非條件為真攒至。
可選類型
也可以在定義的時(shí)候指定變量的類型。
String name = 'Bob';
指定數(shù)據(jù)類型可以更好的辨明自己的使用意圖躁劣,編譯器和IDE 工具可以根據(jù)這些類型信息來(lái)做檢查迫吐,更早的發(fā)現(xiàn)問題。
如前文所說(shuō)账忘,通過指定類型志膀,也可以減少編譯和運(yùn)行時(shí)間。
常量和固定值
如果定義的變量不會(huì)變化鳖擒,可以使用 final 或 const來(lái)指明溉浙。
也可以使用final 或 *
const來(lái)代替類型聲明。
final的值只能被設(shè)定一次蒋荚。
const 是一個(gè)編譯時(shí)的常量戳稽。( Const variables are implicitly final.)
final name = 'Bob'; // Or: final String name = 'Bob';
// name = 'Alice'; // Uncommenting this causes an error
通過對(duì)const類型做四則運(yùn)算將自動(dòng)得到一個(gè)const類型的值。
const bar = 1000000; // Unit of pressure (dynes/cm2)
const atm = 1.01325 * bar; // Standard atmosphere
```language
dart語(yǔ)言簡(jiǎn)易教程二
內(nèi)建數(shù)據(jù)類型(Built-in types)
Dart 語(yǔ)言內(nèi)建了下面集中類型
- numbers
- strings
- booleans
- lists (also known as arrays)
- maps
- runes (for expressing Unicode characters in a string)
- Number 類型
int
取值范圍:-2^53 to 2^53
double
64 位長(zhǎng)度的浮點(diǎn)型數(shù)據(jù)期升,符合IEEE 754 標(biāo)準(zhǔn)惊奇。
int 和 double 類型都是 num 類型的子類。
num 類型包括的操作包括: +, -, *, / 以及位移操作>>.
num 類型 有如下常用方法 abs(), ceil()和 floor()播赁。完整的使用方法請(qǐng)參見:dart:math 包的使用說(shuō)明颂郎。
int 類型不能包含小數(shù)點(diǎn)..
num類型操作例子:
// String -> int
var one = int.parse('1');
assert(one == 1);
// String -> double
var onePointOne = double.parse('1.1');
assert(onePointOne == 1.1);
// int -> String
String oneAsString = 1.toString();
assert(oneAsString == '1');
// double -> String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == '3.14');
num 類型按位操作的例子:
assert((3 << 1) == 6); // 0011 << 1 == 0110
assert((3 >> 1) == 1); // 0011 >> 1 == 0001
assert((3 | 4) == 7); // 0011 | 0100 == 0111
Strings 類型
Dart 的String 是 UTF-16 編碼的一個(gè)隊(duì)列。
Dart語(yǔ)言定義的例子:
var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
var s3 = 'It\'s easy to escape the string delimiter.';
var s4 = "It's even easier to use the other delimiter.";
String 類型可以使用 + 操作:
var s1 = 'String ' 'concatenation'
" works even over line breaks.";
assert(s1 == 'String concatenation works even over '
'line breaks.');
var s2 = 'The + operator '
+ 'works, as well.';
assert(s2 == 'The + operator works, as well.');
可以使用三個(gè)‘ 或“來(lái)定義多行的String 類型容为。
var s1 = '''
You can create
multi-line strings like this one.
''';
var s2 = """This is also a
multi-line string.""";
可以使用r 來(lái)修飾String類型乓序,表 表明是“raw” 類型字符串:
var s = r"In a raw string, even \n isn't special.";
String 類型可以在編譯是才給String類型賦值。
// These work in a const string.
const aConstNum = 0;
const aConstBool = true;
const aConstString = 'a constant string';
// These do NOT work in a const string.
var aNum = 0;
var aBool = true;
var aString = 'a string';
const aConstList = const [1, 2, 3];
const validConstString = '$aConstNum $aConstBool $aConstString';
// const invalidConstString = '$aNum $aBool $aString $aConstList';
booleans 類型
Dart 的布爾類型名字是bool坎背,可能的取值包括”ture“ 和 ”false“替劈。
”bool“ 類型是 compile-time 的常量。
Dart 是強(qiáng)bool 類型檢查沼瘫,只有bool 類型的值是”true“ 才被認(rèn)為是true抬纸。
var name = 'Bob';
if (name) {
// Prints in JavaScript, not in Dart.
print('You have a name!');
}
在production mode 中上面的代碼將不會(huì)輸出任何東西,因?yàn)閚ame != true耿戚。
checked mode 中上面的代碼將會(huì)出現(xiàn)異常湿故,因?yàn)閚ame不是bool 類型阿趁。
Lists 類型
在 Dart 語(yǔ)言中,具有一系列相同類型的數(shù)據(jù)被稱為 List 對(duì)象坛猪。
Dart List 對(duì)象類似JavaScript 語(yǔ)言的 array 對(duì)象脖阵。
定義list的例子:
var list = [1, 2, 3];
Dart list 對(duì)象的第一個(gè)元素的位置是0,最后個(gè)元素的索引是list.lenght - 1墅茉。
var list = [1, 2, 3];
assert(list.length == 3);
assert(list[1] == 2);
list[1] = 1;
assert(list[1] == 1);
Maps 類型
Map 類型將keys 和 values 關(guān)聯(lián)在一起命黔。
keys 和 values 可以是任意類型的對(duì)象。
像其它支持Map 的編程語(yǔ)言一樣就斤,Map 的 key 必須是唯一的悍募。
Map 對(duì)象的定義:
var gifts = {
// Keys Values
'first' : 'partridge',
'second': 'turtledoves',
'fifth' : 'golden rings'
};
var nobleGases = {
// Keys Values
2 : 'helium',
10: 'neon',
18: 'argon',
};
也可以使用Map 對(duì)象的構(gòu)造函數(shù) Map() 來(lái)創(chuàng)建Map 對(duì)象:
var gifts = new Map();
gifts['first'] = 'partridge';
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings';
var nobleGases = new Map();
nobleGases[2] = 'helium';
nobleGases[10] = 'neon';
nobleGases[18] = 'argon';
添加新的key-value 對(duì):
var gifts = {'first': 'partridge'};
assert(gifts['first'] == 'partridge');
檢查key 是否在Map 對(duì)象中:
var gifts = {'first': 'partridge'};
assert(gifts['fifth'] == null);
使用.lenght 來(lái)獲取key-value 對(duì)的數(shù)量:
var gifts = {'first': 'partridge'};
gifts['fourth'] = 'calling birds';
assert(gifts.length == 2);
Runes 類型
Dart 中 runes 是UTF-32字符集的string 對(duì)象。
codeUnitAt 和 codeUnit 用來(lái)獲取UTF-16字符集的字符洋机。
使用runes 來(lái)獲取UTF-32字符集的字符坠宴。
main() {
var clapping = '\u{1f44f}';
print(clapping);
print(clapping.codeUnits);
print(clapping.runes.toList());
Runes input = new Runes(
'\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
上面例子的輸出結(jié)果是:
[55357, 56399]
[128079]
Dart 語(yǔ)言簡(jiǎn)易教程(三)
函數(shù)(Functions)
Dart 是一個(gè)面向?qū)ο蟮恼Z(yǔ)言,所以即使是函數(shù)也是對(duì)象绷旗,函數(shù)屬于Function對(duì)象喜鼓。
可以通過函數(shù)來(lái)指定變量或者像其它的函數(shù)傳遞參數(shù)。
函數(shù)實(shí)現(xiàn)的例子:
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
可以去掉形式參數(shù)數(shù)據(jù)類型和返回值的數(shù)據(jù)類型衔肢。
下面的例子演示了這些:
isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
如果函數(shù)只有單個(gè)語(yǔ)句庄岖,可以采用簡(jiǎn)略的形式:
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
函數(shù)可以有兩中類型的參數(shù):
必須的
必須的參數(shù)放在參數(shù)列表的前面。可選的
可選的參數(shù)跟在必須的參數(shù)后面角骤。
可選的參數(shù)
可以通過名字或位置指定可選參數(shù)隅忿。
函數(shù)調(diào)用:
enableFlags(bold: true, hidden: false);
可選的位置參數(shù)
將參數(shù)使用[] 括起來(lái),用來(lái)表明是可選位置參數(shù)启搂。
例如下面的例子硼控,函數(shù)定義:
String say(String from, String msg, [String device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
調(diào)用函數(shù)不包含第三個(gè)參數(shù):
assert(say('Bob', 'Howdy') == 'Bob says Howdy');
調(diào)用函數(shù)包含第三個(gè)參數(shù):
assert(say('Bob', 'Howdy', 'smoke signal') ==
'Bob says Howdy with a smoke signal');
參數(shù)默認(rèn)值
可以定義包含默認(rèn)位置參數(shù)或默認(rèn)名字參數(shù)的函數(shù)刘陶。參數(shù)的默認(rèn)值必須是編譯時(shí)的靜態(tài)值胳赌。
假如定義函數(shù)時(shí),沒有指定默認(rèn)的參數(shù)值匙隔,則參數(shù)值默認(rèn)為null 疑苫。
- 使用冒號(hào)(:)來(lái)設(shè)置默認(rèn)名字參數(shù)。
// Sets the [bold] and [hidden] flags to the values you
// specify, defaulting to false.
enableFlags({bool bold: false, bool hidden: false}) {
// ...
}
// bold will be true; hidden will be false.
enableFlags(bold: true);
- 使用等號(hào)(
=
)來(lái)設(shè)置默位置字參數(shù)纷责。
String say(String from, String msg,
[String device = 'carrier pigeon', String mood]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
if (mood != null) {
result = '$result (in a $mood mood)';
}
return result;
}
assert(say('Bob', 'Howdy') ==
'Bob says Howdy with a carrier pigeon');
也可以將lists 及maps類型作為默認(rèn)值捍掺。
如下面的例子:
doStuff([List<int> list: const[1, 2, 3],
Map<String, String> gifts: const{'first': 'paper',
'second': 'cotton',
'third': 'leather'}]) {
print('list: $list');
print('gifts: $gifts');
}
main() {
// Use the default values for both parameters.
doStuff();
// Use the default values for the "gifts" parameter.
doStuff(list:[4,5,6]);
// Don't use the default values for either parameter.
doStuff(list: null, gifts: null);
}
對(duì)應(yīng)輸出結(jié)果是:
list: [1, 2, 3]
gifts: {first: paper, second: cotton, third: leather}
list: [4, 5, 6]
gifts: {first: paper, second: cotton, third: leather}
list: null
gifts: null
main() 函數(shù)
所以的APP 都必須有一個(gè)mian()函數(shù),作為APP 的應(yīng)用接入點(diǎn)再膳。
main()函數(shù)返回void 類型挺勿,并且包含可選的List< String > 類型的參數(shù)。
main()函數(shù)不包含參數(shù)的例子:
void main() {
querySelector("#sample_text_id")
..text = "Click me!"
..onClick.listen(reverseText);
}
傳遞函數(shù)給函數(shù)
可以將一個(gè)函數(shù)作為一個(gè)參數(shù)傳遞給另一個(gè)函數(shù)喂柒。例如:
printElement(element) {
print(element);
}
var list = [1, 2, 3];
// Pass printElement as a parameter.
list.forEach(printElement);
//forEach傳入list中的每一個(gè)值做為參數(shù)
也可以將函數(shù)賦值給一個(gè)變量不瓶。例如:
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');
變量作用范圍
嵌套的函數(shù)中可以訪問包含他的函數(shù)中定義的變量禾嫉。例如:
var topLevel = true;
main() {
var insideMain = true;
myFunction() {
var insideFunction = true;
nestedFunction() {
var insideNestedFunction = true;
assert(topLevel);
assert(insideMain);
assert(insideFunction);
assert(insideNestedFunction);
}
}
}
變量閉合
函數(shù)可以返回一個(gè)函數(shù)。例如:
/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(num addBy) {
return (num i) => addBy + i;
}
main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
函數(shù)返回值
所有的函數(shù)都會(huì)有返回值蚊丐。
如果沒有指定函數(shù)返回值熙参,則默認(rèn)的返回值是null。
沒有返回值的函數(shù)麦备,系統(tǒng)會(huì)在最后添加隱式的return 語(yǔ)句孽椰。
dart語(yǔ)言簡(jiǎn)易教程四
操作符與運(yùn)算符
類型比較操作符
Dart 支持在運(yùn)行時(shí)比較對(duì)象的類型,支持的操作如下:
Operator | Meaning |
---|---|
as | Typecast |
is | True if the object has the specified type |
is! | False if the object has the specified type |
is操作凛篙,用來(lái)比較前操作數(shù)是否是后操作數(shù)的對(duì)象黍匾。
as操作,用來(lái)將前操作數(shù)指定為后操作數(shù)的類型呛梆。
指定操作符
=操作符膀捷,將后操作數(shù)的值賦給前操作數(shù)。
??=操作符削彬,如果前操作數(shù)是null類型全庸,則將后操作數(shù)賦值給前操作數(shù);如果前操作數(shù)不等于null,則保持前操作數(shù)的值發(fā)生變化融痛。
級(jí)聯(lián)操作符(..)
通過級(jí)聯(lián)操作符(..)壶笼,可以連續(xù)的操作同一對(duì)象,達(dá)到減少中間變量雁刷,減少代碼的目的覆劈。
如下面的例子:
querySelector('#button') // Get an object.
..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
下面的代碼與上面的例子實(shí)現(xiàn)功能完全相同:
var button = querySelector('#button');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
另一段例子:
final addressBook = (new AddressBookBuilder()
..name = 'jenny'
..email = 'jenny@example.com'
..phone = (new PhoneNumberBuilder()
..number = '415-555-0100'
..label = 'home')
.build())
.build();
簡(jiǎn)易教程五--流程控制
- if and else
- for loops
- while and do-while loops
- break and continue
- switch and case
- assert
- try-catch and throw
簡(jiǎn)易教程六
Dart 語(yǔ)言中類型是可選的,但是明確的指明使用的是泛型
如下面代碼沛励,泛型可以減少代碼重復(fù)
代碼片段一
abstract class ObjectCache {
Object getByKey(String key);
setByKey(String key, Object value);
}
代碼片段二
abstract class StringCache {
String getByKey(String key);
setByKey(String key, String value);
}
以上的兩段代碼可以使用泛型簡(jiǎn)化如下:
abstract class Cache<T> {
T getByKey(String key);
setByKey(String key, T value);
}
庫(kù)和可見性(Libraries and visibility)
使用import 和 library 機(jī)制可以方便的創(chuàng)建一個(gè)模塊或分享代碼责语。
一個(gè)Dart 庫(kù)不僅能夠提供相應(yīng)的API,還可以包含一些以_開頭的變量用于在庫(kù)內(nèi)部使用目派。
每一個(gè)Dart 應(yīng)用都是一個(gè)庫(kù)坤候,即使它沒有使用庫(kù)機(jī)制。
庫(kù)可以方便是使用各種類型的包企蹭。
引用庫(kù)
通過import 語(yǔ)句在一個(gè)庫(kù)中引用另一個(gè)庫(kù)的文件白筹。
import 的例子:
import 'dart:html';
在import語(yǔ)句后面需要接上庫(kù)文件的路徑。
對(duì)Dart 語(yǔ)言提供的庫(kù)文件以dart:xx 格式
其它第三方的庫(kù)文件使用package:xx格式
import 'dart:io';
import 'package:mylib/mylib.dart';
import 'package:utils/utils.dart';
指定一個(gè)庫(kù)的前綴(Specifying a library prefix)
當(dāng)引用的庫(kù)擁有相互沖突的名字谅摄,可以為其中一個(gè)或幾個(gè)指定不一樣的前綴徒河。
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// ...
Element element1 = new Element(); // Uses Element from lib1.
lib2.Element element2 = new lib2.Element(); // Uses Element from lib2.
引用庫(kù)的一部分
如果只需要使用庫(kù)的一部分內(nèi)容,可以有選擇的引用送漠。
show 關(guān)鍵字:只引用一點(diǎn)
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;
延遲加載庫(kù)(Deferred loading a library)
延遲加載機(jī)制顽照,可以在需要使用的時(shí)候再加載庫(kù)。
使用延遲加載庫(kù)的原因:
減少應(yīng)用啟動(dòng)時(shí)間
只加載必要的功能
為了實(shí)現(xiàn)延遲加載闽寡,必須使用deferred as 關(guān)鍵字代兵。
import 'package:deferred/hello.dart' deferred as hello;
然后在需要使用的時(shí)候調(diào)用loadLibrary()方法纵穿。
greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
簡(jiǎn)易教程七--異步請(qǐng)求
Dart中沒有線程的概念,只有isolate奢人,每個(gè)isolate都是隔離的谓媒,并不會(huì)共享內(nèi)存。
dart實(shí)現(xiàn)多線程的方式有兩種
通過dart:async這個(gè)Lib中的API即可:
使用Future類何乎,可以將任務(wù)加入到Event Queue的隊(duì)尾通過isolate來(lái)實(shí)現(xiàn)