Flutter Dart語法學(xué)習(xí)

Dart

開發(fā)FlutterApp之前我們肯定要先了解Dart這門語言及語言的特性熊户、語法等吭服。最近看了大量的Dart語言相關(guān)內(nèi)容,本章會來簡述蝌戒。
目錄

  • 概念及優(yōu)點
  • 變量
  • 函數(shù)
  • 閉包
  • 異步支持
概念及優(yōu)點:
  • Dart:
    Google及全球的其他開發(fā)者沼琉,使用 Dart 開發(fā)了一系列高質(zhì)量打瘪、 關(guān)鍵的 iOS、Android 和 web 應(yīng)用闺骚。 Dart 非常適合移動和 web 應(yīng)用的開發(fā)僻爽。
    1.高效
    Dart 語法清晰簡潔,工具簡單而強大敦捧。 輸入檢測可幫助您盡早識別細(xì)微錯誤。 Dart 擁有久經(jīng)考驗的 核心庫(core libraries) 和一個已經(jīng)擁有數(shù)以千計的 packages 生態(tài)系統(tǒng)
    2.快速
    Dart 提供提前編譯優(yōu)化习瑰,以在移動設(shè)備和 web 上實現(xiàn)可預(yù)測的高性能和快速啟動济蝉。
    3.可移植
    Dart 可以編譯成 ARM 和 x86 代碼,因此 Dart 移動應(yīng)用程序可以在 iOS贺嫂,Android 及 更高版本上實現(xiàn)本地運行雁乡。 對于 web 應(yīng)用程序,Dart 可以轉(zhuǎn)換為 JavaScript曲饱。
    4.易學(xué)
    Dart 是面向?qū)ο蟮木幊陶Z言珠月,語法風(fēng)格對于許多現(xiàn)有的開發(fā)人員來說都很熟悉啤挎。了解Java、JS語言 胜臊,使用 Dart 也就很簡單伙判,也有Swift的一些特性。
    5.響應(yīng)式
    Dart 可以便捷的進(jìn)行響應(yīng)式編程勒魔。由于快速對象分配和垃圾收集器的實現(xiàn)酱塔, 對于管理短期對象(比如 UI 小部件), Dart 更加高效唐全。 Dart 可以通過 Future Stream 的特性和API實現(xiàn)異步編程。
變量
  • var
    自動推斷類型(這點與OC弥雹、Java不同)延届,接收任何類型的的變量方庭,但是一旦賦值,類型就不能改變械念,即本來是字符串龄减,之后就只能是字符串(這點與JS不同)。
var a = "字符串";
//主意:如果這樣就會報錯烁巫,類型在第一次指定后就不能改變
a = 1;

原因:Dart是強類型語言宠能,任何變量都有各自的類型,編譯時會根據(jù)首次賦值數(shù)據(jù)的類型來推斷其類型恃鞋,編譯結(jié)束后其類型不能更改亦歉。JS是純粹的弱類型腳本語言肴楷,var只是變量的聲明荠呐。

  • dynamic
    dynamic與var一樣都是關(guān)鍵詞,聲明的變量可以賦值任意類型對象。聲明的變量可以在后期改變賦值類型呵恢。即本來是字符串媚创,之后可以賦值為number等其他類型。
dynamic a = "字符串";
//不會報錯
a = 1;
  • Object
    Object與dynamic一樣也是聲明的變量可以賦值任意類型對象鳄橘,聲明的變量可以在后期改變賦值類型瘫怜。
Object b = "hello world";
//不會報錯
b = 10;

不同之處,dynamic聲明的對象編譯器會提供所有可能的組合赠涮,至少不會報錯(但有可能運行時會因為找不到之前預(yù)制的組合暗挑,造成崩潰), 而Object聲明的對象只能使用Object的屬性與方法, 否則編譯器會報錯。

dynamic a = "";
Object b = "";
//編譯器不報錯株憾,不警告晒衩。
print(a.length);
//編譯器會警告報錯(Object沒有l(wèi)ength的getter方法):The getter 'length' is not defined for the class 'Object'
print(b.length);

注意:dynamic可以理解為id類型听系,任何類型都可以轉(zhuǎn)換成id(dynamic)類型,可以用id(dynamic)去接掉瞳,編譯器不會報錯浪漠,但是在運行時可能會產(chǎn)生錯誤出現(xiàn)崩潰現(xiàn)象。

  • final
    final 為運行時常量该镣。
    final修飾的常量必須在聲明的時候就進(jìn)行初始化响谓,而且在初始化之后值不可變娘纷,
