Swift:訪問控制

中文文檔

一谎势、模塊和源文件

Swift 中的訪問控制模型基于模塊和源文件這兩個概念。

模塊指的是獨立的代碼單元像捶,框架或應用程序會作為一個獨立的模塊來構(gòu)建和發(fā)布坏瞄。在 Swift 中,一個模塊可以使用 import 關(guān)鍵字導入另外一個模塊脆栋。

在 Swift 中倦卖,Xcode 的每個 target(例如框架或應用程序)都被當作獨立的模塊處理。如果你是為了實現(xiàn)某個通用的功能椿争,或者是為了封裝一些常用方法而將代碼打包成獨立的框架怕膛,這個框架就是 Swift 中的一個模塊。當它被導入到某個應用程序或者其他框架時秦踪,框架內(nèi)容都將屬于這個獨立的模塊褐捻。

源文件就是 Swift 中的源代碼文件,它通常屬于一個模塊椅邓,即一個應用程序或者框架柠逞。盡管我們一般會將不同的類型分別定義在不同的源文件中,但是同一個源文件也可以包含多個類型景馁、函數(shù)之類的定義板壮。

二、訪問級別

Swift 為代碼中的實體提供了五種不同的訪問級別合住。這些訪問級別不僅與源文件中定義的實體相關(guān)绰精,同時也與源文件所屬的模塊相關(guān)。

  • Open 和 Public 級別可以讓實體被同一模塊源文件中的所有實體訪問透葛,在模塊外也可以通過導入該模塊來訪問源文件里的所有實體笨使。通常情況下,你會使用 Open 或 Public 級別來指定框架的外部接口僚害。Open 和 Public 的區(qū)別在后面會提到阱表。
  • Internal 級別讓實體被同一模塊源文件中的任何實體訪問,但是不能被模塊外的實體訪問贡珊。通常情況下最爬,如果某個接口只在應用程序或框架內(nèi)部使用,就可以將其設(shè)置為 Internal 級別门岔。
  • File-private 限制實體只能在其定義的文件內(nèi)部訪問爱致。如果功能的部分細節(jié)只需要在文件內(nèi)使用時,可以使用 File-private 來將其隱藏寒随。
  • Private 限制實體只能在其定義的作用域糠悯,以及同一文件內(nèi)的 extension 訪問帮坚。如果功能的部分細節(jié)只需要在當前作用域內(nèi)使用時,可以使用 Private 來將其隱藏互艾。

Open 為最高訪問級別(限制最少)试和,Private 為最低訪問級別(限制最多)。
Open 只能作用于類和類的成員纫普,它和 Public 的區(qū)別如下:

  • Public 或者其它更嚴訪問級別的類阅悍,只能在其定義的模塊內(nèi)部被繼承。
  • Public 或者其它更嚴訪問級別的類成員昨稼,只能在其定義的模塊內(nèi)部的子類中重寫节视。
  • Open 的類,可以在其定義的模塊中被繼承假栓,也可以在引用它的模塊中被繼承寻行。
  • Open 的類成員,可以在其定義的模塊中子類中重寫匾荆,也可以在引用它的模塊中的子類重寫拌蜘。

把一個類標記為 open,明確的表示你已經(jīng)充分考慮過外部模塊使用此類作為父類的影響牙丽,并且設(shè)計好了你的類的代碼了简卧。

1、訪問級別基本原則

Swift 中的訪問級別遵循一個基本原則:不可以在某個實體中定義訪問級別更低(更嚴格)的實體剩岳。

例如:

  • 一個 Public 的變量贞滨,其類型的訪問級別不能是 Internal入热,F(xiàn)ile-private 或是 Private拍棕。因為無法保證變量的類型在使用變量的地方也具有訪問權(quán)限。
  • 函數(shù)的訪問級別不能高于它的參數(shù)類型和返回類型的訪問級別勺良。因為這樣就會出現(xiàn)函數(shù)可以在任何地方被訪問绰播,但是它的參數(shù)類型和返回類型卻不可以的情況。
2尚困、默認訪問級別

如果你沒有為代碼中的實體顯式指定訪問級別蠢箩,那么它們默認為 internal 級別(有一些例外情況,稍后會進行說明)事甜。因此谬泌,在大多數(shù)情況下,我們不需要顯式指定實體的訪問級別逻谦。

