Swift 3.0 編碼規(guī)范

花了周末的時間翻譯raywenderlich.com的Swift編碼規(guī)范(傳送門), 原文是針對寫作時Swift代碼的規(guī)范,在整理過程中刪除了部分和實際項目無關的條目。

編碼規(guī)范的目標是保證代碼的簡潔性,可讀性和可維護性。

正確性

把警告當做錯誤處理。這條規(guī)則從根本禁止了一些文法使用,如推薦使用#selector文而不是用字符串(更多請閱讀Swift 3為什么推薦使用#selector)。?


命名

使用具有描述性的名稱,并結合駝峰式命名規(guī)則給類方法和變量等命名。類別名稱(類,結構體,枚舉和協(xié)議)首字母大寫,而方法或者變量的首字母小寫。更多命名規(guī)范請查閱Apple Design Guidelines

正例

private let maximumWidgetCount = 100

class WidgetContainer {
? ? var widgetButton: UIButton ?
? ? let ?widgetHeightPercentage = 0.85
}

反例

let MAX_WIDGET_COUNT = 100
class app_widgetContainer {
? ?var wBut: UIButton
? ?let ?wHeightPct = 0.85
}

縮寫和簡寫應該要盡量避免,遵守蘋果命名規(guī)范,縮寫和簡寫中的所有字符大小寫要一致。

正例

let urlString: ?URLString
let userID: ?UserID

反例

let uRLString: ?UrlString
let userId: ?UserId

對于函數(shù)和初始化方法,建議給所有參數(shù)命名,除非上下文非常清晰,如果結合外部參數(shù)命名可以讓函數(shù)調(diào)用更易讀,要結合起來。

func dateFromString(dateString: String) -> NSDate
func convertPointAt(column column:Int, row:Int) > CGPoint
func timedAction(afterDelay delay: NSTime Interval,performaction: SKAction) ->SKAction!

//調(diào)用上述函數(shù)時如下:
dateFromString("2014-03-14")
convertPointAt(column: 42, row: 13)
timedAction(afterDelay: 1.0, perform: someOtherAction)

方法命名的時候要考慮方法體中的第一個參數(shù)的名稱。

class Counter {
? //combineWith + otherCounter
? func combineWith(otherCounter:? Counter, options: Dictionary?) { ... }
?//incrementBy + amount
? func incrementBy(amount: Int) { ... }
}

協(xié)議

根據(jù)蘋果接口設計指導準則,協(xié)議名稱用來描述一些東西是什么的時候是名詞,例如:Collection,WidgetFactory。若協(xié)議名稱用來描述能力應該以-ing, -able, ?或 -ible結尾,例如:Equatable,Resizing.

枚舉

根據(jù)Swift 3蘋果接口設計指導文檔,枚舉中的值使用“小駱駝拼寫法”命名規(guī)則

enum Shape {
? ? case rectangle
? ? case square
? ? case ?triangle
? ? case ?circle
}

類前綴?

Swift中類別(類,結構體)在編譯時會把模塊設置為默認的命名空間,所以不用為了區(qū)分類別而添加前綴,比如RW。如果擔心來自不同模塊的兩個名稱發(fā)生沖突,可以在使用時添加模塊名稱來區(qū)分,注意不要濫用模塊名稱,僅在有可能發(fā)生沖突或疑惑的場景下使用。

import SomeModule
let myClass = MyModule.UsefulClass()

委托 - Delegate

在定義委托方法時,第一個未命名參數(shù)應是委托數(shù)據(jù)源。 (為了保持參數(shù)聲明的一致性在Swift3引入的)

正例

func namePickerView(_ namePickerView: NamePickerView, didSelectName name: String)

func namePickerViewShouldReload(_ namePickerView: NamePickerView) -> Bool

反例

func didSelectName(namePicker: NamePickerViewController, name: String)

func namePickerShouldReload() -> Bool

泛型

泛型類參數(shù)應具有描述性,遵守“大駱駝命名法”。如果一個參數(shù)名沒有具體的含義,可以使用傳統(tǒng)單大寫字符,如T, ?U, 或V等。