final a = "名字";
//會報錯
a = "性別";
  • const
    const 為編譯時常量律适。
    const不僅僅可以聲明常數(shù)變量,也可以聲明常量值以及聲明創(chuàng)建常量值的構(gòu)造函數(shù)棉圈,任何變量都可以有一個常量值眷蜓;
final aList = const[];
const bList = const[]德召;
var cList = const[]汽纤;

這里的aList和bList就是兩個空的蕴坪、不可變的列表集合,而cList則是空的呆瞻、可變的列表集合径玖;
需要注意的是:cList可以重新賦值,可以改變赞赖,而aList和bList不可以重新賦值冤灾;
  • 函數(shù)
    Dart是面向?qū)ο蟮恼Z言韵吨,所以即使是函數(shù)也是對象,并且有一個類型Function。這意味著函數(shù)可以賦值給變量或作為參數(shù)傳遞給其他函數(shù)吞杭,這是函數(shù)式編程的典型特征芽狗。
    1.函數(shù)聲明
返回類型  方法體  (參數(shù)1,  參數(shù)2, ...){
    方法體...
    return 返回值
}

String getPerson(String name, int age){
  return name + '${age}';
}

//如果返回類型不指定時,此時默認(rèn)為dynamic滴劲。

2.箭頭函數(shù)
對于只包含一個表達(dá)式的函數(shù),可以使用簡寫語法鲁捏。

getPerson(name,  age) => name+ ', $age' ; 

bool isNoble (int atomicNumber)=> _nobleGases [ atomicNumber ] 萧芙!= null ;

3.函數(shù)作為變量(方法對象)双揪、入?yún)?/p>

//函數(shù)作為變量
var  method1 = (str){
print(str)
};
method1("kakalala");

//函數(shù)作為參數(shù)
void execute(var callbackMethod){
callbackMethod();
}
//兩種
execute(() => print("xxx"));
execute(method1("kakalala"));

4.可選參數(shù)(可選位置參數(shù)、可選命名參數(shù))

  • 可選位置參數(shù):[param1, param2, ...],可以設(shè)置默認(rèn)參數(shù)
    包裝一組函數(shù)參數(shù)运吓,用[]標(biāo)記為可選的位置參數(shù)疯趟,并放在參數(shù)列表的最后面:
getPerson(String name, [int age = 99, String gender = "御姐"]){
  print ("name = $name, age = $age, gender = $gender");
}

//getPerson() ;這種不傳參是會報錯的迅办。
getPerson(null) ;
getPerson('不知火') ;
getPerson('不知火', 100);
getPerson('不知火', null,  "蘿莉");

控制臺輸出

flutter: name = null, age = 99, gender = 御姐
flutter: name = 不知火, age = 99, gender = 御姐
flutter: name = 不知火, age = 100, gender = 御姐
flutter: name = 不知火, age = null, gender = 蘿莉

注意:name參數(shù)是必須傳入的,否則會報錯姨夹。后邊的可選位置參數(shù)如果不傳會是null矾策,傳null還是會返回null贾虽。可選位置參數(shù)可以設(shè)置默認(rèn)參數(shù)绰咽。

  • 可選命名參數(shù):{param1, param2, ...}
    在傳入的時候地粪,需要指定下對應(yīng)的參數(shù)名蟆技,放在參數(shù)列表的最后面斗忌,用于指定命名參數(shù)旺聚∨榇猓可以設(shè)置默認(rèn)參數(shù)。
getPerson(String name, {int age = 100, String gender = "狼狗"}){
  print("name = $name, age = $age, gender = $gender");
}

//getPerson() ;這種不傳參是會報錯的惊窖。
getPerson(null) ;
getPerson('燼天玉藻前') ;
getPerson('燼天玉藻前', age: 99 );
getPerson('燼天玉藻前', gender: "御姐" );
getPerson('燼天玉藻前', age: 99, gender: "奶狗");

控制臺輸出:

flutter: name = null, age = 100, gender = 狼狗
flutter: name = 燼天玉藻前, age = 100, gender = 狼狗
flutter: name = 燼天玉藻前, age = 99, gender = 狼狗
flutter: name = 燼天玉藻前, age = 100, gender = 御姐
flutter: name = 燼天玉藻前, age = 99, gender = 奶狗

注意:固定參數(shù)必須傳入(那怕傳個null)界酒,可選命名參數(shù)可以設(shè)置默認(rèn)參數(shù)嘴秸。

  • 默認(rèn)參數(shù)值
    默認(rèn)參數(shù)值即我們在方法的參數(shù)列表上面使用 “=” 號給入一個常量值,如果沒有傳入該值的時候凭疮,就使用我們給入的常量值串述。