3掌实、單 target 應用程序的訪問級別

當你編寫一個單目標應用程序時,應用的所有功能都是為該應用服務邦马,而不需要提供給其他應用或者模塊使用贱鼻,所以我們不需要明確設(shè)置訪問級別宴卖,使用默認的訪問級別 Internal 即可。但是邻悬,你也可以使用 fileprivate 訪問或 private 訪問級別症昏,用于隱藏一些功能的實現(xiàn)細節(jié)。

4父丰、框架的訪問級別

當你開發(fā)框架時肝谭,就需要把一些對外的接口定義為 OpenPublic,以便使用者導入該框架后可以正常使用其功能础米。這些被你定義為對外的接口分苇,就是這個框架的 API。

注意
框架依然會使用默認的 internal 屁桑,也可以指定為 fileprivate 訪問或者 private 訪問級別医寿。當你想把某個實體作為框架的 API 的時候,需顯式為其指定開放訪問或公開訪問級別蘑斧。

5靖秩、單元測試 target 的訪問級別

當你的應用程序包含單元測試 target 時,為了測試竖瘾,測試模塊需要訪問應用程序模塊中的代碼沟突。默認情況下只有 openpublic 級別的實體才可以被其他模塊訪問。然而捕传,如果在導入應用程序模塊的語句前使用 @testable 特性惠拭,然后在允許測試的編譯設(shè)置(Build Options -> Enable Testability)下編譯這個應用程序模塊,單元測試目標就可以訪問應用程序模塊中所有內(nèi)部級別的實體庸论。

三职辅、訪問控制語法

通過修飾符 openpublic聂示,internal域携,fileprivateprivate 來聲明實體的訪問級別:

public class SomePublicClass {}
internal class SomeInternalClass {}
fileprivate class SomeFilePrivateClass {}
private class SomePrivateClass {}

public var somePublicVariable = 0
internal let someInternalConstant = 0
fileprivate func someFilePrivateFunction() {}
private func somePrivateFunction() {}
  • 除非專門指定鱼喉,否則實體默認的訪問級別為 internal
class SomeInternalClass {}   // 隱式 internal
var someInternalConstant = 0 // 隱式 internal

四秀鞭、自定義類型

如果想為一個自定義類型指定訪問級別,在定義類型時進行指定即可扛禽。新類型只能在它的訪問級別限制范圍內(nèi)使用锋边。例如,你定義了一個 fileprivate 級別的類编曼,那這個類就只能在定義它的源文件中使用豆巨,可以作為屬性類型、函數(shù)參數(shù)類型或者返回類型灵巧,等等搀矫。

一個類型的訪問級別也會影響到類型成員(屬性抹沪、方法、構(gòu)造器瓤球、下標)的默認訪問級別融欧。如果你將類型指定為 private 或者 fileprivate 級別,那么該類型的所有成員的默認訪問級別也會變成 private 或者 fileprivate 級別卦羡。如果你將類型指定為公開或者 internal (或者不明確指定訪問級別噪馏,而使用默認的 internal ),那么該類型的所有成員的默認訪問級別將是內(nèi)部訪問绿饵。

重點
上面提到欠肾,一個 public 類型的所有成員的訪問級別默認為 internal 級別,而不是 public 級別拟赊。如果你想將某個成員指定為 public 級別刺桃,那么你必須顯式指定。這樣做的好處是吸祟,在你定義公共接口的時候瑟慈,可以明確地選擇哪些接口是需要公開的,哪些是內(nèi)部使用的屋匕,避免不小心將內(nèi)部使用的接口公開葛碧。

public class SomePublicClass {                  // 顯式 public 類
    public var somePublicProperty = 0            // 顯式 public 類成員
    var someInternalProperty = 0                 // 隱式 internal 類成員
    fileprivate func someFilePrivateMethod() {}  // 顯式 fileprivate 類成員
    private func somePrivateMethod() {}          // 顯式 private 類成員
}

class SomeInternalClass {                       // 隱式 internal 類
    var someInternalProperty = 0                 // 隱式 internal 類成員
    fileprivate func someFilePrivateMethod() {}  // 顯式 fileprivate 類成員
    private func somePrivateMethod() {}          // 顯式 private 類成員
}

