Android Kotlin(2)之《函數(shù)和Lambda表達(dá)式》

Android Kotlin第二篇,接下來讓我們一起認(rèn)識下kotlin里的函數(shù)和Kotlin新特性之一Lambda表達(dá)式。當(dāng)然你深入了解Kotlin的時(shí)候局装,你會發(fā)覺Kotlin函數(shù)比java函數(shù)真的強(qiáng)大很多,能節(jié)省很多,也會讓自己代碼清晰很多弹灭。
Android Kotlin系列前面會先講解Kotlin基礎(chǔ),后續(xù)才會有具體到Android內(nèi)揪垄,目前是用Android做調(diào)試測試驗(yàn)證Kotlin

一穷吮、函數(shù)

1、函數(shù)聲明
函數(shù)聲明可以不帶返回饥努,也可以帶返回捡鱼,例如:

    //帶返回的聲明
    fun test0(a0 : Int) : Int{
        return a0
    }
    //不帶返回的聲明,tes1函數(shù)等同于test2
    fun test1(a1 : Int):Unit{
    }
    //不帶返回的聲明
    fun test2(a2 : Int){
    }

與java區(qū)別:
a酷愧、java聲明驾诈,默認(rèn)是私有的函數(shù);Kotlin默認(rèn)是公有的函數(shù)
b溶浴、Kotlin函數(shù)必須有fun關(guān)鍵字
c乍迄、java返回類型在函數(shù)名前;Kotlin返回類型在方法()后后面用“:”隔開士败,如上test0函數(shù)

2闯两、函數(shù)調(diào)用
可以直接調(diào)用,例如:

FunGoKotlin().test0(1)

3、函數(shù)的參數(shù)
函數(shù)聲明時(shí)參數(shù)漾狼,可以不帶默認(rèn)值參數(shù)重慢,也可以帶默認(rèn)值參數(shù),這里與java區(qū)別比較大逊躁,我覺得這點(diǎn)比java更加強(qiáng)大和靈活伤锚,例如:

    //默認(rèn)參數(shù), b3 : Int = 10
    fun test3(a3 : Int, b3 : Int = 10, c3 : Int = 10,d3 : String = "默認(rèn)值") : Int{
        return a3+b3
    }
    //調(diào)用默認(rèn)參數(shù)
    val a3_1 : Int = test3(1)//使用默認(rèn)參數(shù)值
    val a3_2 = test3(1,2);//不使用默認(rèn)參數(shù)值
    val a3_3 = test3(1,c3 = 3, d3 = "")//假設(shè)我不想穿其中某個(gè)參數(shù)(這個(gè)參數(shù)最后一位d3),后面回去前面在賦值的時(shí)候可以使用參數(shù)“參數(shù)名稱=賦值”進(jìn)行調(diào)用函數(shù)

這里聲明函數(shù)的時(shí)候志衣,函數(shù)參數(shù)可以帶默認(rèn)值“d3 : String = "默認(rèn)值"”屯援,調(diào)用的時(shí)候也可以使用“函數(shù)名(d3=“賦值”)”指定某個(gè)參數(shù)賦值

注意:

//繼承復(fù)寫方法,override 關(guān)鍵字函數(shù)參數(shù)是不能有默認(rèn)值的
open class A {
        open fun foo(i: Int = 10) {  }
    }
    class B : A() {
        override fun foo(i: Int) {  }  // 不能有默認(rèn)值
    }

與java區(qū)別:
與java最大區(qū)別就是念脯,Kotlin是可以對參數(shù)重命名狞洋,并且可以調(diào)用參數(shù)重命名進(jìn)行賦值,而且函數(shù)的參數(shù)是可以帶有默認(rèn)值的

4绿店、單表達(dá)式函數(shù)
當(dāng)函數(shù)返回單個(gè)表達(dá)式時(shí)吉懊,可以省略花括號并且在 = 符號之后指定代碼體即可,例如;

    //單表達(dá)式函數(shù)
    fun test4(x : String) = "單表達(dá)式函數(shù)" + x
    fun test4(x : Int,y : Int) = x + y

這點(diǎn)比java強(qiáng)大

5假勿、中綴標(biāo)示方法(全新特性)
這個(gè)是java所沒有的特性
函數(shù)還可以用中綴表示法調(diào)用借嗽,當(dāng)

  • 他們是成員函數(shù)或擴(kuò)展函數(shù)
  • 他們只有一個(gè)參數(shù)
  • 他們用 infix關(guān)鍵字標(biāo)注
    讓我們看個(gè)具體例子,這樣會更加好懂一些转培。例如:
