Swift入坑0x01基礎

高屋建瓴

這節(jié)的基礎內(nèi)容主要參考官檔Swift-The Basics,主要涵蓋Swift中的常量,注釋催烘,各種變量沥阱,錯誤處理以及斷言等的說明。

涉及到的概念比較多伊群,這里先總結(jié)下作為Swift本章主要講到的知識點考杉。加粗的元組和optionals類型是Swift和OC相比特有的兩個類型。

  • 常量和變量
  • 注釋
  • 分號
  • 整數(shù)
  • 浮點數(shù)
  • 類型安全和判斷
  • 數(shù)值型字面量
  • 數(shù)值類型轉(zhuǎn)換
  • 類型別名
  • 布爾值
  • 元組
  • optionals類型
  • 錯誤處理
  • 斷言

各個擊破

常量和變量

官檔原文

1.使用let定義常量/使用var定義變量
let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0

2.多個常量或變量定義用逗號隔開

let maximumNumberOfLoginAttempts = 10, minNumberOfLoginAttempts = 1
var x = 0.0, y = 0.0, z = 0.0

3.變量類型標注

//聲明關(guān)鍵字 + 變量名 + ":" + 變量類型
var welcomeMessage: String

//正確使用
welcomeMessage = "hello world"
//報錯
welcomeMessage = 3

但是呢舰始,你會發(fā)現(xiàn)在現(xiàn)實開發(fā)中我們往往很少給變量加類型說明崇棠,因為往往我們在定義的時候習慣給它初始化。

It’s rare that you need to write type annotations in practice. If you provide an initial value for a constant or variable at the point that it’s defined, Swift can almost always infer the type to be used for that constant or variable, as described in Type Safety and Type Inference. In the welcomeMessage example above, no initial value is provided, and so the type of the welcomeMessage variable is specified with a type annotation rather than being inferred from an initial value.

你很少需要在實踐中使用類型標注丸卷。如果我們再定義常量/變量的時候提供初始化枕稀,Swift總是可以推斷出用于該常量/變量的類型。但是正如 Type Safety and Type Inference所描述的及老,變量"welcomeMessage"并沒有在定義的時候初始化抽莱,所以這個時候變量"welcomeMessage"的類型Swift就不能根據(jù)初始化的值推斷,而是依賴于變量的類型標注(: String).

4.變量命名原則

  • a. 不能包含空格骄恶,數(shù)學符號食铐,箭頭符,專用的unicode值
  • b. 不能以數(shù)字開頭
  • c. 駝峰

這點僧鲁,基本所有語言都有共性虐呻。

5.變量打印

// Prints "The current value of friendlyWelcome is Bonjour!"
print("The current value of friendlyWelcome is \(friendlyWelcome)")

可以看出,這種打印方式還是很特別的寞秃。我們之前OC是使用NSLog做打印斟叼,雖然名稱上與C有錯不同。但是春寿,打印方式上還是一脈相承朗涩,都需要在字符串打印格式中中使用占位符,然后再在格式之后按順序跟著要打印的變量名绑改。

//C
printf("hello these are %s and %s", "wen", "chaors");
//OC
NSLog(@"hello these are %@ and %@", @"wen", @"chaors");
//Swift
print("hello these are \("wen") and \("chaors")")

顯然谢床,Swift在打印格式中直接使用轉(zhuǎn)義符(\)并將變量包裝在小括號()內(nèi),使得打印看上去更加簡潔兄一。不過,剛從C/OC過來的我開始階段還是稍有不適识腿。

注釋

官檔原文

1.和大多數(shù)語言雷同的注釋方式

//單行注釋

/*
多行注釋
第1行
第2行
...
*/

2.嵌套塊注釋

/* This is the start of the first multiline comment.
 /* This is the second, nested multiline comment. */
This is the end of the first multiline comment. */

這其實沒什么可說的出革,不過增加這個支持后,對含有塊注釋的代碼進行注釋就方便多了渡讼。也許這樣說還是不太明朗骂束,我們拿OC舉個例子。

OC不支持嵌套塊注釋

嵌套注釋就是針對這種情況的解決方案成箫,其實有時候還是蠻有用的展箱。

分號

官檔原文

想必我們也已經(jīng)發(fā)現(xiàn),前面寫的Swift示例代碼語句結(jié)尾都沒有分號伟众。

Unlike many other languages, Swift doesn’t require you to write a semicolon (;) after each statement in your code, although you can do so if you wish. However, semicolons are required if you want to write multiple separate statements on a single line.

不像其他語言析藕,Swift并不要求在代碼的每個語句之后添加分號(;).當然如果你愿意,你也可以這樣做凳厢。但是账胧,當一行有多個語句時就必須使用分號了。