正例

struct Stack<Element>{ ... }
func writeTo <Target: OutputStream>(to Target: inout Target)
func swap(_ a: inout T, _ b: inout T)?

反例

struct Stack<T>{ ... }
func write<target: OutputStream>?(to target: inout target)
func swap<Thing>(_ a: inout Thing, _ b: inout Thing)

語言

使用美式英語來定義接口。

正例

let color = "red"

反例

let colour = "red"


代碼組織結構

協(xié)議一致性

當一個對象要實現(xiàn)協(xié)議一致性時,推薦使用 extension 隔離協(xié)議中的方法集,這樣讓相關方法和協(xié)議集中顯示在一起,?也簡化了類支持一個協(xié)議和實現(xiàn)相關方法的流程。

正例

class MyViewcontroller: UIViewController {
? ? ? // ?方法
}

extension MyViewcontroller: UITableViewDataSource {
? ? ? // UITableViewDataSource 方法
}

extension MyViewcontroller: UIScrollViewDelegate {
? ? ? // UIScrollViewDelegate 方法
}?

反例

class MyViewcontroller: UIViewController, UITableViewDataSource, UIScrollViewDelegate {
? ? ? ?// 所有的方法
}

對于UIKit view controllers, 建議用extensions定義不同的類,按照生命周期,自定義方法,IBAction分組。

無用代碼

無用的代碼,包括Xcode生成的模板代碼和占位符注釋應該刪除,除非是有目的性的保留這些代碼。

一些方法內(nèi)只是簡單地調(diào)用了父類里面的方法也需要刪除,包括UIApplicationDelegate內(nèi)的空方法和無用方法。

正例

override func tableView(tableView: UITableView,numberOfRowsInSectionsection: Int) -> Int{
? return Database.contacts.count
}

反例

override func didReceiveMemoryWarning() {
? super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
? return 1
}

override func tableView(tableView: UITableView,numberOfRowsInSectionsection: Int) -> Int {
? return Database.contacts.count
}

最少引入

減少不必要的引入,例如引入Foundation能滿足的情況下不用引入UIKit。

間隔

縮進使用2個空格. 在Xcode的偏好設置和項目設置都可以配置。

Xcode偏好設置
項目設置

方法體的大括號和其他大括號 (if/else/switch/while等) 首括號和首行語句在同一行,尾括號新起一行。

正例

if user.isHappy {
? // xxoo
} else {
? // ooxx
}

反例

if user.isHappy
{
? // xxoo
}
else{
? // ooxx
}

方法體內(nèi)最多只有一個空行,這樣可以保持整齊和簡潔,如果需要多個空行,說明代碼需要重構。

: 左面不要空格,而右面需要保留空格,例外的是三元操作符 ? : 和空數(shù)組 [:]

正例

class TestDatabase: Database {
? ?var data: [String: CGFloat] = ["A": 1.2,"B": 3.2]
}

反例

class TestDatabase: Database {
? ?var data :[String:CGFloat] = ["A" : 1.2,"B" : 3.2]
}


注釋

當需要的時候,使用注釋來解釋闡明特定一塊代碼的用途,注釋必須保持最新,過期的注釋要及時刪除。

避免代碼中出現(xiàn)注釋塊,代碼本身應盡量起到注釋的作用,如果注釋是為了生成文檔可以例外。


類和結構體

應該使用哪一個

結構體是值類型。結構體在使用中沒有標識。一個數(shù)組包含[a, b, c]和另外一個數(shù)組包含[a, b, c]是完全一樣的,它們完全可以?互相替換,使用第一個還是使用第二個都一樣,因為它們代表的是同一個東西。這就是為什么數(shù)組是結構體。

類是引用類型。類使用的場景是需要一個標識或者需要一個特定的生命周期。假設你需要對人?抽象為一個類,因為兩個人,是兩個不同的東西。即使兩個人有同樣的名字和生日,也不能確定這兩個人是一樣的。但是人的生日是一個結構體,因為日期1950/03/03和另外一個日期1950/03/03是相同的,日期是結構體沒有唯一標示。

