第二章——Swift語言【譯】

Swift是蘋果于2014年推出的一種新語言。Swfit 將替換 Objective-C,成為 iOS 和 Mac 的推薦開發(fā)語言。在本章中,您將重點學習Swift的基礎知識。 你不會學到所有的知識,但是你會學到足夠的知識來入門。 然后,當您繼續(xù)閱讀本書時,您將在學習 iOS 開發(fā)的過程中學到更多。

Swift 保持 Objective-C 的表現(xiàn)力,同時引入更安全,簡潔和可讀的語法。它強調(diào)類型安全性,并增加了高級功能,如可選項,泛型,復雜結構和枚舉。最重要的是,在開發(fā)人員多年來構建的、經(jīng)過測試的、高級的 iOS 框架中也能使用這些新功能。

如果你在用 Swift 進行iOS開發(fā)的時候感到困難,您可能需要從 Swift Programming:The Big Nerd Ranch Guide 或 Apple 的 Swift教程 開始,您可以在 developer.apple.com/ 中找到。 但是,如果你有一些編程經(jīng)驗,并想在工作中運用,你可以在這里開始你的 Swift 學習。

Swfit 的類型

Swift 類型可以分為三個基本組:結構體(structure)類(class)枚舉(enumeration)(圖2.1)。 所有三個可以有:

  • 屬性 - 與類型相關聯(lián)的值
  • 構造器 - 初始化類型實例的代碼
  • 實例方法 - 在該類型的實例上調(diào)用的函數(shù)
  • 類或靜態(tài)方法 - 在類型本身上調(diào)用的函數(shù)

圖2.1 Swift 構建塊

Swift 的結構體和枚舉比大多數(shù)語言更加強大。 除了支持屬性,構造器和方法之外,它們還可以符合協(xié)議并可以擴展。

Swift 原始數(shù)據(jù)類型(如數(shù)字和布爾值)的實現(xiàn)可能會讓您感到驚訝:它們都是結構體。 事實上,所有這些 Swift 類型都是結構體:

數(shù)字類型: Int, Float, Double

布爾類型: Bool

文本類型: String, Character

集合類型: Array<Element>, Dictionary<Key:Hashable,Value>,Set<Element:Hashable>

這意味著基礎類型也具有屬性,構造器和自己的方法。 它們也可以符合協(xié)議并擴展。

最后,Swift 的一個關鍵特性是 可選項(optional)。 可選項允許您存儲特定類型的值或根本沒有值。 您將在本章后面更多地了解可選項及其在 Swift 中的作用。

使用標準類型

在本節(jié)中,您將在 Xcode playground 中嘗試使用標準類型。 playground 可讓您編寫代碼并查看結果,而無需手動運行應用程序和檢查輸出。

Xcode 中,選擇 FileNewPlayground... 方便起見,你可以使用此文件的默認名稱。 確保 platform 是 iOS(圖2.2)。

圖2.2配置playground

單擊 Next 并將其保存在方便的位置。

當文件打開時,請注意,playground 分為兩個部分(圖2.3)。 左側較大的白色區(qū)域是您編寫代碼的編輯器。 右側的灰色列是側邊欄。 playground 在每行后編譯并執(zhí)行您的代碼,并在側邊欄中顯示結果。

圖2.3一個playground

在示例代碼中,var 關鍵字表示一個變量,因此 str 的值可以從其初始值更改。 鍵入以下代碼以更改 str 的值,您將看到結果顯示在右側的邊欄中。

var str = "Hello, playground"????"Hello, playground"
str = "Hello, Swift"????????"Hello, Swift"

(請注意,我們會在右邊顯示側邊欄的結果,給那些沒有積極地進行練習的讀者看。)

let 關鍵字表示不能更改的常量值。 在您的 Swift 代碼中,您應該多使用 let,除非您期望該值需要更改。 添加一個常量:

var str = "Hello, playground"????"Hello, playground"
str = "Hello, Swift"????????"Hello, Swift"
let constStr = str?????????"Hello, Swift"

因為constStr是一個常量,所以嘗試改變它的值會導致一個錯誤。

var str = "Hello, playground"????"Hello, playground"
str = "Hello, Swift"????????"Hello, Swift"
let constStr = str?????????"Hello, Swift"
constStr = "Hello, world"

出現(xiàn)錯誤的話,會在錯誤行左側用紅色符號表示。 單擊符號以獲取有關錯誤的更多信息。 在這種情況下,錯誤是

