Swift3.1_函數(shù)與閉包

函數(shù)

當(dāng)你定義一個(gè)函數(shù)時(shí),你可以定義一個(gè)或多個(gè)有名字和類型的值禽绪,作為函數(shù)的輸入,稱為參數(shù)洪规,也可以定義某種類型的值作為函數(shù)執(zhí)行結(jié)束時(shí)的輸出印屁,稱為返回類型。

每個(gè)函數(shù)有個(gè)函數(shù)名斩例,用來(lái)描述函數(shù)執(zhí)行的任務(wù)雄人。要使用一個(gè)函數(shù)時(shí),用函數(shù)名來(lái)調(diào)用這個(gè)函數(shù)念赶,并傳給它匹配的輸入值實(shí)參础钠。函數(shù)的實(shí)參必須與函數(shù)參數(shù)表里參數(shù)的順序一致。

函數(shù)參數(shù)與返回值

函數(shù)的定義以func作為前綴叉谜,后接方法名旗吁,后跟一對(duì)括號(hào)定義參數(shù),參數(shù)用,隔開(kāi)停局;指定函數(shù)返回類型時(shí)很钓,用返回箭頭->后跟返回類型的名稱的方式來(lái)表示。

無(wú)參數(shù)函數(shù)
func sayHelloWorld() -> String {
    return "hello, world"
}
print(sayHelloWorld())
// 打印 "hello, world"
多參數(shù)函數(shù)
func add(num1: Int, num2: Int) -> String {
    return "sum is \(num1+num2)"
}
print(add(num1: 3, num2: 5))
// 打印 "sum is 8"
無(wú)返回值函數(shù)
func say(message: String) {
    print("say \(message)")
}
say(message: "hello")
// 打印 say hello

嚴(yán)格上來(lái)說(shuō)董栽,雖然沒(méi)有返回值被定義码倦,say(message:)函數(shù)依然返回了值。沒(méi)有定義返回類型的函數(shù)會(huì)返回一個(gè)特殊的Void值锭碳。它其實(shí)是一個(gè)空的元組tuple袁稽,沒(méi)有任何元素,可以寫成()擒抛。

多重返回值函數(shù)

你可以用元組tuple類型讓多個(gè)值作為一個(gè)復(fù)合值從函數(shù)中返回推汽。

func minmax(array: [Int]) -> (min: Int, max: Int) {
    let min = array.min()!
    let max = array.max()!
    return (min, max)
}
let (min, max) = minmax(array: [2, 4, 9, 1])
print("min: \(min), max: \(max)")
// 打印 min: 1, max: 9
可選元組返回類型

如果函數(shù)返回的元組類型有可能整個(gè)元組都沒(méi)有值补疑,你可以使用可選的optional元組返回類型反映整個(gè)元組可以是nil的事實(shí)。

可選元組類型如(Int, Int)?與元組包含可選類型如(Int?, Int?)是不同的歹撒×椋可選的元組類型,整個(gè)元組是可選的栈妆,而不只是元組中的每個(gè)元素值。

func minmax(array: [Int]) -> (min: Int, max: Int)? {
    if array.count == 0 {
        return nil
    }
    let min = array.min()!
    let max = array.max()!
    return (min, max)
}
// 通過(guò)可選綁定取值
if let (min, max) = minmax(array: [2, 4, 9, 1]) {
    print("min: \(min), max: \(max)")
}

函數(shù)參數(shù)標(biāo)簽和參數(shù)名稱

每個(gè)函數(shù)參數(shù)都有一個(gè)參數(shù)標(biāo)簽argument label以及一個(gè)參數(shù)名稱parameter name厢钧。參數(shù)標(biāo)簽在調(diào)用函數(shù)的時(shí)候使用鳞尔;調(diào)用的時(shí)候需要將函數(shù)的參數(shù)標(biāo)簽寫在對(duì)應(yīng)的參數(shù)前面。參數(shù)名稱在函數(shù)的實(shí)現(xiàn)中使用早直。默認(rèn)情況下寥假,函數(shù)參數(shù)使用參數(shù)名稱來(lái)作為它們的參數(shù)標(biāo)簽。

func someFunction(firstParameterName: Int, secondParameterName: Int) {
    // firstParameterName 和 secondParameterName 代表參數(shù)中的第一個(gè)和第二個(gè)參數(shù)值
}
someFunction(firstParameterName: 1, secondParameterName: 2)