C語言的編譯器規(guī)定先紫,每句代碼必須使用";"作為分隔符治泥,以便使編譯器知道該語句執(zhí)行到哪里結(jié)束。OC作為C的衍生語言遮精,當然也將這一特點繼承過來居夹。但是,事實上本冲,并不是所有的語言需要這樣做准脂。除了今天的Swift,單行一句代碼不需要加分號的還有Js檬洞,Python等狸膏。

其實,在這個問題上有一個ASI(Automatic semicolon insertion)規(guī)則添怔。簡言之湾戳,就是分號自動插入。很多時候广料,并不是不需要分號砾脑,而是這件事編譯器給我們做了。關(guān)于ASI具體的分析可以看這篇文章

整數(shù)

官檔原文

1.和OC的概念基本相同艾杏,提供API訪問范圍

let minValue = UInt8.min  // minValue is equal to 0, and is of type UInt8
let maxValue = UInt8.max  // maxValue is equal to 255, and is of type UInt8

2.int/uint

On a 32-bit platform, Int(Uint) is the same size as Int32(Uint32).
On a 64-bit platform, Int (Uint) is the same size as Int64(Uint64).

浮點數(shù)

官檔原文

Double represents a 64-bit floating-point number. 15位精度
Float represents a 32-bit floating-point number. 6位精度

類型安全和判斷

官檔原文

就是前面講變量初始化和賦值時涉及到的韧衣,編譯器會根據(jù)你給變量傳遞的數(shù)值類型來推斷變量具體的類型。

這里,需要注意一個細節(jié):

  • 1.對整數(shù)推斷默認是int
  • 2.對浮點數(shù)推斷默認是double

數(shù)值型字面量

官檔原文

1.整數(shù)型字面量:

  • 十進制: 正常模式(無前綴)
  • 二進制: + 0b 前綴
  • 八進制: + 0o 前綴
  • 十六進制:+ 0x 前綴

eg:

let decimalInteger = 17
let binaryInteger = 0b10001       // 17 in binary notation
let octalInteger = 0o21           // 17 in octal notation
let hexadecimalInteger = 0x11     // 17 in hexadecimal notation

2.科學計數(shù)法

  • 1.25e2 1.25 x 10的平方
  • 0xfp-2 15 x 10的-2次方

數(shù)值類型轉(zhuǎn)換

官檔原文

1.整數(shù)轉(zhuǎn)換

let cannotBeNegative: UInt8 = -1
// UInt8 cannot store negative numbers, and so this will report an error
let tooBig: Int8 = Int8.max + 1
// Int8 cannot store a number larger than its maximum value,
// and so this will also report an error

let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)

和其他語言一樣畅铭,某類型整數(shù)表示的數(shù)不能超過它能表示的范圍萧求;其次,不同類型的兩個數(shù)需要轉(zhuǎn)換為相同類型再進行加減法運算顶瞒。

2.浮點數(shù)與轉(zhuǎn)換

let integerPi = Int(pi)

通過轉(zhuǎn)換接口轉(zhuǎn)換。

類型別名

官檔原文

typealias AudioSample = UInt16

var maxAmplitudeFound = AudioSample.min  // means UInt16.min
// maxAmplitudeFound is now 0

就是可以給固有的數(shù)據(jù)類型起一個別名元旬,至于用處榴徐,文檔是這樣描述的:

Type aliases are useful when you want to refer to an existing type by a name that is contextually more appropriate, such as when working with data of a specific size from an external source.

當你想在特定上下文通過更合適的名稱來引用現(xiàn)有類型時,別名就顯得很有用匀归。例如從外部源處理特定大小的數(shù)據(jù)時坑资。

what?關(guān)于這一點的設計哲學穆端,說實話超哥不是很明白袱贮。或者只是為了代碼上語義看上去更加明確和鮮明体啰?

布爾值

官檔原文

et orangesAreOrange = true
let turnipsAreDelicious = false

if turnipsAreDelicious {
    print("Mmm, tasty turnips!")
} else {
    print("Eww, turnips are horrible.")
}

基本上和OC一樣攒巍,但是這里有一點需要注意。就是整數(shù)類型和布爾值的轉(zhuǎn)換荒勇,在OC里if里int只要是非0值就會認為對應的布爾值為真柒莉,按真的邏輯處理。例如下面的代碼可以運行的:

NSInteger i = 0-1;
    if (i) {
        
        NSLog(@"complie succ");
    }

但是沽翔,在Swift里布爾值的定義是嚴格的兢孝,上面的寫法會提示i不是一個布爾值,因而導致編譯不通過仅偎。