有時,一些事物應該定義為結構體,但是還需要兼容AnyObject或者已經(jīng)在以前的歷史版本中定義為類(NSDate,NSSet),所以盡可能的注意?類和結構體之間的區(qū)別。

類定義

下面是一個設計良好的類定義:

class Circle: Shape {
? var x: Int, y: Int
? var radius: Double
? var diameter: Double{
? ? ? get {
? ? ? ? returnradius * 2
? ? ?}
? ? ?set {? ? ?
? ? ? ? radius=newValue/2
? ? }?
}
? ?init(x: Int, y: Int, radius: Double) {
? ? ? self.x = x
? ? ? self.y = y
? ? ? self.radius = radius?
? }

?convenience init(x: Int, y: Int, diameter: Double) {
? ? ?self.init(x: x, y: y, radius: diameter/2)?
}

func describe() -> String{
? ? return"I am a circle at\(centerString())with an area of\(computeArea())"
}
override func computeArea() -> Double{
? ?return M_PI * radius * radius?
}

private func centerString()->String{
? ? return "(\(x),\(y))"
? }
}

上面的例子展示了下面的設計準則:

屬性,變量,常量和參數(shù)等在聲明定義時,其中: 符號后有空格,而: 符號前沒有空格,比如x: Int, 和Circle: Shape

如果定義多個變量/數(shù)據(jù)結構時出于相同的目的和上下文,可以定義在同一行。

縮進getter,setter的定義和屬性觀察器的定義。

不需要添加internal這樣的默認的修飾符。也不需要在重寫一個方法時添加訪問修飾符。

self的使用

為了保持簡潔,可以避免使用 self 關鍵詞,因為Swift 在訪問對象屬性和調(diào)用對象方法不需要使用 self。

不過當在構造器中需要區(qū)分屬性名和參數(shù)名時需要使用 self,還有當在在閉包表達式中引用屬性值。

class BoardLocation ?{
? ? let row: Int, column: Int
? ? init(row: Int, column: Int) ?{
? ? ? ? self.row = row
? ? ? ? self.column = column
? ? ? ? let closure = {
? ? ? ? ? ? print(self.row)? ?
? ? ? ? ?}?
? ? }
}

計算屬性

為了保持簡潔,如果一個屬性是只讀的,請忽略掉get語句。因為只有在需要定義set語句的時候,才需要get語句。

正例

var diameter: ?Double{
? ? return radius ?* ?2
}

反例

var diameter: ?Double{
? ? ?get {
? ? ? ? return radius * 2
? ? ?}
}

?Final

給那些不打算被繼承的類使用final 修飾符, ?例如:

final class Box<T> {
? ? ?let value: T
? ? ?init(_ value: T) {
? ? ? ? ?self.value = value?
? ? ?}
}


?函數(shù)聲明

在定義短函數(shù)聲明時保持在一行,一行內(nèi)包括頭括號:

func reticulateSplines(spline: [Double]) -> Bool {
? ? ?// xxoo
}

對于聲明較長的函數(shù)時,在適當?shù)奈恢脫Q行并在第二行多添加一個縮進:

func reticulateSplines(spline: [Double], adjustmentFactor: Double,? ? translateConstant:Int, ? ? ? ? ?comment:String) -> Bool {
? ? ? // ooxx
}


閉包表達式

僅在閉包表達式參數(shù)在參數(shù)列表中最后一個時,使用尾隨閉包表達式。閉包參數(shù)命名要有描述性。

正例

UIView.animateWithDuration(1.0) {
? ? ?self.myView.alpha=0
}

UIView.animateWithDuration(1.0,?
? ? ? animations: {
? ? ? ? ? ? self.myView.alpha = 0
? ? ? ?},?
? ? ? ? completion: { finish in
? ? ? ? ? ? ?self.myView.removeFromSuperview()?
? ?}
)