所有的參數(shù)都必須有一個(gè)獨(dú)一無(wú)二的名字霞扬。雖然多個(gè)參數(shù)擁有同樣的參數(shù)標(biāo)簽是可能的糕韧,但是一個(gè)唯一的函數(shù)標(biāo)簽?zāi)軌蚴鼓愕拇a更具可讀性。

指定參數(shù)標(biāo)簽

你可以在參數(shù)名稱前指定它的參數(shù)標(biāo)簽喻圃,中間以空格分隔:

func greet(person: String, from hometown: String) -> String {
    return "Hello \(person)! Glad you could visit from \(hometown)."
}
print(greet(person: "Bill", from: "Cupertino"))
// 打印 "Hello Bill! Glad you could visit from Cupertino."
忽略參數(shù)標(biāo)簽

如果你不希望為某個(gè)參數(shù)添加一個(gè)標(biāo)簽萤彩,可以使用一個(gè)下劃線_來(lái)代替一個(gè)明確的參數(shù)標(biāo)簽。

func someFunction(_ firstParameterName: Int, secondParameterName: Int) {
     // firstParameterName 和 secondParameterName 代表參數(shù)中的第一個(gè)和第二個(gè)參數(shù)值
}
someFunction(1, secondParameterName: 2)
默認(rèn)參數(shù)值

你可以在函數(shù)體中通過(guò)給參數(shù)賦值來(lái)為任意一個(gè)參數(shù)定義默認(rèn)值Deafult Value斧拍。當(dāng)默認(rèn)值被定義后雀扶,調(diào)用這個(gè)函數(shù)時(shí)可以忽略這個(gè)參數(shù)。

func double(num: Int, multiple: Int = 2) -> Int {
    return num * multiple
}
print(double(num: 5))
// 打印 10
可變參數(shù)

一個(gè)可變參數(shù)variadic parameter可以接受零個(gè)或多個(gè)值肆汹。函數(shù)調(diào)用時(shí)愚墓,你可以用可變參數(shù)來(lái)指定函數(shù)參數(shù)可以被傳入不確定數(shù)量的輸入值。通過(guò)在變量類型名后面加入...的方式來(lái)定義可變參數(shù)昂勉。

func sum(_ numbers: Int...) -> Int {
    var sum = 0
    for num in numbers {
        sum = sum + num
    }
    return sum
}
print(sum(2, 3, 5))

注意:一個(gè)函數(shù)最多只能擁有一個(gè)可變參數(shù)浪册。

輸入輸出參數(shù)

函數(shù)參數(shù)默認(rèn)是常量。試圖在函數(shù)體中更改參數(shù)值將會(huì)導(dǎo)致編譯錯(cuò)誤岗照。如果你想要一個(gè)函數(shù)可以修改參數(shù)的值村象,并且想要在這些修改在函數(shù)調(diào)用結(jié)束后仍然存在,那么就應(yīng)該把這個(gè)參數(shù)定義為輸入輸出參數(shù)In-Out Parameters攒至。

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temp = a;
    a = b
    b = temp
}
var a = 3
var b = 5
swapTwoInts(&a, &b)
print("a: \(a), b: \(b)")
// 打印 a: 5, b: 3

函數(shù)類型

每個(gè)函數(shù)都有種特定的函數(shù)類型煞肾,函數(shù)的類型由函數(shù)的參數(shù)類型和返回類型組成。

func addTwoInts(_ a: Int, _ b: Int) -> Int {
    return a + b
}

函數(shù)的類型是(Int, Int) -> Int嗓袱。

func printHelloWorld() {
    print("hello, world")
}

函數(shù)的類型是() -> Void籍救。

使用函數(shù)類型
var mathFunction: (Int, Int) -> Int = addTwoInts
print("Result: \(mathFunction(2, 3))")
// Prints "Result: 5"

addTwoIntsmathFunction有同樣的類型,并讓這個(gè)新變量指向addTwoInts函數(shù)”渠抹,就可以用mathFunction來(lái)調(diào)用被賦值的函數(shù)了蝙昙。

函數(shù)類型作為參數(shù)類型
func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
    print("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// 打印 "Result: 8"
函數(shù)類型作為返回類型
func stepForward(_ input: Int) -> Int {
    return input + 1
}
func stepBackward(_ input: Int) -> Int {
    return input - 1
}

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    return backward ? stepBackward : stepForward
}

嵌套函數(shù)