Cannot assign to value: 'constStr' is a 'let' constant.
無法分配給值:'constStr' 是一個 'let' 常量。

playground 代碼中的錯誤將阻止您在側邊欄中看到任何進一步的結果,因此您通常希望立即解決問題。 刪除嘗試更改 constStr 的值的行。

var str = "Hello, playground"????"Hello, playground"
str = "Hello, Swift"????????"Hello, Swift"
let constStr = str?????????"Hello, Swift"
constStr = "Hello, world"

類型推斷

在這一點上,您可能已經(jīng)注意到,constStr 常量和 str 變量都不具有指定的類型。 這并不意味著他們是沒有類型的! 編譯器會從初始值推斷出它們的類型。 這稱為類型推斷。

您可以使用 Xcode 的快速幫助找出推斷的類型。 按住 Alt 在 playground 上單擊 constStr 以查看該常量的快速幫助信息(譯者注:此處虛擬機中按 Alt,Mac 是 Option 鍵 ),如圖2.4所示。

圖2.4 constStr是String類型

Alt-單擊顯示快速幫助將適用于任何對象。

指定類型

如果常數(shù)或變量具有初始值,則可以依賴類型推斷。 如果常數(shù)或變量沒有初始值,或者如果要確保它是某種類型,則可以在聲明中指定類型。

添加指定類型的更多變量:

var str = "Hello, playground"????"Hello, playground"
str = "Hello, Swift"????????"Hello, Swift"
let constStr = str?????????"Hello, Swift"

var nextYear: Int
var bodyTemp: Float
var hasPet: Bool

請注意,邊欄沒有報告任何結果,因為這些變量還沒有值。

我們來看看這些新的類型以及它們的使用方式。

數(shù)字和布爾類型

整數(shù)最常見的類型是 Int。 還有基于數(shù)字長度和符號類型的整數(shù)類型,但是蘋果建議使用 Int,除非你真的有使用別的類型的理由。

對于浮點數(shù),Swift提供了三種不同精度的類型:

Float 為32位,Double 為64位,Float80 為80位。

集合類型

Swift 標準庫提供三個集合:數(shù)組(array)字典(dictionary)集合(set)

數(shù)組是元素的有序集合。 數(shù)組類型寫為 Array <T>,其中 T 是數(shù)組將包含的元素的類型。 數(shù)組可以包含任何類型的元素:標準類型,結構體或類。

為整數(shù)數(shù)組添加一個變量:

var hasPet: Bool
var arrayOfInts: Array<Int>

數(shù)組是強類型的。 一旦將數(shù)組聲明為包含 Int 的元素,就不能向其添加一個 String

有一個用于聲明數(shù)組的簡寫語法:您可以簡單地在數(shù)組將包含的類型周圍使用方括號。 更新 arrayOfInts 的聲明以使用簡寫:

var hasPet: Bool
var arrayOfInts: Array<Int>
var arrayOfInts: [Int]

字典是鍵值對的無序集合。 值(value)可以是任何類型,包括結構體和類。 鍵(key)也可以是任何類型,但它們必須是唯一的。 具體來說,key 必須是 可哈希(hastable) 的,這允許字典保證 key 是唯一的,并且更有效地訪問給定 key 的值。 基本的 Swift 類型,如 IntFloatCharacterString 都是可哈希的。

像 Swift 數(shù)組一樣,Swift 字典也是強類型的,只能包含聲明類型的 鍵(key) 和 值(value)。 例如,您可能有一個字典,按國家/地區(qū)存儲首都。 這個字典的 鍵(key) 將是國名,值將是城市名稱。 鍵和值都將是字符串,您將無法添加任何其他類型的鍵或值。

為這樣的字典添加一個變量:

var arrayOfInts: [Int]
var dictionaryOfCapitalsByCountry: Dictionary<String,String>

還有一個用于聲明字典的簡寫語法。 更新 dictionaryOfCapitalsByCountry 使用簡寫:

var arrayOfInts: [Int]
var dictionaryOfCapitalsByCountry: Dictionary<String,String>
var dictionaryOfCapitalsByCountry: [String:String]

一個集合類似于一個數(shù)組,因為它包含一些特定類型的元素。 然而,集合是無序的,成員必須是唯一的,并且是 可哈希的(hashable) 。 當您只需要確定某個東西是否是一個集合的成員時,集合的無序性使得它們更快。 為集合添加一個變量:

var winningLotteryNumbers: Set<Int>

