【go語言學(xué)習(xí)】函數(shù)function

函數(shù)是組織好的、可重復(fù)使用的恨樟、用于執(zhí)行指定任務(wù)的代碼塊半醉。
Go語言中支持函數(shù)、匿名函數(shù)和閉包厌杜,并且函數(shù)在Go語言中屬于“一等公民”奉呛。

一夯尽、函數(shù)的聲明和調(diào)用

1、函數(shù)的聲明

Go語言中定義函數(shù)使用func關(guān)鍵字登馒,具體格式如下:

func funcName(parametername type) (output type) {
    //這里是處理邏輯代碼
    //返回多個值
    return valu
}
  • func 函數(shù)由func開始聲明
  • funcName 函數(shù)名
  • () 函數(shù)的標(biāo)志
  • parametername type 函數(shù)的參數(shù)列表匙握,參數(shù)列表指定參數(shù)的類型、順序以及個數(shù)陈轿,參數(shù)是可選圈纺,可有可無秦忿;這里的參數(shù)相當(dāng)于一個占位符,所以也叫形式參數(shù)蛾娶,當(dāng)函數(shù)被調(diào)用時灯谣,傳入的值傳遞給參數(shù),這個值被稱為實際參數(shù)
  • ouput type 返回值列表蛔琅,返回值可以由名稱和類型組成胎许,也可以只寫類型不寫名稱;返回值可以有一個或多個罗售,當(dāng)有一個返回值時可以不加()辜窑,多個返回值時必須加()
  • 函數(shù)體:實現(xiàn)指定功能的代碼塊{}里面的內(nèi)容。
2寨躁、函數(shù)的調(diào)用

可以通過funcName(parameter)的方式調(diào)用函數(shù)穆碎。調(diào)用有返回值的函數(shù)時,可以不接收其返回值职恳。

package main

import "fmt"

func main() {
    a := 10
    b := 20
    res := sum(a, b)
    fmt.Printf("%v + %v = %v", a, b, res)
}

func sum(a, b int) int {
    return a + b
}

運行結(jié)果

10 + 20 = 30

二所禀、函數(shù)的參數(shù)

1、參數(shù)的使用:

形式參數(shù):定義函數(shù)時放钦,用于接收外部傳入的數(shù)據(jù)北秽,叫做形式參數(shù),簡稱形參最筒。
實際參數(shù):調(diào)用函數(shù)時贺氓,傳給形參的實際的數(shù)據(jù),叫做實際參數(shù)床蜘,簡稱實參辙培。
函數(shù)調(diào)用:

  • A:函數(shù)名稱必須匹配
  • B:實參與形參必須一一對應(yīng):順序,個數(shù)邢锯,類型
    函數(shù)的參數(shù)中如果相鄰變量的類型相同扬蕊,則可以省略類型,如:
package main

import "fmt"

func main() {
    a := 10
    b := 20
    res := add(a, b)
    fmt.Printf("%v + %v = %v", a, b, res)
}

func add(a, b int) sum int {
    sum = a + b
    return
}
2丹擎、可變參數(shù)

可變參數(shù)是指函數(shù)的參數(shù)數(shù)量不固定尾抑。Go語言中的可變參數(shù)通過在參數(shù)名后加...來標(biāo)識。

注意:可變參數(shù)通常要作為函數(shù)的最后一個參數(shù)蒂培。

func funcName(arg ...int) {}

arg ...int告訴Go這個函數(shù)接受不定數(shù)量的參數(shù)再愈。注意,這些參數(shù)的類型全部是int护戳。在函數(shù)體中翎冲,變量arg是一個int類型的slice

3、參數(shù)的傳遞

go語言函數(shù)的參數(shù)也是存在值傳遞引用傳遞

數(shù)據(jù)類型:

  • 按照數(shù)據(jù)類型來分:

    • 基本數(shù)據(jù)類型
      int媳荒,float抗悍,string驹饺,bool
    • 復(fù)合數(shù)據(jù)類型
      arry,slice缴渊,map赏壹,struct,interface衔沼,chan...
  • 按照數(shù)據(jù)的存儲特點來分:

    • 值類型的數(shù)據(jù)蝌借,操作的是數(shù)據(jù)本身。
      int俐巴,float骨望,string,bool欣舵,arry擎鸠,struct
    • 引用類型的數(shù)據(jù),操作的數(shù)據(jù)的地址缘圈。
      slice劣光,map,chan
  • 值傳遞:值類型的數(shù)據(jù)傳遞為值傳遞糟把,傳遞的是數(shù)據(jù)的副本绢涡。修改數(shù)據(jù),對原始數(shù)據(jù)沒有影響遣疯。

