類型轉(zhuǎn)換
您需要顯式地表示要轉(zhuǎn)換類型,而不是簡單地賦值。
var integer: Int = 100;
var decimal: Double = 12.5;
integer = Int(decimal); //swift類型轉(zhuǎn)換需要顯示聲明
在本例中淤击,將decimal值賦給integer會導(dǎo)致精度下降:integer變量的值最終是12,而不是12.5故源。這就是為什么需要顯示地進行轉(zhuǎn)換的原因污抬。Swift希望確保您知道自己在做什么,并且您可能會因為執(zhí)行類型轉(zhuǎn)換而丟失數(shù)據(jù)。
混合類型運算符
let hourlyRate: Double = 19.5;
let hoursWorked: Int = 10;
let totalCost: Double = hourlyRate * Double(hoursWorked); //195
在本例中印机,您希望結(jié)果是Double矢腻。您不需要Int,因為在這種情況下射赛,Swift會將hourlyRate常量轉(zhuǎn)換成Int來執(zhí)行乘法多柑,將其四舍五入到19,從而失去了Double的精度楣责。
類型推導(dǎo) Type inference
事實證明竣灌,Swift編譯器也可以推導(dǎo)出變量的類型。它不需要你一直告訴它類型——它可以自己算出來秆麸。這是通過一個稱為類型推導(dǎo)的過程完成的初嘹。
let typeInferredInt = 42
如果想聲明一個Double類型的變量,現(xiàn)在你有4中方式:
let actuallyDouble = 3.0
let actuallyDouble = Double(3)
let actuallyDouble: Double = 3
let actuallyDouble = 3 as Double
像3這樣的文字值沒有類型沮趣。只有在表達式中使用它們或?qū)⑺鼈冑x值給常量或變量時屯烦,Swift才會推導(dǎo)出它們的類型。
字符串
計算機如何表示字符串
計算機認為字符串是單個字符的集合房铭。在本書的第一章中驻龟,您了解到數(shù)字是cpu的語言,所有代碼育叁,無論使用哪種編程語言迅脐,都可以簡化為原始數(shù)字。字符串也一樣豪嗽。
這聽起來可能很奇怪谴蔑。字符怎么會是數(shù)字呢?在它的基礎(chǔ)上,計算機需要能夠?qū)⒁粋€字符翻譯成計算機自己的語言龟梦,它通過給每個字符分配不同的數(shù)字來做到這一點隐锭。這形成了從字符到數(shù)字的雙向映射,稱為字符集计贰。
當你按鍵盤上的一個字符鍵時钦睡,你實際上是在把字符的號碼與計算機通信。您的文字處理器應(yīng)用程序?qū)⒃摂?shù)字轉(zhuǎn)換為字符的圖片躁倒,最后將該圖片呈現(xiàn)給您荞怒。
swift中的字符串
字符與字符串
let characterA: Character = "a"
let characterDog: Character = "?? " //字符不能采用類型推導(dǎo)
let stringDog: String = "Dog"
let stringDog = "Dog" //字符串推導(dǎo)
在Swift中沒有字符語義( character literal )這樣的東西。字符就是長度為1的字符串秧秉。然而褐桌,Swift推斷任何字符串語義的類型都是字符串,所以如果您想要一個字符象迎,您必須使用顯式類型表達荧嵌。
字符串拼接Concatenation
var message = "Hello" + " my name is "
let name = "Matt"
message += name // "Hello my name is Matt"
還可以向字符串添加字符呛踊。然而,Swift對類型的嚴格要求意味著啦撮,在這樣做時必須顯式谭网,就像處理數(shù)字時必須顯式一樣。
let exclamationMark: Character = "!"
message += String(exclamationMark) // "Hello my name is Matt!"
字符串插值interpolation
message = "Hello my name is \(name)!" // "Hello my name is Matt!"
let oneThird = 1.0 / 3.0
let oneThirdLongString = "One third is \(oneThird) as a decimal." //One third is 0.3333333333333333 as a decimal.
當然赃春,要用無限個字符來表示三分之一的小數(shù)愉择,因為這是一個循環(huán)小數(shù)。雙精度字符串插值無法控制得到的字符串的精度织中。這是使用字符串插值的一個不幸結(jié)果:它使用起來很簡單薄辅,但是沒有提供定制輸出的功能。
字符串格式化輸出
print(String(format:"%.1fkg抠璃,%03d 個站楚,%@ boy, %@ girl",float, num, string, string))
///輸出結(jié)果:1.1kg搏嗡,010 個窿春,lazy boy, lazy girl
多行字符串
let bigString = """
You can have a string
that contains multiple
lines
by
doing this.
"""
print(bigString)
//You can have a string
//that contains multiple
//lines
//by
//doing this.
請注意采盒,多行字符串文字中的兩空間空白被從結(jié)果中刪除旧乞。Swift查看了最后三行雙引號中前導(dǎo)空格的數(shù)量。使用這個作為基線磅氨,Swift要求它上面的所有行至少有那么大的空間尺栖,這樣它就可以從每一行中刪除它。這使您可以使用漂亮的縮進來格式化代碼烦租,而不影響輸出延赌。
元祖-Tuples
有時數(shù)據(jù)是成對或三個一組的。這方面的一個例子是二維網(wǎng)格上的一對(x, y)坐標叉橱。類似地挫以,三維網(wǎng)格上的一組坐標由x值、y值和z值組成窃祝。在Swift中掐松,您可以通過使用tuple以非常簡單的方式表示此類相關(guān)數(shù)據(jù)。
元組是一種類型粪小,它表示由任意類型的多個值組成的數(shù)據(jù)大磺。您可以在元組中擁有任意多的值。例如探膊,可以定義一對二維坐標杠愧,其中每個軸值都是整數(shù),如下所示:
let coordinates: (Int, Int) = (2, 3)
let coordinates = (2, 3) //類型推導(dǎo)
coordinates
的類型是(Int, Int)突想。元組中的值類型(在本例中為Int)由逗號分隔殴蹄,并由圓括號包圍。創(chuàng)建元組的代碼基本相同猾担,每個值由逗號分隔袭灯,并由圓括號包圍。
當然不同類型混合也是可以的:
let coordinatesMixed = (2.1, 3);
如何訪問元組中的數(shù)據(jù)
您可以通過元組中的位置引用每個項绑嘹,從0開始稽荧。
let x1 = coordinates.0
let y1 = coordinates.1
在前面的示例中,索引0處的第一個值是x坐標工腋,索引1處的第二個值是y坐標姨丈,這一點可能不是很明顯。這是另一個說明為什么總是以避免混淆的方式命名變量很重要的例子擅腰。
幸運的是蟋恬,允許您為元組的各個部分命名,并且您可以明確表示每個部分代表什么趁冈。例如:
let coordinatesNamed = (x: 2, y: 3)
// 推導(dǎo)出的類型是 (x: Int, y: Int)
這里歼争,代碼注釋coordinatesNamed的值,以包含元組每個部分的標簽渗勘。
然后沐绒,當你需要訪問元組的每個部分時,你可以通過它的名字訪問它:
let x2 = coordinatesNamed.x
let y2 = coordinatesNamed.y
這更清晰旺坠,更容易理解乔遮。通常,命名元組的組件是有幫助的取刃。
如果你想同時訪問元組的多個部分蹋肮,就像上面的例子一樣,你也可以使用一個簡寫語法來簡化:
let coordinates3D = (x: 2, y: 3, z: 1)
let (x3, y3, z3) = coordinates3D
這將聲明三個新的常量x3璧疗、y3和z3括尸,并依次將元組的每個部分分配給它們。上面的代碼等同于:
let coordinates3D = (x: 2, y: 3, z: 1)
let x3 = coordinates3D.x
let y3 = coordinates3D.y
let z3 = coordinates3D.z
如果想忽略元組的某個元素病毡,可以用下劃線替換聲明的相應(yīng)部分濒翻。例如,如果您正在執(zhí)行一個2D計算啦膜,并且想忽略coordinates3D的z坐標有送,那么您可以編寫如下代碼:
let (x4, y4, _) = coordinates3D
這行代碼只聲明了x4和y4。_是特殊的僧家,表示你現(xiàn)在忽略了這部分雀摘。
其他的數(shù)字類型
你一直用Int
來表示整數(shù)。Int
在大多數(shù)現(xiàn)代硬件上用64位表示八拱,在較老的或資源受限的系統(tǒng)上用32位表示阵赠。Swift提供了更多使用不同存儲量的數(shù)字類型涯塔。對于整數(shù),可以使用顯式符號類型Int8
清蚀、Int16
匕荸、Int32
、Int64
枷邪。這些類型分別消耗1榛搔、2、4和8字節(jié)的存儲空間东揣。每一種類型都使用1位bit來表示符號sign類型践惑。
如果只處理非負值,則可以使用一組顯式無符號unsigned類型嘶卧。這些包括UInt8
尔觉、UInt16
、UInt32
和UInt64
芥吟。雖然不能用這些符號表示負值穷娱,但是額外的1位bit可以表示比帶符號signed的值大兩倍的值。
下面是不同整數(shù)類型及其存儲大小(以字節(jié)為單位)的總結(jié)运沦。大多數(shù)情況下泵额,您只需要使用Int
。
如果您的代碼與另一個使用這些更精確的大小的軟件片段交互携添,或者您需要優(yōu)化存儲大小嫁盲,那么這些代碼將非常有用。
你一直在用Double
表示小數(shù)烈掠。Swift提供了一種Float
類型羞秤,它的范圍和精度都只是Double
的一半,但需要的存儲空間也只需要一半∽蟮校現(xiàn)代硬件已經(jīng)為Double
進行了優(yōu)化瘾蛋,所以它應(yīng)該是您的首選,除非有充分的理由使用Float
矫限。
大多數(shù)情況下哺哼,您將只使用Int和Double來表示數(shù)字,但是您可能偶爾會遇到其他類型叼风。
例如取董,假設(shè)您需要將一個Int16
、一個UInt8
和一個Int32
相加无宿。你可以這樣做:
let a: Int16 = 12
let b: UInt8 = 255
let c: Int32 = -100000
let answer = Int(a) + Int(b) + Int(c) //結(jié)果是Int
協(xié)議簡介
盡管有十幾種不同的數(shù)字類型茵汰,但它們都非常容易理解和使用,因為它們基本上都支持相同的操作孽鸡。換句話說蹂午,一旦您知道如何使用Int栏豺,使用其他的任何一種都很容易。
Swift真正偉大的特性之一是豆胸,它使用所謂的協(xié)議將類型通用性的概念形式化奥洼。通過學(xué)習(xí)協(xié)議,您可以立即了解使用該協(xié)議的整個類型家族是如何工作的配乱。
箭頭表示符合(有時稱為采用)協(xié)議。雖然這個圖沒有顯示整數(shù)類型遵循的所有協(xié)議皮迟,但是它讓您了解了事物是如何組織的搬泥。
Swift是第一種基于協(xié)議的語言。當您開始理解類型背后的協(xié)議時伏尼,您可以使用其他語言無法使用的方式來利用系統(tǒng)忿檩。
翻譯自Raywenderlich的Swift書籍Swift Apprentice