Kotlin 高階函數(shù)從未如此清晰(上)

前言

高階函數(shù)系列文章:

Kotlin 高階函數(shù)從未如此清晰(上)
Kotlin 高階函數(shù)從未如此清晰(中)
Kotlin 高階函數(shù)從未如此清晰(下) let/also/with/run/apply/repeat 一看就會

上一篇羅列過Kotlin的屬性與函數(shù)的基本知識,算是入門篇本画畅。本篇將繼續(xù)對函數(shù)的一些高級用法進(jìn)行深入分析挺尾。
通過本篇注盈,你將了解到:

1牲距、什么是函數(shù)類型?
2菱皆、Kotlin 函數(shù)類型形參聲明/實(shí)參定義
3恤浪、Kotlin 函數(shù)類型參數(shù)調(diào)用
4、匿名函數(shù)與Lambda
5、Kotlin 函數(shù)作為返回值
6严拒、Java 如何調(diào)用Kotlin 函數(shù)扬绪?

1、什么是函數(shù)類型裤唠?

Java 如何傳遞方法挤牛?

有個(gè)場景:

輸入學(xué)生的姓名、年齡种蘸,返回該學(xué)生的考試分?jǐn)?shù)墓赴。

通常我們會將它封裝為一個(gè)方法,而方法需要放在類或者接口里航瞭,最終調(diào)用時(shí)是通過類/接口的實(shí)例化對象調(diào)用該方法竣蹦,如下:

    private void testStudent(HandleStudent handleStudent) {
        float score = 0;
        if (handleStudent != null) {
            score = handleStudent.getScore("fish", 18);
        }
        System.out.println("score:" + score);
    }
    //接口
    interface HandleStudent {
        //傳入學(xué)生的姓名、年齡沧奴,返回學(xué)生的分?jǐn)?shù)
        float getScore(String name, int age);
    }

實(shí)際上我們只需要調(diào)用getScore(xx)方法痘括,為了實(shí)現(xiàn)這個(gè)目的,需要將它放到類/接口封裝滔吠,最后生成實(shí)例對象調(diào)用纲菌,多了好幾個(gè)步驟。
有沒有更簡單的方式呢疮绷?比如直接傳遞方法本身翰舌?
答案是:沒有。

因?yàn)樵贘ava 的世界里冬骚,類/接口 是一等公民椅贱,方法必須依賴于它們存在。

Kotlin 函數(shù)類型

Java 不支持方法作為方法的參數(shù)只冻,而Kotlin 卻支持函數(shù)作為函數(shù)的參數(shù)/返回值庇麦。

因?yàn)樵贙otlin 的世界里,函數(shù)是一等公民喜德,可以脫離類/接口而存在山橄。

如果你接觸過C++等語言,相信你對函數(shù)參數(shù)不會太陌生舍悯,C++里有函數(shù)指針航棱,指向的是一個(gè)函數(shù)的指針,通過該指針就可以調(diào)用其指向的函數(shù)。

還是以獲取學(xué)生分?jǐn)?shù)為例:

fun upFun1(name: String, age: Int): Float {
    return 88f
}

我們只關(guān)注該函數(shù)的輸入?yún)?shù)與返回值,并不關(guān)心該函數(shù)的名字岸更,而函數(shù)的輸入?yún)?shù)與返回值就決定了該函數(shù)的類型。
upFun1 的函數(shù)類型為:

(String, Int)->Float
輸入?yún)?shù)類型為:String 和 Int朴艰,多個(gè)參數(shù)之間用","隔開,所有參數(shù)使用()括起來
返回值類型為:Float,返回值與輸入?yún)?shù)之間使用"->"連接呵晚。

如此一來就可以表示一個(gè)函數(shù)的類型蜘腌。

2、Kotlin 函數(shù)類型形參聲明/實(shí)參定義

形參聲明

在上一篇文章里饵隙,我們有提到過:Kotlin里的引用類型包括函數(shù)這種引用類型撮珠,既然是引用,那么當(dāng)然可以作為參數(shù)傳遞了金矛,來看看如何聲明一個(gè)使用了函數(shù)作為形參的函數(shù)芯急。