//中綴標(biāo)示方法恶导,必須要帶參數(shù)才行,而且如果只有一個(gè)參數(shù)該參數(shù)是不能設(shè)置默認(rèn)值浸须,關(guān)鍵字:infix
    infix fun Int.test5_1(x : Int) = x+1
    infix fun Int.test5_2(x : Int) : Int{ return x * 2 }
    infix fun String.test5_2(x : Int) : Int{ return x * 2 }

    fun test5(x : Int) : Int{
        when(x){
            //中綴調(diào)用如下惨寿,總結(jié)是有兩種:“xx 方法 傳值”,“xx.方法(傳值)”
            //這里提前用到了when控制流
            //也提前用到了retrun返回删窒,如果在多個(gè)控制流里裂垦,具體如果返回不加“@”,默認(rèn)是返回最近的一層控制流肌索,“@”可以指定返回到某層
            0 -> return@test5 1 test5_2 4
            1 -> return@test5 2 test5_2 4
            2 -> return@test5 1.test5_2(4)
            3 -> return@test5 "" test5_2 6
            4 -> return@test5 "".test5_2(6)
            else -> return@test5 0
        }
    }

在這里你可以更加自己的需求蕉拢,擴(kuò)展一些自己常用的方法

6、可變數(shù)量的參數(shù)(vararg)
參數(shù)前加上vararg诚亚,參數(shù)數(shù)量就可以是變化的晕换。因?yàn)樯厦嫠f的參數(shù)特性,參數(shù)是可以重新命名且指定賦值亡电,所以使得其可變數(shù)量的參數(shù)比java更加強(qiáng)大届巩,那么強(qiáng)大在何處呢硅瞧,如下:
java這樣聲明是不可以的

    public void test0(String a,String... b,String c){

    }

但是Kotlin這樣聲明完全可以

    //可變數(shù)量的參數(shù),關(guān)鍵字varargs
    //一個(gè)函數(shù)里只能有一個(gè)vararg
    fun test6(a : String,  vararg b : String, c : String) : String{return ""}
    //調(diào)用
  val log : String = test6(topFun(),"a0","a1",c = "ad")
  val log1 : String = test6(topFun(),"a0","a1",c = "ad")

7份乒、函數(shù)的作用域
在 Kotlin 中函數(shù)可以在文件頂層聲明,這意味著你不需要像一些語言如 Java、C# 或 Scala 那樣創(chuàng)建一個(gè)類來保存一個(gè)函數(shù)或辖。此外除了頂層函數(shù)瘾英,Kotlin 中函數(shù)也可以聲明在局部作用域、作為成員函數(shù)以及擴(kuò)展函數(shù)颂暇。
函數(shù)可以在文件頂層聲明,也就是說在文件里函數(shù)不一定要放在類里缺谴,可以放在外面和package一級,例如:

package com.xiaoqiang.kotlin.base

//在 Kotlin 中函數(shù)可以在文件頂層聲明耳鸯,這意味著你不需要像一些語言如 Java湿蛔、C# 或 Scala 那樣創(chuàng)建一個(gè)類來保存一個(gè)函數(shù)
fun topFun() : String{
    return "aa"
}

class FunGoKotlin {
    //調(diào)用頂層函數(shù)
    val test7 = topFun()
}

局部函數(shù)(新特性)

     //Kotlin 支持局部函數(shù),即一個(gè)函數(shù)在另一個(gè)函數(shù)內(nèi)部
    fun test6() : String{
        fun test66() : String{
            return "test66()"
        }
        val log : String = test6("a", "b0","b1",c = "ad")
        return log+","+test66()
    }

我感覺這個(gè)還是有點(diǎn)用處县爬,可以是代碼邏輯更加清晰阳啥,增加代碼可讀性

8、支持泛型函數(shù)
這個(gè)和java差不多财喳,唯一區(qū)別就是要在前面尖括號里指定泛類型

    //函數(shù)可以有泛型參數(shù)察迟,通過在函數(shù)名前使用尖括號指定。
    fun <T> test8(t : T) : T{
        return t
    }
    fun <L> test8(l : List<L>) : List<L> {
        return l
    }