到目前為止本章中你所見(jiàn)到的所有函數(shù)都叫全局函數(shù)global functions闪萄,它們定義在全局域中。你也可以把函數(shù)定義在別的函數(shù)體中奇颠,稱作嵌套函數(shù)nested functions败去。

func getTwice(_ num: Int) -> () -> Int {
    let multiple = 2
    func twice () -> Int {
        return num * multiple
    }
    return twice
}

閉包

Swift的閉包表達(dá)式擁有簡(jiǎn)潔的風(fēng)格,并鼓勵(lì)在常見(jiàn)場(chǎng)景中進(jìn)行語(yǔ)法優(yōu)化烈拒,主要優(yōu)化如下:

  • 利用上下文推斷參數(shù)和返回值類型
  • 隱式返回單表達(dá)式閉包圆裕,即單表達(dá)式閉包可以省略return關(guān)鍵字
  • 參數(shù)名稱縮寫
  • 尾隨閉包語(yǔ)法

閉包表達(dá)式

閉包表達(dá)式語(yǔ)法有如下的一般形式:

{ (parameters) -> returnType in
    statements
}

sorted(by:)方法為例,

let numbers = [3, 9, 5, 1, 7]

sorted(by:)方法接受一個(gè)閉包荆几,排序閉包函數(shù)類型需為(Int, Int) -> Bool吓妆。

func backward(_ num1: Int, _ num2: Int) -> Bool {
    return num1 > num2
}

然而,以這種方式來(lái)編寫一個(gè)實(shí)際上很簡(jiǎn)單的表達(dá)式num1 > num2吨铸,確實(shí)太過(guò)繁瑣了行拢。對(duì)于這個(gè)例子來(lái)說(shuō),利用閉包表達(dá)式語(yǔ)法可以更好地構(gòu)造一個(gè)內(nèi)聯(lián)排序閉包诞吱。

let backwardNums = numbers.sorted(by: {(num1, num2) -> Bool in
    num1 > num2
})
根據(jù)上下文推斷類型

Swift可以推斷其參數(shù)和返回值的類型舟奠,sorted(by:)方法被一個(gè)Int數(shù)組調(diào)用,因此其參數(shù)必須是(Int, Int) -> Bool類型的函數(shù)房维。這意味著參數(shù)和返回值類型并不需要作為閉包表達(dá)式定義的一部分沼瘫。因?yàn)樗械念愋投伎梢员徽_推斷:

let backwardNums = numbers.sorted(by: {num1, num2 in return num1 > num2})
單表達(dá)式閉包隱式返回

單行表達(dá)式閉包可以通過(guò)省略return關(guān)鍵字來(lái)隱式返回單行表達(dá)式的結(jié)果,如上版本的例子可以改寫為:

let backwardNums = numbers.sorted(by: {num1, num2 in num1 > num2})
參數(shù)名稱縮寫

Swift自動(dòng)為內(nèi)聯(lián)閉包提供了參數(shù)名稱縮寫功能咙俩,你可以直接通過(guò) $0晕鹊,$1$2來(lái)順序調(diào)用閉包的參數(shù)暴浦,以此類推溅话。

let backwardNums = numbers.sorted(by: {$0 > $1})
運(yùn)算符方法

實(shí)際上還有一種更簡(jiǎn)短的方式來(lái)編寫上面例子中的閉包表達(dá)式。SwiftInt類型定義了關(guān)于大于號(hào)>的實(shí)現(xiàn)歌焦,其作為一個(gè)函數(shù)接受兩個(gè)Int類型的參數(shù)并返回Bool類型的值飞几。而這正好與sorted(by:)方法的參數(shù)需要的函數(shù)類型相符合。因此独撇,你可以簡(jiǎn)單地傳遞一個(gè)大于號(hào)屑墨,Swift可以自動(dòng)推斷出你想使用大于號(hào)的字符串函數(shù)實(shí)現(xiàn):

let backwardNums = numbers.sorted(by: >)

尾隨閉包

如果你需要將一個(gè)很長(zhǎng)的閉包表達(dá)式作為最后一個(gè)參數(shù)傳遞給函數(shù),可以使用尾隨閉包來(lái)增強(qiáng)函數(shù)的可讀性纷铣。尾隨閉包是一個(gè)書寫在函數(shù)括號(hào)之后的閉包表達(dá)式卵史,函數(shù)支持將其作為最后一個(gè)參數(shù)調(diào)用。在使用尾隨閉包時(shí)搜立,你不用寫出它的參數(shù)標(biāo)簽:

func myFunc(completion: () -> Void) {
    completion()
}

不使用尾隨閉包進(jìn)行函數(shù)調(diào)用:

myFunc(completion: {
    print("hello world")
})

使用尾隨閉包進(jìn)行調(diào)用:

myFunc() {
    print("hello world")
}

如果閉包表達(dá)式是函數(shù)或方法的唯一參數(shù)以躯,則當(dāng)你使用尾隨閉包時(shí),你甚至可以把()省略掉:

myFunc {
    print("hello world")
}

值捕獲

閉包可以在其被定義的上下文中捕獲常量或變量。即使定義這些常量和變量的原作用域已經(jīng)不存在忧设,閉包仍然可以在閉包函數(shù)體內(nèi)引用和修改這些值刁标。

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementer() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementer
}

如果我們單獨(dú)考慮嵌套函數(shù)incrementer(),會(huì)發(fā)現(xiàn)它有些不同尋常:

func incrementer() -> Int {
    runningTotal += amount
    return runningTotal
}

incrementer()函數(shù)并沒(méi)有任何參數(shù)址晕,但是在函數(shù)體內(nèi)訪問(wèn)了 runningTotalamount變量膀懈。這是因?yàn)樗鼜耐鈬瘮?shù)捕獲了runningTotalamount變量的引用。捕獲引用保證了runningTotalamount變量在調(diào)用完makeIncrementer后不會(huì)消失谨垃,并且保證了在下一次執(zhí)行incrementer函數(shù)時(shí)启搂,runningTotal依舊存在。

let incrementByTen = makeIncrementer(forIncrement: 10)

incrementByTen()
// 返回的值為10
incrementByTen()
// 返回的值為20
incrementByTen()
// 返回的值為30

Swift閉包可以在其被定義的上下文中捕獲常量或變量刘陶,而Objective-C需要使用__block捕獲上下文中常量或變量胳赌;所以閉包不同于block

閉包是引用類型