fileprivate class SomeFilePrivateClass {        // 顯式 fileprivate 類
    func someFilePrivateMethod() {}              // 隱式 fileprivate 類成員
    private func somePrivateMethod() {}          // 顯式 private 類成員
}

private class SomePrivateClass {                // 顯式 private 類
    func somePrivateMethod() {}                  // 隱式 private 類成員
}
1、元組類型

元組的訪問級別將由元組中訪問級別最嚴格的類型來決定过吻。例如进泼,如果你構(gòu)建了一個包含兩種不同類型的元組,其中一個類型為 internal纤虽,另一個類型為 private乳绕,那么這個元組的訪問級別為 private

注意
元組不同于類廓推、結(jié)構(gòu)體刷袍、枚舉翩隧、函數(shù)那樣有單獨的定義樊展。元組的訪問級別是在它被使用時自動推斷出的,而無法明確指定堆生。

2专缠、函數(shù)類型

函數(shù)的訪問級別根據(jù)訪問級別最嚴格的參數(shù)類型或返回類型的訪問級別來決定。但是淑仆,如果這種訪問級別不符合函數(shù)定義所在環(huán)境的默認訪問級別涝婉,那么就需要明確地指定該函數(shù)的訪問級別。

下面的例子定義了一個名為 someFunction() 的全局函數(shù)蔗怠,并且沒有明確地指定其訪問級別墩弯。也許你會認為該函數(shù)應該擁有默認的訪問級別 internal吩跋,但事實并非如此。事實上渔工,如果按下面這種寫法锌钮,代碼將無法通過編譯:

func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // 此處是函數(shù)實現(xiàn)部分
}

我們可以看到,這個函數(shù)的返回類型是一個元組引矩,該元組中包含兩個自定義的類梁丘。其中一個類的訪問級別是 internal,另一個的訪問級別是 private旺韭,所以根據(jù)元組訪問級別的原則氛谜,該元組的訪問級別是 private(元組的訪問級別與元組中訪問級別最低的類型一致)。

  • 因為該函數(shù)返回類型的訪問級別是 private区端,所以你必須使用 private 修飾符值漫,明確指定該函數(shù)的訪問級別:
private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // 此處是函數(shù)實現(xiàn)部分
}

將該函數(shù)指定為 publicinternal,或者使用默認的訪問級別 internal 都是錯誤的织盼,因為如果把該函數(shù)當做 publicinternal 級別來使用的話惭嚣,可能會無法訪問 private 級別的返回值。

3悔政、枚舉類型

枚舉成員的訪問級別和該枚舉類型相同晚吞,你不能為枚舉成員單獨指定不同的訪問級別。

比如下面的例子谋国,枚舉 CompassPoint 被明確指定為 public槽地,那么它的成員 NorthSouth芦瘾、East捌蚊、West 的訪問級別同樣也是 public

public enum CompassPoint {
    case North
    case South
    case East
    case West
}
原始值和關(guān)聯(lián)值

枚舉定義中的任何原始值或關(guān)聯(lián)值的類型的訪問級別至少不能低于枚舉類型的訪問級別。例如近弟,你不能在一個 internal 的枚舉中定義 private 的原始值類型缅糟。

4、嵌套類型

如果在 private 的類型中定義嵌套類型祷愉,那么該嵌套類型就自動擁有 private 訪問級別窗宦。如果在 public 或者 internal 級別的類型中定義嵌套類型,那么該嵌套類型自動擁有 internal 訪問級別二鳄。如果想讓嵌套類型擁有 public 訪問級別赴涵,那么需要明確指定該嵌套類型的訪問級別。

五订讼、子類

子類的訪問級別不得高于父類的訪問級別髓窜。例如,父類的訪問級別是 internal欺殿,子類的訪問級別就不能是 public寄纵。

此外鳖敷,你可以在符合當前訪問級別的條件下重寫任意類成員(方法、屬性程拭、構(gòu)造器哄陶、下標等)。

可以通過重寫為繼承來的類成員提供更高的訪問級別哺壶。下面的例子中屋吨,類 A 的訪問級別是 public,它包含一個方法 someMethod()山宾,訪問級別為 private至扰。類 B 繼承自類 A,訪問級別為 internal资锰,但是在類 B 中重寫了類 A 中訪問級別為 private 的方法 someMethod()敢课,并重新指定為 internal 級別。通過這種方式绷杜,我們就可以將某類中 private 級別的類成員重新指定為更高的訪問級別直秆,以便其他人使用:

public class A {
    private func someMethod() {}
}

internal class B: A {
    override internal func someMethod() {}
}
  • 我們甚至可以在子類中,用子類成員去訪問訪問級別更低的父類成員鞭盟,只要這一操作在相應訪問級別的限制范圍內(nèi)(也就是說圾结,在同一源文件中訪問父類 private 級別的成員,在同一模塊內(nèi)訪問父類 internal 級別的成員):
public class A {
    private func someMethod() {}
}

internal class B: A {
    override internal func someMethod() {
        super.someMethod()
    }
}

因為父類 A 和子類 B 定義在同一個源文件中齿诉,所以在子類 B 可以在重寫的 someMethod() 方法中調(diào)用 super.someMethod()筝野。

六、常量粤剧、變量歇竟、屬性、下標

常量抵恋、變量焕议、屬性不能擁有比它們的類型更高的訪問級別。例如弧关,你不能定義一個 public 級別的屬性盅安,但是它的類型卻是 private 級別的。同樣梯醒,下標也不能擁有比索引類型或返回類型更高的訪問級別宽堆。

如果常量腌紧、變量茸习、屬性、下標的類型是 private 級別的壁肋,那么它們必須明確指定訪問級別為 private

private var privateInstance = SomePrivateClass()
1号胚、Getter 和 Setter

常量籽慢、變量、屬性猫胁、下標的 GettersSetters 的訪問級別和它們所屬類型的訪問級別相同箱亿。

Setter 的訪問級別可以低于對應的 Getter 的訪問級別,這樣就可以控制變量弃秆、屬性或下標的讀寫權(quán)限届惋。在 varsubscript 關(guān)鍵字之前,你可以通過 fileprivate(set)菠赚,private(set)internal(set) 為它們的寫入權(quán)限指定更低的訪問級別脑豹。

注意
這個規(guī)則同時適用于存儲型屬性和計算型屬性。即使你不明確指定存儲型屬性的 GetterSetter衡查,Swift 也會隱式地為其創(chuàng)建 GetterSetter瘩欺,用于訪問該屬性的后備存儲。使用 fileprivate(set)俱饿,private(set)internal(set) 可以改變 Setter 的訪問級別,這對計算型屬性也同樣適用土居。

下面的例子中定義了一個名為 TrackedString 的結(jié)構(gòu)體,它記錄了 value 屬性被修改的次數(shù):

struct TrackedString {
    private(set) var numberOfEdits = 0
    var value: String = "" {
        didSet {
            numberOfEdits += 1
        }
    }
}
  • 如果你實例化 TrackedString 結(jié)構(gòu)體,并多次對 value 屬性的值進行修改迄损,你就會看到 numberOfEdits 的值會隨著修改次數(shù)而變化:
var stringToEdit = TrackedString()
stringToEdit.value = "This string will be tracked."
stringToEdit.value += " This edit will increment numberOfEdits."
stringToEdit.value += " So will this one."
print("The number of edits is \(stringToEdit.numberOfEdits)")
// 打印 “The number of edits is 3”

雖然你可以在其他的源文件中實例化該結(jié)構(gòu)體并且獲取到 numberOfEdits 屬性的值垮抗,但是你不能對其進行賦值液茎。這一限制保護了該記錄功能的實現(xiàn)細節(jié)滞造,同時還提供了方便的訪問方式。

你可以在必要時為 GetterSetter 顯式指定訪問級別。下面的例子將 TrackedString 結(jié)構(gòu)體明確指定為了 public 訪問級別蔑祟。結(jié)構(gòu)體的成員(包括 numberOfEdits 屬性)擁有默認的訪問級別 internal。你可以結(jié)合 publicprivate(set) 修飾符把結(jié)構(gòu)體中的 numberOfEdits 屬性的 Getter 的訪問級別設(shè)置為 public,而 Setter 的訪問級別設(shè)置為 private

public struct TrackedString {
    public private(set) var numberOfEdits = 0
    public var value: String = "" {
        didSet {
            numberOfEdits += 1
        }
    }
    public init() {}
}