與數(shù)組和字典不同,集合沒有縮寫語法。

字面值和下標

可以為標準類型分配字面值。 例如,str 被賦予字符串字面值。 字符串字面值用雙引號形成。 將分配給 str 的字面值與分配給 constStr 的非字面值進行對比:

var str = "Hello, playground"????"Hello, playground"
str = "Hello, Swift"????????"Hello, Swift"
let constStr = str?????????"Hello, Swift"

在 playground 上添加兩個數(shù)字字面值:

let number = 42????????????42
let fmStation = 91.1??????????91.1

數(shù)組和字典也可以分配字面值。 創(chuàng)建文字數(shù)組和字典的語法類似于用于指定這些類型的簡寫語法。

let countingUp = ["one", "two"]????????????????["one", "two"]
let nameByParkingSpace = [13: "Alice", 27: "Bob"]???????[13: "Alice", 27: "Bob"]

Swift 還提供下標作為訪問數(shù)組的速記。 要檢索數(shù)組中的元素,您可以在數(shù)組名后面的方括號中提供元素的索引。

let countingUp = ["one", "two"]??????????["one", "two"]
let secondElement = countingUp[1]?????????"two"
...

請注意, 數(shù)組的下標始終從 0 開始,下標 1 檢索第二個元素。

檢索數(shù)組時,請確保使用有效的下標。 嘗試訪問超出范圍的下標會導致 trap(程序中斷)。 trap 是運行時錯誤,在程序進入未知狀態(tài)之前終止程序。

下標也適用于字典——在本章后面講解。

構造器

到目前為止,您已經(jīng)使用字面值初始化了常量和變量。 在這樣做時,您創(chuàng)建了一個特定類型的實例。 實例(instance) 是類型的特定實例。 從歷史上看,這個術語只用于課堂,但在 Swift 中,它也用于描述結構體和枚舉。 例如,常量 secondElement 包含一個 String 的實例。

創(chuàng)建實例的另一種方法是在類型上使用 構造器(initializer)。 構造器負責準備新類型實例的內(nèi)容。構造器執(zhí)行完成后,該實例已準備就緒。 要使用構造器創(chuàng)建新實例,可以使用類型名稱后跟一對括號,如果需要,則加上參數(shù)。 該類型和參數(shù)的組合對應于特定的構造器。

一些標準類型也具有構造器,當沒有提供參數(shù)時返回空文本。 向 playground 添加一個空字符串,一個空數(shù)組和一個空集。

let emptyString = String()??????????""
let emptyArrayOfInts = [Int]()???????? 0 elements

let emptySetOfFloats = Set<Float>()??????0 elements

其他類型具有默認值:

let defaultNumber = Int()??????0
let defaultBool = Bool()??????false

類型可以有多個構造器。 例如,String 具有接受 Int 的構造器,并根據(jù)該值創(chuàng)建一個字符串。

let number = 42???????????????42
let meaningOfLife = String(number)??????"42"

要創(chuàng)建一個集合,可以使用接受數(shù)組字面量的 Set 構造器:

let availableRooms = Set([205, 411, 412])?????{412, 205, 411}

Float 有幾個構造器。 無參數(shù)構造器返回具有默認值的 Float 實例。 還有一個接受浮點數(shù)字的構造器。

let defaultFloat = Float()???????0.0
let floatFromLiteral = Float(3.14)??? 3.14

如果對浮點文字使用類型推斷,則類型默認為 Double。 使用浮點文字創(chuàng)建以下常量:

let easyPi = 3.14?????????3.14

使用接受 DoubleFloat 構造器,從此 Double 創(chuàng)建一個 Float

let easyPi = 3.14?????????????3.14
let floatFromDouble = Float(easyPi)?????3.14

您可以通過在聲明中指定類型來實現(xiàn)相同的結果。

let easyPi = 3.14??????????3.14
let floatFromDouble = Float(easyPi)??3.14
let floatingPi: Float = 3.14?????3.14

屬性

屬性是與類型實例相關聯(lián)的值。 例如,String 具有屬性 isEmpty,它是一個 Bool,它告訴您字符串是否為空。 Array <T> 具有屬性 count,它是數(shù)組中的元素數(shù)量,為 Int。 在 playground 上訪問這些屬性:

let countingUp = ["one", "two"]????["one", "two"]
let secondElement = countingUp[1]???"two"
countingUp.count???????????2
...
let emptyString = String()
emptyString.isEmpty??????????true