注意纲酗,不能同時使用可選的位置參數(shù)和可選的命名參數(shù)
//這種是不可以的,錯誤事例右蕊。
getPerson(String name, {int age = 100, String gender = "狼狗"}, [int age2 = 1002, String gender2 = "狼狗2"]){
 
}
閉包

閉包是一個方法(對象)吮螺,閉包定義在其它方法內(nèi)部,能夠訪問外部方法的局部變量萝风,并持有其狀態(tài)闹丐。

void main() {

    // 創(chuàng)建一個函數(shù)add1被因,返回加2
    Function add1 = addNum(2);
    
    // 創(chuàng)建一個函數(shù)add2,返回加4
    Function add2 = addNum(4);

    // 2 + 3 = 5
    print(add1(3));
    // 4 + 3 = 7
    print(add2(3));
}

// 返回一個函數(shù)對象堕花,功能是返回累加的數(shù)字
Function addNum(int addBy){
    return (int i) => addBy + I;
}

控制臺輸出:

flutter: 5
flutter: 7
異步支持

Dart代碼運行在一個單線程,如果Dart代碼阻塞了---例如缘挽,程序計算很長時間呻粹,或者等待I/O等浊,整個程序就會凍結(jié)。
Dart異步函數(shù):Future轧飞、Stream撒踪,設(shè)置好耗時操作后返回,不會阻塞線程掸绞。
async和await關(guān)鍵詞支持了異步編程耕捞,允許寫出和同步代碼很像的異步代碼砸脊。

Future