反例

UIView.animateWithDuration(1.0, animations: {
? ? ? self.myView.alpha=0
})

UIView.animateWithDuration(1.0,?
? ? ? ? animations: {
? ? ? ? ? ? ? self.myView.alpha = 0
? ? ? ? ? ?}) { finish in
? ? ? ? ? self.myView.removeFromSuperview()
}

當單個閉包表達式上下文清晰時,使用隱式的返回值:

attendeeList.sort { a, b in
? ? ?a > b
}

鏈式方法使用尾隨閉包會更清晰易讀,?至于如何使用空格,換行,還是使用命名和匿名參數(shù)不做具體要求。

let value = numbers.map{ $0 * 2 ?}.filter{ ?$0 % 3 == 0 }.index(of: 90)

let value=numbers
? ? ? ? ? .map{ $0 * 2 }
? ? ? ? ? .filter{ $0 > 50 }
? ? ? ? ? .map{$0 + 10}


類型

優(yōu)先使用Swift原生類型,可以根據(jù)需要使用Objective-C提供的方法,因為Swift提供了到Objective-C的橋接 。

正例

let width = 120.0 ?// Double
let widthString = (width as NSNumber).stringValue // String

反例

let width: NSNumber = 120.0 // NSNumber
let widthString: NSString=width.stringValue ?// NSString

?在 Sprite Kit ?代碼中, 使用CGFloat可以避免數(shù)據(jù)多次轉換,讓代碼更簡潔。

常量

定義常量使用 let 關鍵字,定義變量使用 var 關鍵字, 如果變量的值未來不會發(fā)生變化要使用常量。

?建議: 一個好的技巧是,使用 let 定義任何東西,只有在編譯器提出警告需要改變的時候才修改為 var 定義。

你可以使用類型屬性來定義類型常量而不是實例常量,使用static let 可以定義類型屬性常量。 這樣方式定義類別屬性整體上優(yōu)于全局常量,因為更容易區(qū)分于實例屬性. ?比如:

正例

enum Math {
? ?static let e = 2.718281828459045235360287 ?
? ?static let pi = 3.141592653589793238462643
}
radius * Math.pi * 2// ?周長

Note:?使用枚舉的好處是變量不會被無意初始化,且全局有效。

反例

let e=2.718281828459045235360287// ?污染全局命名空間
let pi=3.141592653589793238462643

radius * pi * 2// pi是實例數(shù)據(jù)還是全局常量?

靜態(tài)方法和變量類型屬性

靜態(tài)方法和類別屬性的工作原理類似于全局方法和全局屬性,應該節(jié)制使用。它們的使用場景在于如果某些功能局限于特別的類型或和Objective-C 互相調(diào)用。

可選類型

可以變量和函數(shù)返回值聲明為可選類型(?),如果nil值可以接受。

當你確認實例變量會稍晚在使用前初始化,可以在聲明時使用!來隱式的拆包類型,比如在viewDidLoad中會初始化的子視圖。

當你訪問一個可選類型值時,如果只需要訪問一次或者在可選值鏈中有多個可選類型值時,請使用可選類型值鏈:

self.textContainer?.textLabel?.setNeedsDisplay()

如果可以方便的一次性拆包或者?執(zhí)行多次性操作時,使用可選類型綁定:

if let textContainer =self.textContainer {
? ? ? // 對textContainer多次操作
}

當我們命名一個可選值變量和屬性時,避免使用如optionalString 或 maybeView名稱,因為可選值的已經(jīng)體現(xiàn)在類型定義中。

在可選值綁定時,直接映射原始的命名比使用諸如unwrappedView 或 actualLabel好。

正例

var subview: UIView?
var volume: Double?

if let subview=subview, volume=volume {
? ? ? // xxoo
}

反例

var optionalSubview: UIView?
var volume: Double?
if let unwrappedSubview = optionalSubview {
? ? if let realVolume = volume {
? ? ? ? ? // ooxx
? ? }
}

結構體構造器