image.png

元組

官檔原文

Tuples是一個OC里沒有的概念跨蟹。它的定義是這樣的:

Tuples group multiple values into a single compound value. The values within a tuple can be of any type and don’t have to be of the same type as each other.

元組將多個值組合為一個復合值。其中的類型可以是任意類型橘沥,并且他們可以是不同類型窗轩。

1.??

let http404Error = (404, "Not Found")
// http404Error is of type (Int, String), and equals (404, "Not Found")

這個??的元組用來描述http狀態(tài)代碼。404代表錯誤碼威恼,"Not Found"代表錯誤的描述信息品姓。將一個int和string復合為一個元組來表示http的狀態(tài)信息。

2.表示和使用

//1.一般表示
let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)")
// prints "The status code is 404"
print("The status message is \(statusMessage)")
// prints "The status message is Not Found"

//2.按需使用箫措,不用的用_代替
let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)")
// prints "The status code is 404"

//3.按索引訪問
print("The status code is \(http404Error.0)")
// prints "The status code is 404"
print("The status message is \(http404Error.1)")
// prints "The status message is Not Found"

//4.為元組元素命名腹备,按名訪問
let http200Status = (statusCode: 200, description: "OK")
print("The status code is \(http200Status.statusCode)")
// prints "The status code is 200"
print("The status message is \(http200Status.description)")
// prints "The status message is OK"

方法2讓我想起了go語言中數(shù)組和字典的遍歷,只需要訪問值不需要下標的時候也是可以使用_占位即可斤蔓。

方法3說明其內(nèi)部的存儲類似于數(shù)組植酥,也是一個有序的順序結(jié)構(gòu)。

Optionals類型

官檔原文

這又是一個Swift特有的類型。

You use optionals in situations where a value may be absent. An optional represents two possibilities: Either there is a value, and you can unwrap the optional to access that value, or there isn’t a value at all.

optionals類型用于處理值可能缺失的情況友驮∑颍可選意味著:

  • 這里有一個值,并且你可以打開可選項訪問他
  • 根本就不存在值

The concept of optionals doesn’t exist in C or Objective-C. The nearest thing in Objective-C is the ability to return nil from a method that would otherwise return an object, with nil meaning “the absence of a valid object.” However, this only works for objects—it doesn’t work for structures, basic C types, or enumeration values. For these types, Objective-C methods typically return a special value (such as NSNotFound) to indicate the absence of a value. This approach assumes that the method’s caller knows there’s a special value to test against and remembers to check for it. Swift’s optionals let you indicate the absence of a value for any type at all, without the need for special constants.

這一段大概是說optionals類似于OC里的nil卸留,但是nil只能用來表示對象走越,不能表示一般數(shù)據(jù)類型。但optionals可以用于這些類型耻瑟。

1.nil 只有optional類型才能被賦值為nil

// optional類型
var serverResponseCode: Int? = 404
// serverResponseCode contains an actual Int value of 404
serverResponseCode = nil
// serverResponseCode now contains no value

//普通int類型
var i = 345
// 這樣賦值編譯器會報錯:can not assign to value
I = nil

2.optional類型的展開

if convertedNumber != nil {
    print("convertedNumber has an integer value of \(convertedNumber!).")
}
// prints "convertedNumber has an integer value of 123."

if let actualNumber = Int(possibleNumber) {
    print("\'\(possibleNumber)\' has an integer value of \(actualNumber)")
} else {
    print("\'\(possibleNumber)\' could not be converted to an integer")
}

4.隱式展開optional

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark
 
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark

Sometimes it’s clear from a program’s structure that an optional will always have a value, after that value is first set. In these cases, it’s useful to remove the need to check and unwrap the optional’s value every time it’s accessed, because it can be safely assumed to have a value all of the time.

有時optional類型在設置值之后旨指,將始終擁有該值。在這個情況下喳整,不需要每次訪問都檢查和解包谆构。

使用"!"而不是"?"框都,即隱式自動解包(將其值暴露)搬素。實際上,這種情況就和一般變量的使用一樣了魏保。

錯誤處理

官檔原文

本質(zhì)上還是try-catch那一套熬尺。關(guān)于錯誤處理,后面還有專門的章節(jié)詳述囱淋。

func canThrowAnError() throws {
    // this function may or may not throw an error
}

do {
    try canThrowAnError()
    // no error was thrown
} catch {
    // an error was thrown
}

斷言

官檔原文