9耳高、支持尾遞歸函數(shù)

    //kotlin是支持尾遞歸函數(shù)的扎瓶,這可以允許一些算法可以正常的使用循環(huán)而不是寫一個(gè)遞歸函數(shù),而且沒有內(nèi)存溢出的風(fēng)險(xiǎn)泌枪。
    // 如果一個(gè)函數(shù)用tailrec修飾符標(biāo)記就滿足了編譯器優(yōu)化遞歸的條件概荷,并用高效迅速的循環(huán)代替它。
    //當(dāng)函數(shù)被關(guān)鍵字tailrec修飾碌燕,同時(shí)滿足尾遞歸(tail recursion)的函數(shù)式編程方式的形式時(shí)乍赫,編譯器就會對代碼進(jìn)行優(yōu)化, 
    // 消除函數(shù)的遞歸調(diào)用, 產(chǎn)生一段基于循環(huán)實(shí)現(xiàn)的, 快速而且高效的代碼。
    tailrec fun findFixPoint(x: Double = 1.0): Double
            = if (x == Math.cos(x)) x else findFixPoint(Math.cos(x))

二陆蟆、Lambda表達(dá)式與高階函數(shù)

當(dāng)你學(xué)習(xí)了Lambda表達(dá)式后雷厂,你會發(fā)現(xiàn)Lambda表達(dá)式真的是一種非常簡單的方法,去定義一個(gè)匿名函數(shù)叠殷,比java能節(jié)省很多代碼,當(dāng)然越簡單也許理解起來越困難像棘,但是當(dāng)你理解了后,你會發(fā)現(xiàn)真的很好用壶冒,它能避免我們?nèi)懸恍┌四承┖瘮?shù)的抽象類火災(zāi)接口缕题,然后在類中去實(shí)現(xiàn)它們。在Kotlin瘪松,我們把一個(gè)函數(shù)作為另外一個(gè)函數(shù)的參數(shù)墅诡。

1壳嚎、lambda表達(dá)式

Lambda表達(dá)式的完整語法形式,例如下:

val sum = { x: Int, y: Int -> x + y }

lambda表達(dá)式總是被大括號擴(kuò)著末早,參數(shù)聲明在大括號內(nèi),函數(shù)體在 ->符號之后然磷。
其實(shí)這個(gè)調(diào)用起來更像是函數(shù)焙糟,直接sum(x,y),所有Kotlin允許我們這樣來寫Lambda表達(dá)式:

val sum1 : (Int, Int) -> Int = { x, y -> x + y }

這樣看起來和函數(shù)很像
那么對應(yīng)的返回值呢样屠?有是什么穿撮。如果返回值類型是Unit,可以

val sum2 : (Int,Int) -> Unit = {x,y -> Unit}

如果返回值類型確定不是Unit痪欲,默認(rèn)返回值是 -> 后函數(shù)體中最后一個(gè)表達(dá)式視為返回值悦穿,例如:

val sum3 : (Int, Int) -> Int = { x,y ->
            val temp = x + y
            temp * 2//這個(gè)視為最后返回值
        }

單個(gè)參數(shù)的隱式名稱(it)
當(dāng)然Kotlin還給我們提供了特殊約定,特殊情況下還可以進(jìn)一步減少代碼业踢,如果Lambda表達(dá)式只有一個(gè)參數(shù)值時(shí)栗柒,我們可以使用it來代替單個(gè)參數(shù),視為隱式名稱知举,例如;

val sum4 : (Int) -> Int = { it * 10 }

看到這里瞬沦,我想你會發(fā)現(xiàn)Lambda表達(dá)式基本上沒有指明返回類型,而是自動(dòng)推斷出類型雇锡。如果你想指明返回類型的話逛钻,你可以使用匿名函數(shù)
匿名函數(shù)
匿名函數(shù),沒有名字锰提,其他語法和常規(guī)函數(shù)類似曙痘。舉個(gè)具體實(shí)例吧:

    //匿名函數(shù)
    val test13 = fun(x : Int, y : Int):Int {  return x + y }
    //調(diào)用匿名函數(shù)
    val test14 = test13(1,2)

看到這里,我相信大家對lambda表達(dá)式有了一定了解

2立肘、高階函數(shù)

高階函數(shù)是將函數(shù)用作參數(shù)或返回值的函數(shù)边坤。我覺得這個(gè)非常有用,而且很好理解谅年,有一個(gè)例子很好解釋:

fun <T> lock(lock: Lock, body: () -> T): T {
        lock.lock()
        try {
            return body()
        }
        finally {
            lock.unlock()
        }
    }

body擁有函數(shù)類型茧痒, 所以它應(yīng)該是一個(gè)不帶參數(shù)并且返回 T類型值的函數(shù)。 它在 try-代碼塊內(nèi)部調(diào)用融蹂、被 lock保護(hù)旺订,其結(jié)果由lock()函數(shù)返回弄企。可能剛剛開始比較難理解耸峭,我們還是一起看看幾個(gè)實(shí)例桩蓉,會讓我們更加好理解一些淋纲,例如:
實(shí)例一

    //接受另一個(gè)函數(shù)作為參數(shù)的函數(shù)劳闹,我們必須為該參數(shù)指定函數(shù)類型
    fun <T> max(collection: Collection<T>, less: (T, T) -> Boolean): T? {
        var max: T? = null
        for (it in collection)
            if (max == null || less(max, it))
                max = it
        return max
    }