//testUpFun1 接收的參數(shù)為函數(shù)類型:(String, Int)->Float
fun testUpFun1(getScore : (String, Int)->Float) {
}

傳入的形參不使用的話沒啥意義,對于函數(shù)類型驶俊,通常是調(diào)用該函數(shù)娶耍,如下:

//testUpFun1 接收的參數(shù)為函數(shù)類型:(String, Int)->String
fun testUpFun1(getScore : (String, Int)->Float) {
    var score = getScore("fish", 18)
    println("student score:$score")
}

實(shí)參定義

形參有了,當(dāng)調(diào)用testUpFun1(xx)時(shí)需要傳入實(shí)參饼酿,也就是傳入函數(shù)的定義:

fun upFun1(name: String, age: Int): Float {
    return 88f
}

定義了upFun1函數(shù)榕酒,該函數(shù)類型為:(String, Int)->Float,符合作為testUpFun1 形參的條件故俐。

3想鹰、Kotlin 函數(shù)類型參數(shù)調(diào)用

形參和實(shí)參都有了,接著來看如何將兩者結(jié)合起來药版,總結(jié)來說有如下幾種方式:


image.png

接下來一一看看三者的實(shí)現(xiàn)方式辑舷。

函數(shù)引用

當(dāng)我們定義了一個(gè)函數(shù)后,想將這個(gè)函數(shù)作為實(shí)參傳遞給另一個(gè)函數(shù)槽片,可以通過:: + 函數(shù)名 的方式傳遞何缓,官方說法叫做:函數(shù)引用。

fun upFun1(name: String, age: Int): Float {
    return 88f
}

//testUpFun1 接收的參數(shù)為函數(shù)類型:(String, Int)->String
fun testUpFun1(getScore : (String, Int)->Float) {
    var score = getScore("fish", 18)
    println("student score:$score")
}

fun main(args: Array<String>) {
    //通過函數(shù)引用調(diào)用
    testUpFun1(::upFun1)
}

如上还栓,testUpFun1 函數(shù)需要傳入一個(gè)函數(shù)類型的參數(shù)碌廓,通過"::"引用函數(shù)名即可。

變量(函數(shù)類型)

普通函數(shù)定義

既然函數(shù)引用可以當(dāng)做參數(shù)傳遞蝙云,那么它當(dāng)然可以賦值給變量氓皱,如下:

fun upFun1(name: String, age: Int): Float {
    return 88f
}
//賦值
//var varFun:(String, Int)->Float = ::upFun1
//類型推斷,可以不用寫變量類型
var varFun = ::upFun1

fun main(args: Array<String>) {
    testUpFun1(varFun)
}

此時(shí)勃刨,我們只需要把varFun 作為實(shí)參傳遞即可。
需要注意的是:Kotlin 會對變量進(jìn)行類型推斷股淡,因此我們可以省略變量類型

匿名函數(shù)

當(dāng)然了身隐,若是想要在聲明變量的同時(shí)將函數(shù)定義了,這也是可以的:

//匿名函數(shù)
//var varFun1:(String, Int)->Float = fun (name: String, age: Int):Float {
//    return 88f
//}
//類型推斷
var varFun1 = fun (name: String, age: Int):Float {
    return 88f
}
fun main(args: Array<String>) {
    testUpFun1(varFun1)
}

可以看出唯灵,我們聲明的函數(shù)沒有函數(shù)名贾铝,只有一個(gè)"fun"聲明。
此時(shí),varFun1 表示的是一個(gè)匿名函數(shù)垢揩。
同樣的因?yàn)轭愋妥詣油茖?dǎo)玖绿,可以不用寫變量類型。

Lambda 表達(dá)式

在Java 里叁巨,有時(shí)候我們會將匿名內(nèi)部類轉(zhuǎn)為Lambda形式斑匪,而Kotlin 對于Lambda的使用更廣泛了,上面的匿名函數(shù)我們可以用Lambda表示锋勺。