七篇亭、構(gòu)造器

  • 自定義構(gòu)造器的訪問級別可以低于或等于其所屬類型的訪問級別谊却。唯一的例外是必要構(gòu)造器捕透,它的訪問級別必須和所屬類型的訪問級別相同。

  • 如同函數(shù)或方法的參數(shù),構(gòu)造器參數(shù)的訪問級別也不能低于構(gòu)造器本身的訪問級別婴噩。

1玩般、默認構(gòu)造器

Swift 會為結(jié)構(gòu)體和類提供一個默認的無參數(shù)的構(gòu)造器,只要它們?yōu)樗写鎯π蛯傩栽O(shè)置了默認初始值洒忧,并且未提供自定義的構(gòu)造器履磨。

默認構(gòu)造器的訪問級別與所屬類型的訪問級別相同,除非類型的訪問級別是 public。如果一個類型被指定為 public 級別飞蹂,那么默認構(gòu)造器的訪問級別將為 internal。如果你希望一個 public 級別的類型也能在其他模塊中使用這種無參數(shù)的默認構(gòu)造器妖胀,你只能自己提供一個 public 訪問級別的無參數(shù)構(gòu)造器芥颈。

2爬坑、結(jié)構(gòu)體默認的成員逐一構(gòu)造器

如果結(jié)構(gòu)體中任意存儲型屬性的訪問級別為 private盾计,那么該結(jié)構(gòu)體默認的成員逐一構(gòu)造器的訪問級別就是 private哥攘。否則栅葡,這種構(gòu)造器的訪問級別依然是 internal尤泽。

如同前面提到的默認構(gòu)造器欣簇,如果你希望一個 public 級別的結(jié)構(gòu)體也能在其他模塊中使用其默認的成員逐一構(gòu)造器,你依然只能自己提供一個 public 訪問級別的成員逐一構(gòu)造器鬼店。

八网棍、協(xié)議

如果想為一個協(xié)議類型明確地指定訪問級別,在定義協(xié)議時指定即可妇智。這將限制該協(xié)議只能在適當?shù)脑L問級別范圍內(nèi)被采納滥玷。

協(xié)議中的每一個要求都具有和該協(xié)議相同的訪問級別。你不能將協(xié)議中的要求設(shè)置為其他訪問級別巍棱。這樣才能確保該協(xié)議的所有要求對于任意采納者都將可用惑畴。

注意
如果你定義了一個 public 訪問級別的協(xié)議,那么該協(xié)議的所有實現(xiàn)也會是 public 訪問級別航徙。這一點不同于其他類型如贷,例如,當類型是 public 訪問級別時到踏,其成員的訪問級別卻只是 internal杠袱。

1、協(xié)議繼承

如果定義了一個繼承自其他協(xié)議的新協(xié)議窝稿,那么新協(xié)議擁有的訪問級別最高也只能和被繼承協(xié)議的訪問級別相同楣富。例如,你不能將繼承自 internal 協(xié)議的新協(xié)議定義為 public 協(xié)議伴榔。

2纹蝴、協(xié)議一致性

一個類型可以采納比自身訪問級別低的協(xié)議庄萎。例如,你可以定義一個 public 級別的類型塘安,它可以在其他模塊中使用糠涛,同時它也可以采納一個 internal 級別的協(xié)議,但是只能在該協(xié)議所在的模塊中作為符合該協(xié)議的類型使用兼犯。

采納了協(xié)議的類型的訪問級別取它本身和所采納協(xié)議兩者間最低的訪問級別忍捡。也就是說如果一個類型是 public 級別,采納的協(xié)議是 internal 級別免都,那么采納了這個協(xié)議后锉罐,該類型作為符合協(xié)議的類型時帆竹,其訪問級別也是 internal绕娘。

如果你采納了協(xié)議,那么實現(xiàn)了協(xié)議的所有要求后栽连,你必須確保這些實現(xiàn)的訪問級別不能低于協(xié)議的訪問級別险领。例如,一個 public 級別的類型秒紧,采納了 internal 級別的協(xié)議绢陌,那么協(xié)議的實現(xiàn)至少也得是 internal 級別。

注意
Swift 和 Objective-C 一樣熔恢,協(xié)議的一致性是全局的脐湾,也就是說,在同一程序中叙淌,一個類型不可能用兩種不同的方式實現(xiàn)同一個協(xié)議秤掌。

九、Extension