less就是你要傳遞的函數(shù)參數(shù),那么如何使用呢洽瞬,你不要小瞧上面的函數(shù)哦本涕!接下里讓我看看有哪些使用:

fun test10(a : Int) : String{
        val numbers : List<Int> = mutableListOf(17,12,5,67,3,10)
        var stings : List<String> = arrayListOf("asd","dd","a","dddd")
        var times : List<String> = arrayListOf("15:00:01","15:00:00","4:10:00","17:00:00")

        fun dateScale(date1 : String, date2 : String) : Boolean{
            val df = SimpleDateFormat("HH:mm:ss")//創(chuàng)建日期轉(zhuǎn)換對象HH:mm:ss為時(shí)分秒,年月日為yyyy-MM-dd
            val dt1 = df.parse(date1)//將字符串轉(zhuǎn)換為date類型
            val dt2 = df.parse(date2)
            if (dt1.getTime() > dt2.getTime())
            //比較時(shí)間大小,如果dt1大于dt2
            {
                return true
            }else{
                return false
            }
        }

        when(a){
            0 -> {
                //求Int集合里最大值伙窃,返回最大值
                return@test10 max(numbers, {x,y -> x>y}).toString()
            }
            1 -> {
                //求Int集合里最小值菩颖,返回最小值
                return@test10 max(numbers, {x,y -> x<y}).toString()
            }
            2 -> {
                //求字符串集合里長度最長的值,返回長度最長的字符
                return@test10 max(stings, {x,y -> x.length>y.length}).toString()
            }
            3 -> {
                //甚至你可以把你需要做的一些操作放在一個(gè)函數(shù)里進(jìn)行調(diào)用为障,例如:dateScale(x,y)
                //求時(shí)間集合里最小時(shí)間晦闰,返回最小時(shí)間
                return@test10 max(times, {x,y -> dateScale(x,y)}).toString()
            }
            //當(dāng)然你還可以實(shí)現(xiàn)很多很多,是不是感覺比java更加簡潔和易懂啊鳍怨,而且非常非常的節(jié)省代碼呻右,說實(shí)話我是喜歡上Kotlin風(fēng)格
            else -> return@test10 ""
        }
    }

哈哈,有沒有發(fā)現(xiàn)真的比java能節(jié)省很多代碼鞋喇,如果你想用java實(shí)現(xiàn)上面方法声滥,當(dāng)然也可以實(shí)現(xiàn),只是你會發(fā)現(xiàn)java沒有Kotlin把代碼分析的如此清晰侦香,其中max方法你完全不用改變
示例二
上面返回的是單個(gè)值落塑,那么我是否可以寫個(gè)公共函數(shù)用來返回滿足條件的集合呢,當(dāng)然可以罐韩,只需要對max稍作修改憾赁,如下:

    fun <T> meetCons(collection: Collection<T>, less: (T) -> Boolean): List<T?> {
        val tmp: MutableList<T?> = mutableListOf()
        for (it in collection)
            if (less(it))
                tmp.add(it)
        return tmp
    }

這樣,你就可以對集合進(jìn)行指定篩選出你需要的集合了散吵,調(diào)用:

    fun test11() : String {
        val stings : List<String> = arrayListOf("asd","dd","ass","dddd","125")
        //返回所有字符長度為3的集合
        //你可以這樣返回
//        return meetCons(stings,less = {x -> x.length == 3}).toString()
        //當(dāng)然你也可以省去less =
        return meetCons(stings){x -> x.length == 3}.toString()
    }

示例三
上面我將集合作為參數(shù)進(jìn)行傳遞缠沈,那么是否可以對集合進(jìn)行添加類似擴(kuò)展函數(shù)呢,答案是肯定错蝴。
我們將Collection<T>拿到方法名前洲愤,就相當(dāng)于對Collection<T>進(jìn)行擴(kuò)展了,當(dāng)然返回值啥地你都可與自由的擴(kuò)展了顷锰,是不是覺得很神奇和好用柬赐,例如:

    fun <T> Collection<T>.meetCons(less: (T) -> Boolean): Collection<T?> {
        val tmp: MutableList<T?> = mutableListOf()
        for (it in this)
            if (less(it))
                tmp.add(it)
        return tmp
    }

那么如何調(diào)用呢,和擴(kuò)展函數(shù)類似調(diào)用方法官紫,例如;