//Lambda 表達(dá)式
//var lambda1:(String, Int)->Float = {
//    name:String,age:Int->
//    88f
//}
//類型推導(dǎo)
var lambda1 = { name: String, age: Int ->
    88f
}
fun main(args: Array<String>) {
    testUpFun1(lambda1)
}

可以看出蚀瘸,變量作為實(shí)參傳遞,對比普通函數(shù)定義庶橱、匿名函數(shù)贮勃、Lambda 表達(dá)式三者寫法,發(fā)現(xiàn)Lambda最簡潔苏章,簡潔有時(shí)候也意味著難以理解寂嘉。

Lambda 格式以及一些風(fēng)騷寫法,我們放在下節(jié)分析

直接傳入函數(shù)體

不管是函數(shù)引用還是變量作為實(shí)參枫绅,都需要先將函數(shù)定義好泉孩,有時(shí)候函數(shù)只在一個(gè)地方使用,無需再單獨(dú)定義出來撑瞧,此時(shí)可以選擇直接將函數(shù)體當(dāng)做實(shí)參傳遞棵譬。

匿名函數(shù)

在調(diào)用函數(shù)的時(shí)候,直接傳入匿名函數(shù)作實(shí)參:

//testUpFun1 接收的參數(shù)為函數(shù)類型:(String, Int)->String
fun testUpFun1(getScore: (String, Int) -> Float) {
    var score = getScore("fish", 18)
    println("student score:$score")
}

fun main(args: Array<String>) {
    //傳入匿名函數(shù)
    testUpFun1(fun(name: String, age: Int): Float {
        return 88f
    })
}

Lambda

老樣子预伺,一般匿名函數(shù)都可以用Lambda 替代:

fun main(args: Array<String>) {
    //Lambda 表示
    testUpFun1({ name: String, age: Int ->
        88f
    }
    )
}

此時(shí)订咸,編譯器會提示你可以再優(yōu)化一下寫法:

fun main(args: Array<String>) {
    //傳入匿名函數(shù)
    testUpFun1 { name: String, age: Int ->
        88f
    }
}

我們知道函數(shù)的調(diào)用需要用"()"括起來,此時(shí)"()"都沒了酬诀,越來越簡潔了脏嚷。

4、匿名函數(shù)與Lambda

上面簡單展示了匿名函數(shù)和Lambda的使用瞒御,只是一些基本寫法父叙,尤其是Lambda還有一些風(fēng)騷寫法,接著來分析肴裙。

匿名函數(shù)

顧名思義趾唱,函數(shù)是有函數(shù)名的,如果省略了函數(shù)名那么就稱之為匿名函數(shù)蜻懦。

//定義匿名函數(shù)
var anoymous1: (String, Int) -> Float = fun(name: String, age: Int): Float {
    println("name:$name age:$age")
    return 88f
}
//自動推導(dǎo)甜癞,消除變量類型
var anoymous2 = fun(name: String, age: Int): Float {
    println("name:$name age:$age")
    return 88f
}

//調(diào)用
fun main(args: Array<String>) {
    //傳入匿名函數(shù)
    testUpFun1(fun(name: String, age: Int): Float {
        println("name:$name age:$age")
        return 88f
    })
    testUpFun1(anoymous1)
    testUpFun1(anoymous2)
}

需要注意的是:

匿名函數(shù)返回值表示的是該匿名函數(shù)本身的返回值。

Lambda

匿名函數(shù)還是不夠簡潔宛乃,此時(shí)Lambda出現(xiàn)了悠咱,分三步闡述蒸辆。

Lambda 基本結(jié)構(gòu)

var varLambda2 = { name: String, int: Int ->
    println()
    test()
    "jj"
}

以此為例,Lambda 有如下約定:

1析既、大括號"{}" 包裹內(nèi)容躬贡。
2、使用"->"連接參數(shù)與實(shí)現(xiàn)體眼坏。
3拂玻、"->"左邊表示參數(shù)列表,參數(shù)間使用","分割空骚。
4纺讲、"->"右邊表示實(shí)現(xiàn)體,多個(gè)語句分行表示囤屹。
5熬甚、如果沒有參數(shù)列表,那么"->"可以省略
6肋坚、Lambda 無需"return"關(guān)鍵字乡括,最后一行默認(rèn)表示返回值(如例子中"jj"表示Lambda返回了String類型

變量接收Lambda

//完整寫法
var varLambda1:(String, Int)->Float = { name: String, age: Int ->
    println("student name:$name age:$age")
    88f
}

因?yàn)樽詣油茖?dǎo)類型,因此可以省略變量類型:

//省略類型
var varLambda1 = { name: String, age: Int ->
    println("student name:$name age:$age")
    88f
}

當(dāng)然智厌,非得要類型的話诲泌,還可以這么寫:

//Lambda里省略了參數(shù)類型,因?yàn)?="之前已經(jīng)聲明了
var varLambda1: (String, Int) -> Float = { name, age ->
    println("student name:$name age:$age")
    88f
}

函數(shù)調(diào)用傳入Lambda

接下來通過不同的case由淺入深演示Lambda各種風(fēng)騷寫法铣鹏。

第一種Case:
將之前的testUpFun1 改造一下敷扫,新增一個(gè)參數(shù),如下:

//testUpFun1 接收的參數(shù)為函數(shù)類型:(String, Int)->String
fun testUpFun1(getScore: (String, Int) -> Float) {
    var score = getScore("fish", 18)
    println("student score:$score")
}

//改造后
fun testUpFun2(getScore: (String, Int) -> Float, needDelay:Boolean) {
    if (needDelay)
        println("delay...")
    var score = getScore("fish", 18)
    println("student score:$score")
}

testUpFun2 函數(shù)有兩個(gè)參數(shù)诚卸,一個(gè)是函數(shù)類型葵第,另一個(gè)是Boolean。
接著來看看如何調(diào)用testUpFun2 函數(shù)合溺,我們以直接傳入函數(shù)體為例:

fun main2(args : Array<String>) {
    testUpFun2({ name: String, age: Int ->
        println("name:$name age:$age")
        88f
    }, true
    )
}

第二種Case:
我們再變一下testUpFun2 參數(shù)卒密,函數(shù)類型和Boolean交換位置:

fun testUpFun3( needDelay: Boolean, getScore: (String, Int) -> Float) {
    if (needDelay)
        println("delay...")
    var score = getScore("fish", 18)
    println("student score:$score")
}

調(diào)用如下:

fun main3(args: Array<String>) {
    testUpFun3(true, { name: String, age: Int ->
        println("name:$name age:$age")
        88f
    }
    )
}

此時(shí),編譯器會提示你可以將"{}"整體提取出來放在"()"括號后棠赛,如下:

fun main3(args: Array<String>) {
    testUpFun3(true
    ) { name: String, age: Int ->
        println("name:$name age:$age")
        88f
    }
}

這是Lambda的一個(gè)約定:

如果Lambda 作為函數(shù)的最后一個(gè)參數(shù)哮奇,那么Lambda可以提取到"()"外展示。

第三種Case:
再對testUpFun3 參數(shù)做調(diào)整睛约,只保留一個(gè)函數(shù)類型的參數(shù):

//定義
fun testUpFun4(getScore: (String, Int) -> Float) {
    var score = getScore("fish", 18)
    println("student score:$score")
}
//調(diào)用
fun main4(args: Array<String>) {
    testUpFun4(
    ) { name: String, age: Int ->
        println("name:$name age:$age")
        88f
    }
}

同樣的編譯器會提示可以將"()"省略鼎俘,如下:

fun main4(args: Array<String>) {
    //省略"()"
    testUpFun4 { name: String, age: Int ->
        println("name:$name age:$age")
        88f
    }
}

這是Lambda的一個(gè)約定:

如果Lambda 作為函數(shù)的唯一參數(shù),那么調(diào)用函數(shù)"()"可以省略辩涝。

第四種Case:
這次不修改testUpFunX而芥,我們修改Lambda表達(dá)式的入?yún)ⅲ臑椋?/p>

//單參數(shù)
fun testUpFun5(getScore: (String) -> Float) {
    var score = getScore("fish")
    println("student score:$score")
}
調(diào)用如下:
fun main5(args: Array<String>) {
    ////省略"()"
    testUpFun5  { name: String ->
        println("name:$name")
        88f
    }
}