實例方法

實例方法是特定于特定類型的函數(shù),可以被該類型的實例調(diào)用。 從 Array <T> 中嘗試 append(_ :) 實例方法。 您將首先需要將 constantUp 數(shù)組從常量更改為變量。

let countingUp = ["one", "two"]
var countingUp = ["one", "two"]?????["one", "two"]
let secondElement = countingUp[1]????"two"
countingUp.count
countingUp.append("three")???????["one", "two", "three"]

append(_ :)方法接受數(shù)組類型的元素,并將其添加到數(shù)組的末尾。 我們將在第3章討論方法,包括命名。

可選值(Optional)

Swift 類型可以是 可選(optional) 的,這通過附加 ?到一個類型名稱來表示 。

var anOptionalFloat: Float?
var anOptionalArrayOfStrings: [String]?
var anOptionalArrayOfOptionalStrings: [String?]?

可選值(optional) 可以表示變量可能根本不存儲值。 可選的值將是指定類型的實例或 nil

在這本書中,您將有很多機會使用可選值。 以下是一個讓您熟悉語法的示例,以便您以后可以專注于使用可選值。

想象一下樂器讀數(shù):

var reading1: Float
var reading2: Float
var reading3: Float

有時,儀器可能發(fā)生故障,因而不能返回一個 reading。 您不希望這種故障顯示為 0.0。 你希望它是完全不同的東西,告訴你檢查你的樂器或采取一些其他的行動。

您可以通過將讀數(shù)聲明為可選來執(zhí)行此操作。 將這些聲明添加到您的 playground。

var reading1: Float???? nil
var reading2: Float?????nil
var reading3: Float?????nil

作為可選的浮點數(shù),每個讀數(shù)可以包含 Floatnil。 如果沒有給出初始值,則該值默認為 nil

您可以像任何其他變量一樣將值分配給可選項。 為 reading 變量 分配浮點數(shù)字:

reading1 = 9.8????9.8
reading2 = 9.2????9.2
reading3 = 9.7 ????9.7

但是,您不能像非可選浮點數(shù)那樣使用這些可選浮點,即使它們已被賦值為 Float。 在讀取可選變量的值之前,必須解決其值為 nil 的可能性。 這被稱為 解包(unwrap) 可選值。

您將嘗試解開一個可選變量的兩種方式:可選綁定和強制解包。 您將首先嘗試執(zhí)行強制展開。 這不是因為它是更好的選擇——其實這是不太安全的選擇。 但是我們先實施強制解包將讓您看到危險,并了解為什么可選綁定通常更好。

要強行解開一個可選項,你可以附加一個! 到它的后面。 首先,嘗試 avgReading,就像它們是非可選變量一樣:

reading1 = 9.8????????????????9.8
reading2 = 9.2????????????????9.2
reading3 = 9.7????????????????9.7
let avgReading = (reading1 + reading2 + reading3) / 3

這會導致錯誤,因為可選值需要先解開。 因此我們強制解開 reading 以解決錯誤:

let avgReading = (reading1 + reading2 + reading3) / 3
let avgReading = (reading1! + reading2! + reading3!) / 3????9.566667

一切都看起來不錯,能看到邊欄中的正確平均值。 但危險潛伏在于您的代碼中。 當你強行展開一個可選值,你告訴編譯器你確定這個可選值不會是 nil,因而它可以被看作是一個正常的 Float。 但如果不是浮點數(shù)呢? 試著注釋掉 reading3 的賦值語句,這將返回默認值 nil

reading1 = 9.8??????9.8
reading2 = 9.2??????9.2
reading3 = 9.7
// reading3 = 9.7

現(xiàn)在出現(xiàn)了一個錯誤。 Xcode 可能會在 playground 底部打開其調(diào)試區(qū)域,并提供有關錯誤的信息。 如果沒有,請選擇 ViewDebug AreaShow Debug Area。 錯誤如下:

fatal error: unexpectedly found nil while unwrapping an Optional value
致命錯誤:在解開可選值時意外發(fā)現(xiàn)為零

如果你強行展開一個可選值,而且該可選值為 nil,那么會導致出現(xiàn) 中斷(trap) 并終止應用程序。

解開可選值的更安全的方法是 可選綁定(optional binding)。 可選綁定在條件 if-let 語句中工作:將可選項分配給相應非可選類型的臨時常量。 如果您的可選值具有值,則分配有效,然后繼續(xù)使用非可選常量。 如果可選是 nil,那么可以使用 else 子句來處理這種情況。