Future與JS中的Promise和Swift的RXSwift非常相似,其語法也是鏈?zhǔn)胶瘮?shù)調(diào)用驱显,該函數(shù)異步操作執(zhí)行后瞳抓,最終返回成功(執(zhí)行成功的操作)孩哑、失敗(捕獲錯誤或者停止后續(xù)操作)胳蛮,失敗和成功是對立的只會出現(xiàn)一種。
注意:Future 的所有API的返回值都是一個Future對象斗幼,所以可以進(jìn)行鏈?zhǔn)秸{(diào)用蜕窿。

  • Future構(gòu)造函數(shù)

Future(FutureOr<T> computation())
computation 的返回值可以是普通值或者是Future對象,但是都是Future對象接收呆馁。

 Future<num> future1 = Future(() {
  print('async call1');
  return 123;
});
//直接調(diào)用
future1.then((data) {
  //執(zhí)行成功會走到這里
  print(data);
}, onError: (e) {
  print("onError: \$e");
}).catchError((e) {
  //執(zhí)行失敗會走到這里
  print(e);
}).whenComplete(() {
  //無論成功或失敗都會走到這里
});

Future<Future> future2 = Future((){
    print('async call2');
    return future1;
});

//嵌套調(diào)用
future2.then((value) => value).then((value) => {
   print('222---'+value.toString())
});

控制臺打印

Reloaded 1 of 499 libraries in 154ms.
flutter: async call1
flutter: 123
flutter: async call2
flutter: 222---123

注意:computation函數(shù)體中的代碼是被異步執(zhí)行的浙滤,與JS中Promise構(gòu)造函數(shù)的回調(diào)執(zhí)行時機不一樣瓷叫,如需要被同步執(zhí)行,則使用如下這個命名構(gòu)造函數(shù):

Future.sync(FutureOr<T> computation())

//該段代碼放到上邊代碼之后執(zhí)行
Future<num> future3 = Future.sync((){
    print('sync call');
    return 333;
});

future3.then((value) => {
   print('sync'+'$value')
});

控制臺輸出

flutter: sync call
flutter: sync333
flutter: async call1
flutter: 123
flutter: async call2
flutter: 222---123

由此可見盒卸,future3(sync)方法會先執(zhí)行蔽介,之后在執(zhí)行之前的future1煮寡、future2.可見正常的future中的computation函數(shù)體中的代碼是被異步執(zhí)行的。

  • Future.then
    then中接收異步結(jié)果
Future.delayed(new Duration(seconds: 2),(){
   return "延遲2s執(zhí)行";
}).then((data){
   print(data);
});
  • Future.catchError
    捕獲錯誤
Future.delayed(new Duration(seconds: 2),(){
   //return "延遲2s執(zhí)行";
   throw AssertionError("Error");  
}).then((data){
   //執(zhí)行成功會走到這里  
   print("success");
}).catchError((e){
   //執(zhí)行失敗會走到這里  
   print(e);
});

在異步任務(wù)中拋出了一個異常薇组,then的回調(diào)函數(shù)將不會被執(zhí)行律胀, catchError回調(diào)函數(shù)將被調(diào)用貌矿;并不是只有 catchError回調(diào)才能捕獲錯誤逛漫,then方法還有一個可選參數(shù)onError(之前介紹結(jié)構(gòu)體時已經(jīng)提到),我們也可以它來捕獲異常:

Future.delayed(new Duration(seconds: 2), () {
    //return "延遲2s執(zhí)行";
    throw AssertionError("Error");
}).then((data) {
    print("success");
}, onError: (e) {
    print(e);
});
  • Future.whenComplete
    不管成功失敗都要處理事件的場景克握,會調(diào)用此方法菩暗,比如在網(wǎng)絡(luò)請求前彈出加載對話框,在請求結(jié)束后關(guān)閉對話框。這種場景下梢,有兩種方法孽江,第一種是分別在then或catch中關(guān)閉一下對話框,第二種就是使用Future的whenComplete回調(diào):
Future.delayed(new Duration(seconds: 2),(){
   //return "延遲2s執(zhí)行";
   throw AssertionError("Error");
}).then((data){
   //執(zhí)行成功會走到這里 
   print(data);
}).catchError((e){
   //執(zhí)行失敗會走到這里   
   print(e);
}).whenComplete((){
   //無論成功或失敗都會走到這里
});
  • Future.wait
    需要等待多個異步任務(wù)都執(zhí)行結(jié)束后再統(tǒng)一進(jìn)行一些操作(比如我們有一個界面辆琅,需要先分別從兩個網(wǎng)絡(luò)接口獲取數(shù)據(jù)婉烟,獲取成功后暇屋,我們需要將兩個接口數(shù)據(jù)進(jìn)行特定的處理后再顯示到UI界面上)
    Future.wait就是做這件事的(類似RXswift的zip函數(shù))咐刨,它接受一個Future數(shù)組參數(shù),只有數(shù)組中所有Future都執(zhí)行成功后而涉,才會觸發(fā)then的成功回調(diào)联予,只要有一個Future執(zhí)行失敗啼县,就會觸發(fā)錯誤回調(diào)。
Future<List<Future>> future4 = Future.wait([
 // 2秒后返回結(jié)果  
 Future.delayed(new Duration(seconds: 2), () {
   return "延遲2s執(zhí)行";
 }),
 // 4秒后返回結(jié)果  
 Future.delayed(new Duration(seconds: 4), () {
   return " 延遲4s執(zhí)行";
 })
])

future4.then((value) => {
print(value[0]+ value[1]);
}).catchError((e){
 print(e);
});

控制臺輸出

//等待4s輸出
flutter: 延遲2s執(zhí)行 延遲4s執(zhí)行
  • 回調(diào)地獄(Callback Hell)
    代碼中有大量異步邏輯躯泰,并且出現(xiàn)大量異步任務(wù)依賴其它異步任務(wù)的結(jié)果時谭羔,必然會出現(xiàn)回調(diào)中套回調(diào)情況。我們需要使用async/await和Future.then來解決這種問題麦向。
    使用場景:大量依賴的業(yè)務(wù)邏輯瘟裸,登錄流程邏輯等
    先來看下回調(diào)地獄例子:
//先分別定義各個異步任務(wù)
Future<String> future1(String str1){
    ...
//第一個任務(wù)
};
Future<String> future2(String str2){
    ...
//第二個任務(wù)
};
Future future3(String info){
    ...
    // 第三個任務(wù)
};

future1("str1").then((str2){
 //1返回數(shù)據(jù),作為2的參數(shù)
 future2(str2).then((info){
    //2的返回數(shù)據(jù)诵竭,作為3的入?yún)?    future3(info).then((){
       //獲取3的返回數(shù)據(jù)
        ...
    });
  });
})

Future消除Callback Hell
使用Future的鏈?zhǔn)綑C制话告,依次向下就避免了嵌套。跟JS的Promise完全一樣沙郭。不足之處是還是有一層回調(diào)佛呻。

future1("str1").then((str2){
      return future2(str2);
}).then((info){
    return future3(info);
}).then((e){
   //執(zhí)行3接下來的操作 
}).catchError((e){
  //錯誤處理  
  print(e);
});

async/await消除callback hell
上邊的方式雖然避免了嵌套,但是在每個方法還是有一層回調(diào)病线。我們可以使用async/await來實現(xiàn)像同步代碼那樣來執(zhí)行異步任務(wù)而不使用回調(diào)的方式吓著。