上面的例子中易核,`incrementByTen是常量匈织,但是這些常量指向的閉包仍然可以增加其捕獲的變量的值浪默。這是因?yàn)楹瘮?shù)和閉包都是引用類型牡直。

無(wú)論你將函數(shù)或閉包賦值給一個(gè)常量還是變量,你實(shí)際上都是將常量或變量的值設(shè)置為對(duì)應(yīng)函數(shù)或閉包的引用纳决。上面的例子中碰逸,指向閉包的引用incrementByTen是一個(gè)常量,而并非閉包內(nèi)容本身阔加。

解決閉包引起的循環(huán)強(qiáng)引用

Swift有如下要求:只要在閉包內(nèi)使用self的成員饵史,就要用self.someProperty或者self.someMethod()(而不只是somePropertysomeMethod())。這提醒你可能會(huì)一不小心就捕獲了self胜榔,造成循環(huán)強(qiáng)引用胳喷。

定義捕獲列表

捕獲列表中的每一項(xiàng)都由一對(duì)元素組成,一個(gè)元素是weakunowned關(guān)鍵字夭织,另一個(gè)元素是類實(shí)例的引用(例如self)或初始化過(guò)的變量(如delegate = self.delegate!)吭露。這些項(xiàng)在方括號(hào)中用逗號(hào)分開(kāi)。

如果閉包有參數(shù)列表和返回類型尊惰,把捕獲列表放在它們前面:

lazy var someClosure: (Int, String) -> String = {
    [unowned self, weak delegate = self.delegate!] (index: Int, stringToProcess: String) -> String in
    // 這里是閉包的函數(shù)體
}

如果閉包沒(méi)有指明參數(shù)列表或者返回類型讲竿,即它們會(huì)通過(guò)上下文推斷,那么可以把捕獲列表和關(guān)鍵字in放在閉包最開(kāi)始的地方:

lazy var someClosure: Void -> String = {
    [unowned self, weak delegate = self.delegate!] in
    // 這里是閉包的函數(shù)體
}

注意:

在閉包和捕獲的實(shí)例總是互相引用并且總是同時(shí)銷毀時(shí)弄屡,將閉包內(nèi)的捕獲定義為無(wú)主引用题禀。

如果被捕獲的引用絕對(duì)不會(huì)變?yōu)閚il,應(yīng)該用無(wú)主引用膀捷,而不是弱引用迈嘹。

逃逸閉包

當(dāng)一個(gè)閉包作為參數(shù)傳到一個(gè)函數(shù)中,但是這個(gè)閉包在函數(shù)返回之后才被執(zhí)行全庸,我們稱該閉包從函數(shù)中逃逸江锨。當(dāng)你定義接受閉包作為參數(shù)的函數(shù)時(shí)吃警,你可以在參數(shù)名之前標(biāo)注@escaping,用來(lái)指明這個(gè)閉包是允許逃逸出這個(gè)函數(shù)的啄育。

一種能使閉包逃逸出函數(shù)的方法是酌心,將這個(gè)閉包保存在一個(gè)函數(shù)外部定義的變量中桩砰。舉個(gè)例子唐全,很多啟動(dòng)異步操作的函數(shù)接受一個(gè)閉包參數(shù)作為completion handler。這類函數(shù)會(huì)在異步操作開(kāi)始之后立刻返回昧绣,但是閉包直到異步操作結(jié)束后才會(huì)被調(diào)用氓英。在這種情況下侯勉,閉包需要“逃逸”出函數(shù),因?yàn)殚]包需要在函數(shù)返回之后被調(diào)用铝阐。例如:

var completionHandlers: [() -> Void] = []
func escapingClosureFunc(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

將一個(gè)閉包標(biāo)記為@escaping意味著你必須在閉包中顯式地引用self址貌。

自動(dòng)閉包

自動(dòng)閉包是一種自動(dòng)創(chuàng)建的閉包,用于包裝傳遞給函數(shù)作為參數(shù)的表達(dá)式徘键。這種閉包不接受任何參數(shù)练对,當(dāng)它被調(diào)用的時(shí)候,會(huì)返回被包裝在其中的表達(dá)式的值吹害。這種便利語(yǔ)法讓你能夠省略閉包的花括號(hào)螟凭,用一個(gè)普通的表達(dá)式來(lái)代替顯式的閉包。

自動(dòng)閉包讓你能夠延遲求值它呀,因?yàn)橹钡侥阏{(diào)用這個(gè)閉包螺男,代碼段才會(huì)被執(zhí)行。延遲求值對(duì)于那些有副作用和高計(jì)算成本的代碼來(lái)說(shuō)是很有益處的纵穿,因?yàn)樗沟媚隳芸刂拼a的執(zhí)行時(shí)機(jī)下隧。下面的代碼展示了閉包如何延時(shí)求值。

var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
print(customersInLine.count)
// 打印出 "5"

let customerProvider = { customersInLine.remove(at: 0) }
print(customersInLine.count)
// 打印出 "5"

print("Now serving \(customerProvider())!")
// Prints "Now serving Chris!"
print(customersInLine.count)
// 打印出 "4"
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谓媒,一起剝皮案震驚了整個(gè)濱河市淆院,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌篙耗,老刑警劉巖迫筑,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異宗弯,居然都是意外死亡脯燃,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門蒙保,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)辕棚,“玉大人,你說(shuō)我怎么就攤上這事∈藕浚” “怎么了扁瓢?”我有些...
    開(kāi)封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)补君。 經(jīng)常有香客問(wèn)我引几,道長(zhǎng),這世上最難降的妖魔是什么挽铁? 我笑而不...
    開(kāi)封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任伟桅,我火速辦了婚禮,結(jié)果婚禮上叽掘,老公的妹妹穿的比我還像新娘楣铁。我一直安慰自己,他們只是感情好更扁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布盖腕。 她就那樣靜靜地躺著,像睡著了一般浓镜。 火紅的嫁衣襯著肌膚如雪溃列。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天竖哩,我揣著相機(jī)與錄音哭廉,去河邊找鬼脊僚。 笑死相叁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辽幌。 我是一名探鬼主播增淹,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼乌企!你這毒婦竟也來(lái)了虑润?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤加酵,失蹤者是張志新(化名)和其女友劉穎拳喻,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體猪腕,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡冗澈,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了陋葡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亚亲。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捌归,到底是詐尸還是另有隱情肛响,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布惜索,位于F島的核電站特笋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏巾兆。R本人自食惡果不足惜雹有,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望臼寄。 院中可真熱鬧霸奕,春花似錦、人聲如沸吉拳。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)留攒。三九已至煤惩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炼邀,已是汗流浹背魄揉。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拭宁,地道東北人洛退。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像杰标,于是被迫代替她去往敵國(guó)和親兵怯。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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