更改您的代碼以使用 if-let 語句來測試所有三個變量中的有效值。

let avgReading = (reading1! + reading2! + reading3!) / 3
if let r1 = reading1,
??let r2 = reading2,
??let r3 = reading3 {
????let avgReading = (r1 + r2 + r3) / 3
} else {
??let errorString = "Instrument reported a reading that was nil."
}

reading3 目前為 nil,所以其對 r3 的賦值失敗,側欄顯示錯誤字符串。

要查看其他情況下的操作,請將將值分配給 reading3 的語句恢復。 現(xiàn)在所有三個讀數(shù)都有值,所有三個變量都是有效的,邊欄更新顯示三個 reading 變量的平均值。

檢索字典

回想一下,數(shù)組超出它的范圍會導致一個 異常(trap)。 而字典則不一樣,檢索字典的結果是可選的:

let nameByParkingSpace = [13: "Alice", 27: "Bob"]????[13: "Alice", 27: "Bob"]
let space13Assignee: String? = nameByParkingSpace[13]??"Alice"
let space42Assignee: String? = nameByParkingSpace[42]??nil

如果 鍵(key) 不在字典中,結果將為零。 與其他可選值一樣,當檢索字典時,通常使用 if-let

let space13Assignee: String? = nameByParkingSpace[13]
if let space13Assignee = nameByParkingSpace[13] {
??print("Key 13 is assigned in the dictionary!")
}

循環(huán)和字符串插值

Swift 具有您可能熟悉的其他語言的所有控制流程語句:if-elsewhileforfor-inrepeat-whileswitch。 然而,即使如此,它們與你習慣的有一些區(qū)別。 Swift 和 C語言風格的這些語句之間的關鍵區(qū)別在于,在這些語句表達式上不需要括號,Swift 只要求對子句使用大括號。

此外,ifwhile 類語句的表達式必須為 Bool

Swift 沒有傳統(tǒng)的 C 風格的循環(huán),你可能習慣了。 相反,您可以使用 Swift 的 Range 類型和 for-in 語句更簡單地完成相同的事情:

let range = 0..<countingUp.count
for i in range {
??let string = countingUp[i]
??// Use 'string'
}

枚舉數(shù)組中的項是最直觀的:

for string in countingUp {
??// Use 'string'
}

如果你想要數(shù)組中的每一項的索引呢? Swift的 enumerated() 函數(shù)從其參數(shù)返回整數(shù)和值的序列:

for (i, string) in countingUp.enumerated() {
??// (0, "one"), (1, "two")
}

你會問那些括號是什么? enumerated() 函數(shù)返回一個 元組(tuple) 序列。 元組是與數(shù)組類似的值的有序分組,但元組的每個成員可能有不同的類型。 在這個例子中,元組是 (Int,String) 類型。 在這本書中我們不會花太多時間在元組上,它們不會在iOS API中使用,因為 Objective-C 不支持它們。 但是,它們可以在您的 Swift 代碼中使用。

元組的另一個應用是枚舉字典的內(nèi)容:

let nameByParkingSpace = [13: "Alice", 27: "Bob"]

for (space, name) in nameByParkingSpace {
??let permit = "Space \(space): \(name)"
}

你注意到字符串中的奇怪的標記嗎? 那就是Swift的 字符串插值(string interpolation)。 ( 和 ) 之間的表達式在運行時被檢測并插入到字符串中。 在本示例中,您用的是局部變量,然而這同樣可以在任何有效的 Swift 表達式,如方法調(diào)用中使用。

要查看循環(huán)每次迭代的 permit 變量的值,首先單擊行 let allow = Space\(space):\(name) 結果側邊欄最右端的循環(huán) Show Result 指示符。 您將看到代碼下的 permit 的當前值。 按住 Control 鍵并點擊結果并選擇* Value History*(圖2.5)。 這可以對觀察循環(huán)代碼中發(fā)生的情況非常有用。

圖2.5使用 Value History 來查看字符串插值的結果

枚舉和Switch語句

枚舉是具有離散值集的類型。 定義一個描述 pie 的枚舉:

enum PieType {
??case apple
??case cherry
??case pecan
}

let favoritePie = PieType.apple

Swift 有一個強大的 switch 語句,除了別的以外,它非常適合使用在枚舉值的匹配:

let name: String
switch favoritePie {
case .apple:
??name = "Apple"
case .cherry:
??name = "Cherry"
case .pecan:
??name = "Pecan"
}

switch 語句的 case 必須是詳盡的:必須明確地或通過 default:case 來考慮 switch 表達式的每個可能的值。 與 C 不同的是,Swift switch case 的情況不會落空——它僅執(zhí)行匹配的情況下的代碼。 (如果您需要C的 fall-through 行為,則可以使用 fallthrough 關鍵字顯式請求它。)(譯:也就是Swift 的 Switch 的 case 語句匹配后只執(zhí)行當前 case 后的語句,不會像 C 一樣沒遇到 break 則繼續(xù)執(zhí)行下去)

Switch語句可以匹配許多類型,甚至范圍:

let macOSVersion: Int = ...
switch macOSVersion {
case 0...8:
??print("A big cat")
case 9:
??print("Mavericks")
case 10:
??print("Yosemite")
case 11:
??print("El Capitan")
case 12:
??print("Sierra")
default:
??print("Greetings, people of the future! What's new in 10.\(macOSVersion)?")
}

有關 switch 語句及其模式匹配功能的更多信息,請參閱 Apple 的 Swift編程語言(Swift Programming Language) 指南中的 控制流程(Control Flow) 部分。 (多看幾遍)

枚舉和原始值

Swift枚舉的原始值可以用 case 關聯(lián):

enum PieType: Int {
??case apple = 0
??case cherry
??case pecan
}

使用指定的類型,rawValue 可以是 PieType 的實例 ,然后使用該值初始化枚舉類型。 這會返回一個可選的值,因為原始值可能與枚舉的實際情況不符,因此它是可選綁定的絕佳候選。

let pieRawValue = PieType.pecan.rawValue
?// pieRawValue is an Int with a value of 2

if let pieType = PieType(rawValue: pieRawValue) {
??// Got a valid 'pieType'!
}

枚舉的原始值通常是 Int,但它同樣可以是任何整數(shù)或浮點數(shù)類型以及 StringCharacter 類型。

當原始值為整數(shù)類型時,如果未給出顯式值,則值將自動遞增。 對于 PieType,只有 apple case 被賦予了一個明確的值。 cherrypecan 的值分別自動分配為 1 和 2 的原始值。

還有更多關于枚舉的知識。 枚舉的每個 case 都可以具有相關聯(lián)的值。 您將在第20章中了解有關相關值的更多信息。

探索蘋果的Swift文檔

要了解 Apple 的 Swift 文檔,請從 developer.apple.com/swift 開始。 這里有兩個特殊的資源來尋找。 我們建議將其加入書簽并訪問它們,以便您可以查看特定的概念或深入挖掘。

The Swift Programming Language

本指南介紹了Swift的許多功能。 它從基礎開始,包括示例代碼和大量細節(jié)。 它還包含 Swift 的語言參考和正式語法。

Swift Standard Library Reference

標準庫參考文獻列出了Swift類型,協(xié)議和全局(或免費)功能的細節(jié)。

您的作業(yè)是瀏覽 Swift標準庫參考(Swift Standard Library Reference) 的 類型(Types) 部分 以及 Swift編程語言指南(The Swift Programming Language guide) 中的 基礎知識(The Basics)字符串(Strings)字符(Characters) 以及 集合類型( Collection Types)。 鞏固您在本章中學到的知識,并熟悉這些資源提供的信息。 如果您在需要時知道在何處查找細節(jié),那么您將會減少要記住它們的壓力——這讓您可以專注于 iOS 開發(fā)。

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

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

  • Swift 介紹 簡介 Swift 語言由蘋果公司在 2014 年推出,用來撰寫 OS X 和 iOS 應用程序 ...
    大L君閱讀 3,267評論 3 25
  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile麗語閱讀 3,854評論 0 6
  • 2014年的蘋果全球開發(fā)者大會(WWDC),當Craig Federighi向全世界宣布“We have new ...
    yeshenlong520閱讀 2,308評論 0 9
  • 關于 Swift 重要這個文檔所包含的準備信息, 是關于開發(fā)的 API 和技術的。這個信息可能會改變, 根據(jù)這個文...
    無灃閱讀 4,351評論 1 27
  • 一個人,一個背包、相機,一本小說,宜昌至鳳凰,八個小時,漫長而又短暫。沿途的風景很美,看著窗外秀麗的景色和日漸西沉...
    四夕點又閱讀 393評論 0 3