Extension 可以在訪問級別允許的情況下對類鹰霍、結(jié)構(gòu)體闻鉴、枚舉進行擴展。Extension 的成員具有和原始類型成員一致的訪問級別茂洒。例如孟岛,你使用 extension 擴展了一個 public 或者 internal 類型,extension 中的成員就默認使用 internal 訪問級別督勺,和原始類型中的成員一致渠羞。如果你使用 extension 擴展了一個 private 類型,則 extension 的成員默認使用 private 訪問級別智哀。

或者次询,你可以明確指定 extension 的訪問級別(例如,private extension)盏触,從而給該 extension 中的所有成員指定一個新的默認訪問級別渗蟹。這個新的默認訪問級別仍然可以被單獨指定的訪問級別所覆蓋块饺。

如果你使用 extension 來遵循協(xié)議的話,就不能顯式地聲明 extension 的訪問級別雌芽。extension 每個 protocol 要求的實現(xiàn)都默認使用 protocol 的訪問級別授艰。

1、Extension 的私有成員

擴展同一文件內(nèi)的類世落,結(jié)構(gòu)體或者枚舉淮腾,extension 里的代碼會表現(xiàn)得跟聲明在原類型里的一模一樣。也就是說你可以這樣:

  • 在類型的聲明里聲明一個私有成員屉佳,在同一文件的 extension 里訪問谷朝。
  • 在 extension 里聲明一個私有成員,在同一文件的另一個 extension 里訪問武花。
  • 在 extension 里聲明一個私有成員圆凰,在同一文件的類型聲明里訪問。

這意味著你可以像組織的代碼去使用 extension体箕,而且不受私有成員的影響专钉。例如,給定下面這樣一個簡單的協(xié)議:

protocol SomeProtocol {
    func doSomething() {}
}
  • 你可以使用 extension 來遵守協(xié)議累铅,就像這樣:
struct SomeStruct {
    private var privateVariable = 12
}

extension SomeStruct: SomeProtocol {
    func doSomething() {
        print(privateVariable)
    }
}

十跃须、泛型

泛型類型或泛型函數(shù)的訪問級別取決于泛型類型或泛型函數(shù)本身的訪問級別,還需結(jié)合類型參數(shù)的類型約束的訪問級別娃兽,根據(jù)這些訪問級別中的最低訪問級別來確定菇民。

十一、類型別名

你定義的任何類型別名都會被當作不同的類型投储,以便于進行訪問控制第练。類型別名的訪問級別不可高于其表示的類型的訪問級別。例如轻要,private 級別的類型別名可以作為 private复旬、file-privateinternal冲泥、public 或者 open 類型的別名驹碍,但是 public 級別的類型別名只能作為 public 類型的別名,不能作為 internal凡恍、file-privateprivate 類型的別名志秃。

注意
這條規(guī)則也適用于為滿足協(xié)議一致性而將類型別名用于關(guān)聯(lián)類型的情況。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嚼酝,一起剝皮案震驚了整個濱河市浮还,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌闽巩,老刑警劉巖钧舌,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件担汤,死亡現(xiàn)場離奇詭異,居然都是意外死亡洼冻,警方通過查閱死者的電腦和手機崭歧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撞牢,“玉大人率碾,你說我怎么就攤上這事∥荼耄” “怎么了所宰?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長畜挥。 經(jīng)常有香客問我仔粥,道長,這世上最難降的妖魔是什么砰嘁? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任件炉,我火速辦了婚禮勘究,結(jié)果婚禮上矮湘,老公的妹妹穿的比我還像新娘。我一直安慰自己口糕,他們只是感情好缅阳,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著景描,像睡著了一般十办。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上超棺,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天向族,我揣著相機與錄音,去河邊找鬼棠绘。 笑死裕坊,一個胖子當著我的面吹牛雪营,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼彼乌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了诅炉?” 一聲冷哼從身側(cè)響起黑滴,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赡突,沒想到半個月后对扶,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體区赵,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年浪南,在試婚紗的時候發(fā)現(xiàn)自己被綠了惧笛。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡逞泄,死狀恐怖患整,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情喷众,我是刑警寧澤各谚,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站到千,受9級特大地震影響昌渤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜憔四,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一膀息、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧了赵,春花似錦潜支、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至络断,卻和暖如春裁替,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背貌笨。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工弱判, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锥惋。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓昌腰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親净刮。 傳聞我的和親對象是個殘疾皇子剥哑,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353