fun test12() : String {
        val stings : List<String> = arrayListOf("asd","dd","ass","dddd","125")

        //閉包
        var sum = ""
        stings.filter { it.length == 3 }.forEach {
            sum += it
        }

        //返回所有字符長度為3的集合
        //我們可以這樣返回
//        return stings.meetCons{x -> x.length == 3}.toString()
        //當(dāng)然只有一個(gè)參數(shù)的時(shí)候肛宋,kotlin是有個(gè)約定的州藕,使用it代替單個(gè)參數(shù),這樣更加簡潔
        return stings.meetCons{ it.length == 3 }.toString() + ">>" + sum
    }

上面調(diào)用里有閉包調(diào)用酝陈,Lambda 表達(dá)式或者匿名函數(shù)可以訪問其 閉包 床玻,即在外部作用域中聲明的變量。 與 Java 不同的是可以修改閉包中捕獲的變量
匿名函數(shù)
匿名函數(shù)沉帮,沒有名字锈死,其他語法和常規(guī)函數(shù)類似,例如:

    //匿名函數(shù)
    val test13 = fun(x : Int, y : Int):Int {  return x + y }
    //調(diào)用匿名函數(shù)
    val test14 = test13(1,2)
    //匿名函數(shù)可以省略返回類型穆壕,類型會自動(dòng)推斷
    val test15 = fun(x : Int, y : Int) = x + y 

內(nèi)聯(lián)函數(shù)(inline待牵、noinline)

使用高階函數(shù)會帶來一些運(yùn)行時(shí)的效率損失:每一個(gè)函數(shù)都是一個(gè)對象,并且會捕獲一個(gè)閉包喇勋。 即那些在函數(shù)體內(nèi)會訪問到的變量缨该。 內(nèi)存分配(對于函數(shù)對象和類)和虛擬調(diào)用會引入運(yùn)行時(shí)間開銷。
但是在許多情況下通過內(nèi)聯(lián)化 lambda 表達(dá)式可以消除這類的開銷

    //內(nèi)聯(lián)函數(shù)
    inline fun test16(inlined: () -> Unit, noinline notInlined: () -> Unit) {
        // ……
    }

inline 修飾符影響函數(shù)本身和傳給它的 lambda 表達(dá)式:所有這些都將內(nèi)聯(lián)到調(diào)用處川背。
內(nèi)聯(lián)可能導(dǎo)致生成的代碼增加贰拿,但是如果我們使用得當(dāng)(不內(nèi)聯(lián)大函數(shù)),它將在性能上有所提升熄云,尤其是在循環(huán)中的“超多態(tài)(megamorphic)”調(diào)用處膨更。
使用inline可以是函數(shù)內(nèi)聯(lián),noinline 可以控制局部不內(nèi)聯(lián)皱碘,調(diào)用合適會在性能上有所提升询一,寫代碼的時(shí)候可以考慮這些,優(yōu)化代碼

源碼下載
這里源碼會隨著后面發(fā)布的Kotlin逐漸完善

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末癌椿,一起剝皮案震驚了整個(gè)濱河市健蕊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌踢俄,老刑警劉巖缩功,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異都办,居然都是意外死亡嫡锌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門琳钉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來势木,“玉大人,你說我怎么就攤上這事歌懒±沧溃” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵及皂,是天一觀的道長甫男。 經(jīng)常有香客問我且改,道長,這世上最難降的妖魔是什么板驳? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任又跛,我火速辦了婚禮,結(jié)果婚禮上若治,老公的妹妹穿的比我還像新娘慨蓝。我一直安慰自己,他們只是感情好直砂,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布菌仁。 她就那樣靜靜地躺著浩习,像睡著了一般静暂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谱秽,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天洽蛀,我揣著相機(jī)與錄音,去河邊找鬼疟赊。 笑死郊供,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的近哟。 我是一名探鬼主播驮审,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吉执!你這毒婦竟也來了疯淫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤戳玫,失蹤者是張志新(化名)和其女友劉穎熙掺,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咕宿,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡币绩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了府阀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缆镣。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖试浙,靈堂內(nèi)的尸體忽然破棺而出董瞻,到底是詐尸還是另有隱情,我是刑警寧澤川队,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布力细,位于F島的核電站睬澡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏眠蚂。R本人自食惡果不足惜煞聪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一妖滔、第九天 我趴在偏房一處隱蔽的房頂上張望怔匣。 院中可真熱鬧,春花似錦放刨、人聲如沸笛臣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沈堡。三九已至静陈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诞丽,已是汗流浹背鲸拥。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留僧免,地道東北人刑赶。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像懂衩,于是被迫代替她去往敵國和親撞叨。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容