使用Swift原生的結構體構造器而不是傳統(tǒng)的的CGGeometry構造器。

正例

let bounds = CGRect(x: 40, y: 20, width: 120, height: 80)
let centerPoint = CGPoint(x: 96, y: 42)

反例

let bounds = CGRectMake(40,20,120,80)
let centerPoint = CGPointMake(96,42)

推薦使用結構體內(nèi)部的常量CGRect.infiniteRect,CGRect.nullRect等,來替代全局常量CGRectInfinite,CGRectNull等。對于已經(jīng)存在的變量值,可以簡寫成 .zero。

延遲初始化

延遲初始化用來細致地控制對象的生命周期,這對于想實現(xiàn)延遲加載視圖的UIViewController特別有用,你可以使用即時被調(diào)用閉包或私有構造方法:

lazy var locationManager: CLLocationManager=self.makeLocationManager()

private func makeLocationManager() -> CLLocationManager {
? ? let manager=CLLocationManager() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?manager.desiredAccuracy=kCLLocationAccuracyBest?
? ? manager.delegate=self
? ? manager.requestAlwaysAuthorization()
? ? return manager
}

注意:Location manager 的負面效果會彈出對話框要求用戶提供權限,這是做延時加載的原因。

類型推斷

推薦使用更加緊湊的代碼,讓編譯器能夠推斷出每個常量和變量的類型。類型推斷也適用于小的數(shù)組和字典,如果需要可以指定特定的類型,如 CGFloat 或 Int16 。

正例

let message = "Click the button"
let currentBounds = computeViewBounds()
var names = ["Mic","Sam","Christine"]
let maximumWidth: CGFloat =106.5

反例

let message:String="Click the button"
let currentBounds: CGRect=computeViewBounds()
let names=[String]()

類型注解對空的數(shù)組和字典

對空的數(shù)據(jù)和字典,使用類型注解。

正例

var names: ?[String] = []
var lookup: ?[String: Int] = [:]

反例

var names = [String]()
var lookup = [String: Int]()

注意:這意味著選擇描述性名稱更加重要。

語法糖

使用簡潔的類型定義語法,而不是全稱語法。

正例

var deviceModels: [String]
var employees: [Int:String]
var faxNumber: Int?

反例

var deviceModels: Array<String>
var employees: Dictionary<Int, String>
var faxNumber: Optional<Int>


函數(shù) VS 方法

自由函數(shù)不依附于任何類或類型,應該節(jié)制地使用。如果可能優(yōu)先使用方法而不是自由函數(shù),這有助于代碼的可讀性和易發(fā)現(xiàn)性。

自由函數(shù)使用的場景是當不確定它和具體的類別或實例相關。

正例

let sorted = items.mergeSort() // ?易發(fā)現(xiàn)性
rocket.launch() ?// ?可讀性

反例

let sorted = mergeSort(items)// ?不易被發(fā)現(xiàn)
launch(&rocket)

自由函數(shù)

let tuples = zip(a, b)?
let value = max(x,y,z)// ?天然自由函數(shù)!


內(nèi)存管理

代碼應避免指針循環(huán)引用,分析對象圖譜,使用弱引用?和未知引用避免強引用循環(huán). 另外使用值類型(結構體和枚舉)可以避免循環(huán)引用。

延長對象生命周期

延長對象生命周期習慣上使用[weak self] 和 guard let strongSelf = self else { return }.?[weak self]? 優(yōu)于 [unowned self] 因為前者更更能明顯地self 生命周期長于閉包塊。 顯式延長?生命周期優(yōu)先于?可選性拆包.

正例

resource.request().onComplete { [weak self] response in
? guard let strongSelf = self else {return}
? let model = strongSelf.updateModel(response)?
? strongSelf.updateUI(model)
}

反例

// 如果self在response之前銷毀會?崩潰
resource.request().onComplete { [unowned self] ?response in
? ? let model = self.updateModel(response)
? ? self.updateUI(model)
}

反例