task() async {
   try{
    String str2 = await future1("str1");
    String info = await future2(str2);
    await future3(info);
    //執(zhí)行接下來的操作   
   } catch(e){
    //錯誤處理   
    print(e);   
   }  
}
  • async/await
    async用來表示函數(shù)是異步的芹助,定義的函數(shù)會返回一個Future對象坷澡,可以使用then方法添加回調(diào)函數(shù)
    await 后面是一個Future会通,表示等待該異步任務(wù)完成牙瓢,異步完成后才會往下走酣倾;await必須出現(xiàn)在 async 函數(shù)內(nèi)部簿盅。
    async/await將一個異步流用同步的代碼表現(xiàn)出來祟身。

async/await只是一個語法糖菩貌,JS編譯器或Dart解釋器最終都會將其轉(zhuǎn)化為一個JS的Promise和Dart的Future的調(diào)用鏈司澎。

Stream

如果說Future是可以接收單個異步事件返回單個事件的成功失敗欺缘,那么Stream就可以接收多個異步事件,并返回多個事件的成功失敗挤安,供使用者使用谚殊。
使用場景:多次讀取數(shù)據(jù)的異步任務(wù)場景,如網(wǎng)絡(luò)內(nèi)容下載漱受、文件讀寫等
該例子借助了其他地方的例子络凿。

Stream.fromFutures([
  // 1秒后返回結(jié)果
  Future.delayed(new Duration(seconds: 1), () {
    return "hello 1";
  }),
  // 拋出一個異常
  Future.delayed(new Duration(seconds: 2),(){
    throw AssertionError("Error");
  }),
  // 3秒后返回結(jié)果
  Future.delayed(new Duration(seconds: 3), () {
    return "hello 3";
  })
]).listen((data){
   print(data);
}, onError: (e){
   print(e.message);
},onDone: (){

});

控制臺輸出

flutter: hello 1
flutter: Error
flutter: hello 3

Future.wait是函數(shù)中存在多個延時操作,則以延時最長操作完成后統(tǒng)一返回昂羡,其他的延時操作等待最長的延時操作完成絮记。
async/await:處理多個異步操作,前后有依賴邏輯的虐先,使用異步實現(xiàn)同步怨愤。
Stream:統(tǒng)一監(jiān)聽該Stream中的多個異步延時操作返回,相當(dāng)于之前的多個Future異步處理統(tǒng)一監(jiān)聽蛹批。

  • 其中Future和Stream只做了常用的方法和函數(shù)的介紹撰洗,更詳細(xì)的會在之后依次給大家做下總結(jié)。

到這里大概把Dart中經(jīng)常使用的語法和屬性方法介紹了一遍腐芍,有錯誤或者理解不到位的地方差导,可以提出,共同進(jìn)步猪勇。

Dart相比Java和JavaScript還是有許多優(yōu)點有優(yōu)勢的设褐,Dart既能進(jìn)行服務(wù)端腳本、APP開發(fā)、web開發(fā)助析,但是生態(tài)目前不足犀被,不過Flutter目前火熱,相信生態(tài)之后會越來越好外冀。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末寡键,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子雪隧,更是在濱河造成了極大的恐慌西轩,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脑沿,死亡現(xiàn)場離奇詭異遭商,居然都是意外死亡,警方通過查閱死者的電腦和手機捅伤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巫玻,“玉大人丛忆,你說我怎么就攤上這事∪猿樱” “怎么了熄诡?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長诗力。 經(jīng)常有香客問我凰浮,道長,這世上最難降的妖魔是什么苇本? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任袜茧,我火速辦了婚禮,結(jié)果婚禮上瓣窄,老公的妹妹穿的比我還像新娘笛厦。我一直安慰自己,他們只是感情好俺夕,可當(dāng)我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布裳凸。 她就那樣靜靜地躺著,像睡著了一般劝贸。 火紅的嫁衣襯著肌膚如雪姨谷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天映九,我揣著相機與錄音梦湘,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛践叠,可吹牛的內(nèi)容都是我干的言缤。 我是一名探鬼主播,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼禁灼,長吁一口氣:“原來是場噩夢啊……” “哼管挟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起弄捕,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤僻孝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后守谓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體穿铆,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年斋荞,在試婚紗的時候發(fā)現(xiàn)自己被綠了荞雏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡平酿,死狀恐怖凤优,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蜈彼,我是刑警寧澤筑辨,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站幸逆,受9級特大地震影響棍辕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜还绘,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一楚昭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拍顷,春花似錦哪替、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至爱沟,卻和暖如春帅霜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背呼伸。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工身冀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留钝尸,地道東北人。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓搂根,卻偏偏與公主長得像珍促,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子剩愧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,870評論 2 361