此時(shí)膀值,可以寫成如下方式:

fun main5(args: Array<String>) {
    ////省略"()"
    testUpFun5  {
        //用it 替代了Lambda 的name
        println("name:$it")
        88f
    }
}

這是Lambda的一個(gè)約定:

如果Lambda 入?yún)⒅挥幸粋€(gè)棍丐,那么可以省略"->"以及入?yún)⒘斜恚⒃趯?shí)現(xiàn)體里用it 指代這個(gè)唯一的參數(shù)沧踏。

第五種Case:
Lambda 有1個(gè)入?yún)⒖梢杂?it"指代歌逢,Lambda 沒有入?yún)⒛兀?/p>

//無參數(shù)
fun testUpFun6(getScore: () -> Float) {
    var score = getScore()
    println("student score:$score")
}
fun main6(args: Array<String>) {
    ////省略"()"
    testUpFun6 {
        println("name")
        88f
    }
}

可以看出,此時(shí)只需要"{}"括起來即可翘狱。
這是Lambda的一個(gè)約定:

如果Lambda 沒有入?yún)⒚匕福敲纯梢允÷?->"以及入?yún)⒘斜怼?/p>

注:此時(shí)在Lambda里不能使用"it",因?yàn)樗緵]入?yún)ⅰ?/em>

以上就是Kotlin Lambda 常用的一些變換規(guī)則潦匈。

5阱高、Kotlin 函數(shù)作為返回值

定義函數(shù):

fun testUpFun7(getScore: (String) -> Unit): (Boolean, Int) -> String {
    //調(diào)用函數(shù)
    var score = getScore("fish")
    println("student score:$score")

    //返回函數(shù),Lambda表示
    return { need: Boolean, age: Int ->
        println("need:$need  age:$age")
        "fish"
    }
}

調(diào)用:

fun main7(args: Array<String>) {
    ////省略"()"
    var testReturn = testUpFun7 {
        println("name:$it")
    }
    //調(diào)用
    testReturn(true, 5)
}

只要掌握了高階函數(shù)的傳參茬缩,返回值也不在話下赤惊,此處就不展開細(xì)說了。

6凰锡、Java 如何調(diào)用Kotlin 函數(shù)未舟?

以上都是Kotlin 調(diào)用 Kotlin,來看Java 如何調(diào)用Kotlin的高階函數(shù)掂为。
還是以如下函數(shù)為例:

fun testUpFun3(needDelay: Boolean, getScore: (String, Int) -> Float) {
    if (needDelay)
        println("delay...")
    var score = getScore("fish", 18)
    println("student score:$score")
}

在Java里調(diào)用:

    private void testKotlin() {
        UpFunKt.testUpFun3(true, new Function2<String, Integer, Float>() {
            @Override
            public Float invoke(String s, Integer integer) {
                return null;
            }
        });
    }

可以看出testUpFun3里的函數(shù)類型參數(shù)轉(zhuǎn)化為了Function2 的實(shí)例裕膀,F(xiàn)unction2 為何方神圣?


image.png

實(shí)際上就是Kotlin 里為了兼容Java 調(diào)用定義了一堆接口勇哗,這些接口標(biāo)明了入?yún)⒑头祷刂抵缈福琂ava 調(diào)用時(shí)需要重寫invoke()方法即可,當(dāng)在Kotlin里調(diào)用對應(yīng)的函數(shù)參數(shù)時(shí)欲诺,將會調(diào)用到invoke()回到Java 代碼抄谐。
在Functions.kt里定義了23個(gè)接口:


image.png

基本上可以滿足大部分的參數(shù)需求。

小結(jié)
理解了以上內(nèi)容瞧栗,我相信大家對Lambda各種寫法都不會再陌生斯稳,如果你還是有疑惑,可能是我沒闡述明白迹恐,歡迎留言討論挣惰。
下篇將會繼續(xù)分析泛型函數(shù)、擴(kuò)展函數(shù)殴边、內(nèi)聯(lián)函數(shù)憎茂、常用的高階函數(shù)如let/run/apply 等,進(jìn)而自然過渡到協(xié)程的分析锤岸,那時(shí)再看協(xié)程就事半功倍了竖幔。