//?self可能在updateModel和updateUI被釋放
resource.request().onComplete { [weak self] response in
? let model = self?.updateModel(response)
? self?.updateUI(model)
}


訪問控制

合理的使用private 和? fileprivate, 推薦使用private,在使用extension時可使用fileprivate。

訪問控制符一般放在屬性修飾符的最前面. 除非需要使用 static 修飾符 ,@IBAction,? @IBOutlet 或 @discardableResult 。

正例

class TimeMachine {
? ?private dynamic lazy var fluxCapacitor = FluxCapacitor()
}

private let message = "Great Scott!"

反例

class TimeMachine {
? ?lazy dynamic private var fluxCapacitor=FluxCapacitor()
}

fileprivate let message = "Great Scott!"


控制流程

循環(huán)使用for-in表達式,而不使用 while 表達式。

正例

for _ in 0..<3 {
? print("Hello three times")
}

for(index, person) in attendeeList.enumerate() {
? ? print("\(person)is at position #\(index)")
}

for index in 0.stride(from: 0, to: items.count, by: 2) {
? print(index)
}
for index in (0...3).reverse() {
? ? print(index)
}

反例

var i=0
while i<3 {
? print("Hello three times")
? i+=1
}

var i=0
while i<3 {
? let person = attendeeList[i]
? print("\(person)is at position #\(i)")?
? i+=1
}


黃金路徑

當編碼遇到條件判斷時,左邊的距離是黃金路徑或幸福路徑,因為路徑越短,速度越快。不要嵌套if循環(huán),多個返回語句是可以的。guard 就為此而生的。

正例

func computeFFT(context: Context?, inputData: InputData?) ?throws -> Frequencies {
? ? guard let context = context else {throwFFTError.NoContext }

? ?guard let inputData = inputData else { throwFFTError.NoInputData }

? //?計算frequencies
? return frequencies
}

反例

func computeFFT(context: Context?, inputData: InputData?) throws -> Frequencies {
if let context = context {
? ? if let inputData = inputData {
? ? ? ? ? ?// 計算frequencies
? ? ? ? ? return frequencies? ?
? ? } else {
? ? ? ? ?throwFFTError.NoInputData? ?
? ? ?}?
? ?} else {
? ? ? throwFFTError.NoContext?
? ?}
}

當有多個條件需要用 guard 或 if let 解包,可用復合語句避免嵌套。

正例

guard let number1=number1, number2=number2, number3=number3 else{
? ? fatalError("impossible")
}
// 處理number

反例

if let number1=number1 {
? ? ?if let number2=number2 {
? ? ? ? ? ?if let number3=number3 {
? ? ? ? ? ? ? ?// 處理number
? ? ? ? ? ? ?} else {? ? ?
? ? ? ? ? ? ? fatalError("impossible")? ?
? ? ? ? ? ? ?}?
? ? ? ? ?} else {? ?
? ? ? ? ? ? fatalError("impossible")?
? ? ? ? ? }
? ? ? } else {
? ?fatalError("impossible")
}

?失敗防護

防護語句的退出有很多方式,一般都是單行語句,如 return,throw,break,continue 和 fatalError()等。 避免出現(xiàn)大的代碼塊,?如果清理代碼需要多個退出點,可以用 defer 模塊避免重復清理代碼。


分號

Swift不強制每條語句有分號,當一行內(nèi)寫多個語句的時候是必須的。

不要在一行里寫多個語句。

例外的是在構造for遞增循環(huán)時需要使用分號,但構造for循環(huán)時推薦使用 用 for-in ?結構。

正例

let swift = "not a scripting language"

反例

let swift = "not a scripting language";


圓括號

條件判斷時圓括號不是必須的,建議省略。

正例

if name=="Hello" {
? ? print("World")
}

反例

if(name=="Hello") {
? ?print("World")
}


推薦閱讀

Swift入門 - 數(shù)組


更多

獲取更多內(nèi)容請關注微信公眾號豆志昂揚:

+ 直接添加公眾號豆志昂揚

+ 微信掃描下圖二維碼;

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

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