package main

import "fmt"

func main() {
    arr1 := [3]int{1, 2, 3}
    fmt.Println("函數(shù)調(diào)用前雄可,數(shù)組的數(shù)據(jù):", arr1)
    fun(arr1)
    fmt.Println("函數(shù)調(diào)用后,數(shù)組的數(shù)據(jù):", arr1)
}

func fun(arr2 [3]int) {
    fmt.Println("函數(shù)中缠犀,數(shù)組的數(shù)據(jù):", arr2)
    arr2[0] = 100
    fmt.Println("函數(shù)中数苫,修改后數(shù)據(jù)的數(shù)據(jù):", arr2)
}

運行結(jié)果

函數(shù)調(diào)用前,數(shù)組的數(shù)據(jù): [1 2 3]
函數(shù)中辨液,數(shù)組的數(shù)據(jù): [1 2 3]
函數(shù)中虐急,修改后數(shù)據(jù)的數(shù)據(jù): [100 2 3]
函數(shù)調(diào)用后,數(shù)組的數(shù)據(jù): [1 2 3]
  • 引用傳遞:引用類型的數(shù)據(jù)傳遞為引用傳遞滔迈,傳遞的數(shù)據(jù)的地址止吁,導(dǎo)致多個變量指向同一塊內(nèi)存。
package main

import "fmt"

func main() {
    slice1 := []int{1, 2, 3}
    fmt.Println("函數(shù)調(diào)用前燎悍,切片的數(shù)據(jù):", slice1)
    fun(slice1)
    fmt.Println("函數(shù)調(diào)用后敬惦,切片的數(shù)據(jù):", slice1)
}

func fun(slice2 []int) {
    fmt.Println("函數(shù)中,切片的數(shù)據(jù):", slice2)
    slice2[0] = 100
    fmt.Println("函數(shù)中间涵,修改后切片的數(shù)據(jù):", slice2)
}

運行結(jié)果

函數(shù)調(diào)用前仁热,切片的數(shù)據(jù): [1 2 3]
函數(shù)中,切片的數(shù)據(jù): [1 2 3]
函數(shù)中勾哩,修改后切片的數(shù)據(jù): [100 2 3]
函數(shù)調(diào)用后抗蠢,切片的數(shù)據(jù): [100 2 3]
  • 指針傳遞:傳遞的就是數(shù)據(jù)的內(nèi)存地址。

三思劳、函數(shù)的返回值

函數(shù)的返回值:
一個函數(shù)的執(zhí)行結(jié)果迅矛,返回給函數(shù)調(diào)用處,執(zhí)行結(jié)果就叫函數(shù)的返回值潜叛。
return語句:
一個函數(shù)的定義上有返回值秽褒,那么函數(shù)中必須有return語句,將執(zhí)行結(jié)果返回給函數(shù)的調(diào)用處威兜。
函數(shù)的返回結(jié)果必須和函數(shù)定義的一致销斟,類型、數(shù)量椒舵、順序蚂踊。

  • 返回值的命名
    函數(shù)定義時可以給返回值命名,并在函數(shù)體中直接使用這些變量笔宿,最后通過return關(guān)鍵字返回犁钟。
func add(x, y int) (sum int) {
    sum = x + y
    return
}
  • 多返回值
    一個函數(shù)可以沒有返回值,也可以有一個返回值泼橘,也可以有返回多個值涝动。
func calc(x, y int) (sum, sub int) {
    sum = x + y
    sub = x - y
    return
}
  • 空白標(biāo)識符-可用來舍棄某些返回值。
func calc(x, y int) (sum, sub int) {
    sum = x + y
    sub = x - y
    return
}
_, sub := calc(10, 20) //舍棄sum

四炬灭、函數(shù)的作用域

作用域:變量可以使用的范圍醋粟。

1、全局變量

全局變量是定義在函數(shù)外部的變量重归,它在程序整個運行周期內(nèi)都有效米愿。 所有的函數(shù)都可以使用,而且共享這一份數(shù)據(jù)提前。

package main

import "fmt"

var a = 10