斷言和先決條件猪杭,這也是我們都熟悉的。他們是在運行時發(fā)生的檢查妥衣,如果斷言里或先決條件里的布爾值為真皂吮,則代碼照常執(zhí)行;否則税手,程序的當前狀態(tài)無效蜂筹,代碼執(zhí)行將結(jié)束。

The difference between assertions and preconditions is in when they’re checked: Assertions are checked only in debug builds, but preconditions are checked in both debug and production builds. In production builds, the condition inside an assertion isn’t evaluated. This means you can use as many assertions as you want during your development process, without impacting performance in production.

斷言和先決條件的不同之處在于他們什么時候做檢查:斷言只在 debug 構(gòu)建的時候檢查芦倒,但先決條件則在 debug 和生產(chǎn)構(gòu)建中生效艺挪。在生產(chǎn)構(gòu)建中,斷言中的條件不會被計算兵扬。這就是說你可以在開發(fā)的過程當中隨便使用斷言而無需擔心影響生產(chǎn)性能麻裳。

1.斷言的使用

let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
// This assertion fails because -3 is not >= 0.

if age > 10 {
    print("You can ride the roller-coaster or the ferris wheel.")
} else if age >= 0 {
    print("You can ride the ferris wheel.")
} else {
    assertionFailure("A person's age can't be less than zero.")
}

2.強制先決條件

// In the implementation of a subscript...
precondition(index > 0, "Index must be greater than zero.")

preconditionFailure("Index can't be less than zero.")

3. fatalError用于標注暫時還沒實現(xiàn)的方法

fatalError("Unimplemented")
image.png

至此,這一節(jié)就告一段落了器钟。

---------------------------------------------------------20190519.13.24午后

I know I want, and now I can

有時候
堅持你最不想干的事
反而能得到你最想要的東西
但是
如果可以給這種不想干
注入一種激情
那么得到的會不會更多呢津坑?
-----------------------------非著名八線互聯(lián)網(wǎng)九流程序猿 chaors

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末彤敛,一起剝皮案震驚了整個濱河市浩考,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌囤热,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件穆役,死亡現(xiàn)場離奇詭異寸五,居然都是意外死亡,警方通過查閱死者的電腦和手機耿币,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門梳杏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人淹接,你說我怎么就攤上這事秘狞。” “怎么了蹈集?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長雇初。 經(jīng)常有香客問我拢肆,道長,這世上最難降的妖魔是什么靖诗? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任郭怪,我火速辦了婚禮,結(jié)果婚禮上刊橘,老公的妹妹穿的比我還像新娘鄙才。我一直安慰自己,他們只是感情好促绵,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布攒庵。 她就那樣靜靜地躺著,像睡著了一般败晴。 火紅的嫁衣襯著肌膚如雪浓冒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天尖坤,我揣著相機與錄音稳懒,去河邊找鬼。 笑死慢味,一個胖子當著我的面吹牛场梆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播纯路,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼或油,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了感昼?” 一聲冷哼從身側(cè)響起装哆,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蜕琴,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體萍桌,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年凌简,在試婚紗的時候發(fā)現(xiàn)自己被綠了上炎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡雏搂,死狀恐怖藕施,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凸郑,我是刑警寧澤裳食,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站芙沥,受9級特大地震影響诲祸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜而昨,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一救氯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧歌憨,春花似錦着憨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至心铃,卻和暖如春惧眠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背于个。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工氛魁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人厅篓。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓秀存,卻偏偏與公主長得像,于是被迫代替她去往敵國和親羽氮。 傳聞我的和親對象是個殘疾皇子或链,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

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

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學習記錄文檔,今天18年5月份再次想寫文章档押,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 2,739評論 2 9
  • 關(guān)于 Swift 重要這個文檔所包含的準備信息, 是關(guān)于開發(fā)的 API 和技術(shù)的澳盐。這個信息可能會改變, 根據(jù)這個文...
    無灃閱讀 4,283評論 1 27
  • 基本數(shù)據(jù)類型 整數(shù)整數(shù)就是沒有小數(shù)部分的數(shù)字祈纯,如 42 和 -23 。整數(shù)是有符號的(正叼耙、負腕窥、零)或無符號的(正、...
    Gary_Tseng閱讀 527評論 0 0
  • 一直以來筛婉,我都想好好的研究研究一下這個新語言簇爆。之前雖然用過一段時間,但一直都覺得不甚了解爽撒。這本書已經(jīng)得到了好久入蛆,期...
    天蓬大元閱讀 1,295評論 0 1
  • 李錄在《我眼中的查理.芒格》說了查理.芒格的兩個故事。 01查理喜歡與人早餐約會硕勿,通常是7:30哨毁。第一次約會,李錄...
    風一wf閱讀 342評論 0 0