本文基于Kotlin 1.5.3,文中Demo請點(diǎn)擊

您若喜歡是偷,請點(diǎn)贊拳氢、關(guān)注募逞,您的鼓勵(lì)是我前進(jìn)的動力

持續(xù)更新中,和我一起步步為營系統(tǒng)馋评、深入學(xué)習(xí)Android/Kotlin

1放接、Android各種Context的前世今生
2、Android DecorView 必知必會
3留特、Window/WindowManager 不可不知之事
4纠脾、View Measure/Layout/Draw 真明白了
5、Android事件分發(fā)全套服務(wù)
6蜕青、Android invalidate/postInvalidate/requestLayout 徹底厘清
7苟蹈、Android Window 如何確定大小/onMeasure()多次執(zhí)行原因
8、Android事件驅(qū)動Handler-Message-Looper解析
9右核、Android 鍵盤一招搞定
10慧脱、Android 各種坐標(biāo)徹底明了
11、Android Activity/Window/View 的background
12蒙兰、Android Activity創(chuàng)建到View的顯示過
13磷瘤、Android IPC 系列
14、Android 存儲系列
15搜变、Java 并發(fā)系列不再疑惑
16采缚、Java 線程池系列
17、Android Jetpack 前置基礎(chǔ)系列
18挠他、Android Jetpack 易懂易學(xué)系列

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扳抽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子殖侵,更是在濱河造成了極大的恐慌贸呢,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,207評論 6 521
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拢军,死亡現(xiàn)場離奇詭異楞陷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)茉唉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,455評論 3 400
  • 文/潘曉璐 我一進(jìn)店門固蛾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人度陆,你說我怎么就攤上這事艾凯。” “怎么了懂傀?”我有些...
    開封第一講書人閱讀 170,031評論 0 366
  • 文/不壞的土叔 我叫張陵趾诗,是天一觀的道長。 經(jīng)常有香客問我蹬蚁,道長恃泪,這世上最難降的妖魔是什么郑兴? 我笑而不...
    開封第一講書人閱讀 60,334評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮悟泵,結(jié)果婚禮上杈笔,老公的妹妹穿的比我還像新娘。我一直安慰自己糕非,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,322評論 6 398
  • 文/花漫 我一把揭開白布球榆。 她就那樣靜靜地躺著朽肥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪持钉。 梳的紋絲不亂的頭發(fā)上衡招,一...
    開封第一講書人閱讀 52,895評論 1 314
  • 那天,我揣著相機(jī)與錄音每强,去河邊找鬼始腾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛空执,可吹牛的內(nèi)容都是我干的浪箭。 我是一名探鬼主播,決...
    沈念sama閱讀 41,300評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼辨绊,長吁一口氣:“原來是場噩夢啊……” “哼奶栖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起门坷,我...
    開封第一講書人閱讀 40,264評論 0 277
  • 序言:老撾萬榮一對情侶失蹤宣鄙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后默蚌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冻晤,經(jīng)...
    沈念sama閱讀 46,784評論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,870評論 3 343
  • 正文 我和宋清朗相戀三年绸吸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鼻弧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,989評論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惯裕,死狀恐怖温数,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蜻势,我是刑警寧澤撑刺,帶...
    沈念sama閱讀 36,649評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站握玛,受9級特大地震影響够傍,放射性物質(zhì)發(fā)生泄漏甫菠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,331評論 3 336
  • 文/蒙蒙 一冕屯、第九天 我趴在偏房一處隱蔽的房頂上張望寂诱。 院中可真熱鬧,春花似錦安聘、人聲如沸痰洒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,814評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丘喻。三九已至,卻和暖如春念颈,著一層夾襖步出監(jiān)牢的瞬間泉粉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,940評論 1 275
  • 我被黑心中介騙來泰國打工榴芳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嗡靡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,452評論 3 379
  • 正文 我出身青樓窟感,卻偏偏與公主長得像讨彼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子肌括,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,995評論 2 361

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