func main() {
    fmt.Println("test調(diào)用前吗货,main中訪問a:", a)
    test()
    fmt.Println("test調(diào)用后,main中訪問a:", a)
}

func test() {
    fmt.Println("操作前狈网,test中訪問a: ", a)
    a = 20
    fmt.Println("操作后宙搬,test中訪問a: ", a)
}

運行結(jié)果

test調(diào)用前,main中訪問a: 10
操作前拓哺,test中訪問a:  10
操作后勇垛,test中訪問a:  20
test調(diào)用后,main中訪問a: 20
2士鸥、局部變量

一個函數(shù)內(nèi)部定義的變量闲孤,就叫做局部變量
局部變量只能在定義的范圍內(nèi)訪問操作

package main

import "fmt"

func main() {
    test()
    fmt.Println("main中訪問a:", a) //undefined: a
}

func test() {
    a := 20
    fmt.Println("test中訪問a: ", a)
}

運行結(jié)果

# command-line-arguments
.\main.go:7:35: undefined: a

局部變量和全局變量重名,優(yōu)先訪問局部變量烤礁。

package main

import "fmt"

var a = 100

func main() {
    test()
}

func test() {
    a := 20
    fmt.Println("test中訪問a: ", a)
}

運行結(jié)果

test中訪問a:  20

另外讼积,if肥照,switchfor語句中聲明的變量也屬于局部變量勤众,在代碼塊外無法訪問舆绎。

五、函數(shù)的本質(zhì)

函數(shù)也是Go語言中的一種數(shù)據(jù)類型们颜,可以作為另一個函數(shù)的參數(shù)吕朵,也可以作為另一個函數(shù)的返回值。

1窥突、函數(shù)是一種數(shù)據(jù)類型
package main

import "fmt"

func main() {
    fmt.Printf("%T\n", fun1) //fun1的類型是func(int, int)
    fmt.Printf("%T\n", fun2) //fun2的類型是func(int, int) int
}

func fun1(a, b int) {
    fmt.Println(a, b)
}

func fun2(c, d int) int {
    fmt.Println(c, d)
    return 0
}

運行結(jié)果

func(int, int)
func(int, int) int
2努溃、定義函數(shù)類型的變量
var f fun(int, int) int

上面語句定義了一個變量f,它是一個函數(shù)類型阻问,這種函數(shù)接收兩個int類型的參數(shù)并且返回一個int類型的返回值梧税。
所有參數(shù)和返回值符合條件的函數(shù)可以賦值給f變量

package main

import "fmt"

func main() {
    var f func(int, int) int
    f = sum
    res := f(20, 10)
    fmt.Println("20 + 10 = ", res)
    f = sub
    res = f(20, 10)
    fmt.Println("20 - 10 = ", res)
}

func sum(a, b int) int {
    return a + b
}

func sub(a, b int) int {
    return a - b
}

運行結(jié)果

20 + 10 =  30
20 - 10 =  10

六、匿名函數(shù)

匿名函數(shù)就是沒有函數(shù)名的函數(shù)

func (參數(shù)) (返回值) {
    函數(shù)體
}

匿名函數(shù)因為沒有函數(shù)名则拷,所以沒辦法像普通函數(shù)那樣調(diào)用贡蓖,所以匿名函數(shù)需要保存到某個變量或者作為立即執(zhí)行函數(shù)。

package main

import "fmt"

func main() {
    // 將匿名函數(shù)保存到變量中
    sum := func(a, b int) int {
        return a + b
    }
    // 通過變量調(diào)用匿名函數(shù)
    res := sum(10, 20)
    fmt.Println("10 + 20 =", res)
    // 自執(zhí)行函數(shù),匿名函數(shù)定義完直接加()執(zhí)行
    func(c, d int) {
        fmt.Printf("%v + %v = %v\n", c, d, c+d)
    }(10, 20)
}

運行結(jié)果

10 + 20 = 30
10 + 20 = 30

七煌茬、高階函數(shù)

go語言支持函數(shù)式編程:

  • 將一個函數(shù)作為另一個函數(shù)的參數(shù)
  • 將一個函數(shù)作為另一個函數(shù)的返回值

1斥铺、回調(diào)函數(shù)

一個函數(shù)被作為參數(shù)傳遞給另一個函數(shù),那么這個函數(shù)就叫做回調(diào)函數(shù)坛善。
回調(diào)函數(shù)并不會馬上被調(diào)用執(zhí)行晾蜘,它會在包含它的函數(shù)內(nèi)的某個特定的時間點被“回調(diào)”(就像它的名字一樣)。

package main

import "fmt"

func main() {
    res := calc(10, 20, add)
    fmt.Println(res)
}
// add是一個func(int, int)int類型的函數(shù)眠屎,可以作為參數(shù)傳遞給calc函數(shù)
func add(a, b int) int {
    return a + b
}

// calc 高階函數(shù)剔交,它有兩個int類型的參數(shù)和一個func(int, int)int函數(shù)類型的參數(shù)
// oper 回調(diào)函數(shù),它被作為參數(shù)傳遞給calc函數(shù)
func calc(a, b int, oper func(int, int) int) int {
    res := oper(a, b)
    return res
}

運行結(jié)果

30
2改衩、函數(shù)作為返回值
package main

import "fmt"

func main() {
    fun := calc("+")
    res := fun(10, 20)
    fmt.Println("10 + 20 =", res)
}

func sum(a, b int) int {
    return a + b
}

func sub(a, b int) int {
    return a - b
}

func calc(s string) func(int, int) int {
    switch s {
    case "+":
        return sum
    case "-":
        return sub
    default:
        fmt.Println("你傳的是個啥玩意岖常!")
        return nil
    }
}

運行結(jié)果

10 + 20 = 30
3、閉包

一個外層函數(shù)葫督,有內(nèi)層函數(shù)竭鞍,該內(nèi)層函數(shù)會操作外層函數(shù)的局部變量(外層函數(shù)的參數(shù),或外層函數(shù)定義的變量)橄镜,并且該內(nèi)層函數(shù)作為外層函數(shù)的返回值偎快。
這個內(nèi)層函數(shù)和外層函數(shù)的局部變量,統(tǒng)稱為閉包結(jié)構(gòu)洽胶。

局部變量的生命周期會發(fā)生改變晒夹。正常的局部變量隨著函數(shù)的調(diào)用而創(chuàng)建,隨著函數(shù)的結(jié)束而銷毀。
但是閉包結(jié)構(gòu)的外層函數(shù)的局部變量并不會隨著外層函數(shù)的結(jié)束而銷毀丐怯,因為內(nèi)層函數(shù)還要繼續(xù)使用喷好。

package main

import "fmt"

func main() {
    fun := add()
    res := fun()
    fmt.Println("第一次調(diào)用,res=", res)
    res = fun()
    fmt.Println("第二次調(diào)用响逢,res=", res)
    res = fun()
    fmt.Println("第二次調(diào)用绒窑,res=", res)
}

func add() func() int {
    i := 0
    return func() int {
        i++
        return i
    }
}

運行結(jié)果

第一次調(diào)用棕孙,res= 1
第二次調(diào)用舔亭,res= 2
第二次調(diào)用,res= 3

七蟀俊、defer語句

defer是Go語言中的延遲執(zhí)行語句钦铺,用來添加函數(shù)結(jié)束時執(zhí)行的代碼,常用于釋放某些已分配的資源肢预、關(guān)閉數(shù)據(jù)庫連接矛洞、斷開socket連接、解鎖一個加鎖的資源烫映。
Go語言機(jī)制擔(dān)保一定會執(zhí)行defer語句中的代碼沼本。

1、延遲函數(shù)
  • 被延遲的函數(shù)锭沟,在離開所在的函數(shù)或方法時抽兆,執(zhí)行(報錯的時候也會執(zhí)行
  • 如果有很多defer語句,遵從“先進(jìn)后出”的模式
package main

import "fmt"

func main() {
    a := 1
    b := 2
    c := 3
    d := 4
    //defer a++ //a++ 是一個語句族淮,并非函數(shù)或方法辫红,程序報錯
    defer fmt.Println("defer", a)
    defer fmt.Println("defer", b)
    defer fmt.Println("defer", c)
    defer fmt.Println("defer", d)
    fmt.Println(a)
    fmt.Println(b)
    fmt.Println(c)
    fmt.Println(d)
}

運行結(jié)果

1
2
3
4
defer 4
defer 3
defer 2
defer 1
2、延遲方法

延遲并不僅僅局限于函數(shù)祝辣。延遲一個方法調(diào)用也是完全合法的贴妻。

package main

import "fmt"

// Student 學(xué)生結(jié)構(gòu)體
type Student struct {
    name string
    city string
}

func (s Student) hello() {
    fmt.Printf("我叫%v, 我來自%v。\n", s.name, s.city)
}

func main() {
    s := Student{
        name: "jack",
        city: "北京市",
    }
    defer s.hello()
    fmt.Print("大家好蝙斜,")
}

運行結(jié)果

大家好名惩,我叫jack, 我來自北京市
3、延遲參數(shù)

defer聲明時會先計算確定參數(shù)的值孕荠,defer推遲執(zhí)行的僅是其函數(shù)體娩鹉。

package main

import "fmt"

func main() {
    a := 1
    defer fun(a)
    a++
    fmt.Println("main中的a =", a)
}

func fun(a int) {
    fmt.Println("fun中的a =", a)
}

運行結(jié)果

main中的a = 2
fun中的a = 1
4、defer與return
  • 所有函數(shù)在執(zhí)行 RET 返回指令之前岛琼,都會先檢查是否存在 defer 語句底循,若存在則先逆序調(diào)用 defer 語句進(jìn)行收尾工作再退出返回;
  • 匿名返回值是在 return 執(zhí)行時被聲明槐瑞,有名返回值則是在函數(shù)聲明的同時被聲明熙涤,因此在 defer 語句中只能訪問有名返回值,而不能直接訪問匿名返回值;
  • return 其實應(yīng)該包含前后兩個步驟:第一步是給返回值賦值(若為有名返回值則直接賦值祠挫,若為匿名返回值則先聲明再賦值)那槽;第二步是調(diào)用 RET 返回指令并傳入返回值,而 RET 則會檢查 defer 是否存在等舔,若存在就先逆序插播 defer 語句骚灸,最后 RET 攜帶返回值退出函數(shù);
  • 因此慌植,??defer甚牲、return、返回值三者的執(zhí)行順序應(yīng)該是:return最先給返回值賦值蝶柿;接著 defer 開始執(zhí)行一些收尾工作丈钙;最后 RET 指令攜帶返回值退出函數(shù)。
(1)匿名返回值的情況
package main

import "fmt"

func main() {
    fmt.Println(fun1())
}

func fun1() int {
    var i int
    defer func() {
        i++
    }()
    return i
}

運行結(jié)果

0
(2)有名返回值的情況
package main

import "fmt"

func main() {
    fmt.Println(fun2())
}

func fun2() (i int) {
    defer func() {
        i++
    }()
    return i
}

運行結(jié)果

1

分析

  • fun1()int函數(shù)的返回值沒有被提前聲名交汤,其值來自于其他變量的賦值雏赦,而 defer 中修改的也是其他變量(其實該 defer 根本無法直接訪問到返回值),因此函數(shù)退出時返回值并沒有被修改芙扎。
  • fun2()(i int) 函數(shù)的返回值被提前聲名星岗,這使得 defer 可以訪問該返回值,因此在 return 賦值返回值 i 之后戒洼,defer 調(diào)用返回值 i 并進(jìn)行了修改俏橘,最后致使 return 調(diào)用 RET 退出函數(shù)后的返回值才會是 defer 修改過的值。

經(jīng)典案例

package main

import "fmt"

func main() {
    fmt.Println(f1())
    fmt.Println(f2())
    fmt.Println(f3())
    fmt.Println(f4())
}

func f1() int {
    x := 5
    defer func() {
        x++ // defer 訪問的是變量x施逾,訪問不到返回值
        // fmt.Println("f1函數(shù)defer中的x =", x) //6
    }()
    return x // 返回值 = 5     //返回5
}

func f2() (x int) {
    defer func() {
        x++ //defer 訪問x, 可以訪問返回值敷矫,在RET之前,將返回值修改為6
        // fmt.Println("f2函數(shù)defer中的x =", x) //6
    }()
    return 5 // 返回值(x) = 5   //返回6
}

func f3() (y int) {
    x := 5
    defer func() {
        x++ // defer 訪問變量x汉额,將變量x修改為6
        // fmt.Println("f3函數(shù)defer中的x =", x) //6
    }()
    return x // 返回值(y) = 5   //返回5
}
func f4() (x int) {
    defer func(x int) {
        x++ // 這里修改的defer時傳入的x(0),將其修改為1
        // fmt.Println("f4函數(shù)defer中的x =", x) //1
    }(x) // defer 語句調(diào)用時傳入x的值為int類型的默認(rèn)值0
    return 5 // 返回值(x) = 5   //返回5
}

運行結(jié)果

5
6
5
5
5曹仗、defer的作用域
  • defer 只對當(dāng)前協(xié)程有效(main 可以看作是主協(xié)程);
  • 當(dāng)任意一條(主)協(xié)程發(fā)生 panic 時蠕搜,會執(zhí)行當(dāng)前協(xié)程中 panic 之前已聲明的 defer怎茫;
  • 在發(fā)生 panic 的(主)協(xié)程中,如果沒有一個 defer 調(diào)用 recover()進(jìn)行恢復(fù)妓灌,則會在執(zhí)行完最后一個已聲明的 defer 后轨蛤,引發(fā)整個進(jìn)程崩潰;
  • 主動調(diào)用 os.Exit(int) 退出進(jìn)程時虫埂,defer 將不再被執(zhí)行祥山。
package main

import (
    "fmt"
    // "os"
)

func main() {
    fmt.Println("start")
    // panic("崩潰了")              // defer和之后的語句都不再執(zhí)行
    // os.Exit(1)                  // defer和之后的語句都不再執(zhí)行
    defer fmt.Println("defer")
    // go func() {
    //  panic("崩潰了")
    // }()                         // defer不被執(zhí)行
    // panic("崩潰了")             // defer會執(zhí)行,但后面的語句不再執(zhí)行
    fmt.Println("over")
    // os.Exit(1)                  // defer不被執(zhí)行
}

八掉伏、內(nèi)置函數(shù)

內(nèi)置函數(shù) 介紹
close 主要用來關(guān)閉channel
len 用來求長度缝呕,比如string澳窑、array、slice供常、map摊聋、channel
new 用來分配內(nèi)存,主要用來分配值類型栈暇,比如int麻裁、struct。返回的是指針
make 用來分配內(nèi)存源祈,主要用來分配引用類型煎源,比如chan、map新博、slice
append 用來追加元素到數(shù)組薪夕、slice中
panic和recover 用來做錯誤處理

panic和recover

Go語言中目前是沒有異常機(jī)制,但是使用panic/recover模式來處理錯誤赫悄。 panic可以在任何地方引發(fā),但recover只有在defer調(diào)用的函數(shù)中有效馏慨。

package main

import (
    "fmt"
)

func main() {
    fmt.Println("start")
    defer func() {
        err := recover()
        if err != nil {
            fmt.Println("recover")
            fmt.Println("活了")
        }
    }()

    panic("panic")
    fmt.Println("over")
}

運行結(jié)果

start
recover
活了
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末埂淮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子写隶,更是在濱河造成了極大的恐慌倔撞,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件慕趴,死亡現(xiàn)場離奇詭異痪蝇,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)冕房,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門躏啰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人耙册,你說我怎么就攤上這事给僵。” “怎么了详拙?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵帝际,是天一觀的道長。 經(jīng)常有香客問我饶辙,道長蹲诀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任弃揽,我火速辦了婚禮脯爪,結(jié)果婚禮上珊佣,老公的妹妹穿的比我還像新娘。我一直安慰自己披粟,他們只是感情好咒锻,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著守屉,像睡著了一般惑艇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拇泛,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天滨巴,我揣著相機(jī)與錄音,去河邊找鬼俺叭。 笑死恭取,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的熄守。 我是一名探鬼主播蜈垮,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼裕照!你這毒婦竟也來了攒发?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤晋南,失蹤者是張志新(化名)和其女友劉穎惠猿,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體负间,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡偶妖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了政溃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趾访。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖玩祟,靈堂內(nèi)的尸體忽然破棺而出腹缩,到底是詐尸還是另有隱情,我是刑警寧澤空扎,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布藏鹊,位于F島的核電站,受9級特大地震影響转锈,放射性物質(zhì)發(fā)生泄漏盘寡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一撮慨、第九天 我趴在偏房一處隱蔽的房頂上張望竿痰。 院中可真熱鬧脆粥,春花似錦、人聲如沸影涉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蟹倾。三九已至匣缘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鲜棠,已是汗流浹背肌厨。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留豁陆,地道東北人柑爸。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像盒音,于是被迫代替她去往敵國和親表鳍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355