第1章 未來的iOS開發(fā)語言Swift語言介紹
蘋果(Apple)公司最近動作還是比較多的,除了即將推出的iWatch 等新硬件產(chǎn)品外,還推出了一種新的編程語言Swift。可能初次接觸蘋果軟件開發(fā)的程序員對Swift還很陌生,當然,這也不奇怪,因為在寫這本書時,Swift才剛剛推出。不過,由于Swift出身貴族,這也注定了Swift將擁有一個美好的未來,很可能成為蘋果軟件開發(fā)體系的中堅力量。既然Swift如此重要,作為求知欲極強的程序員們怎能放過這么一個成為國內(nèi),不!應該說世界上首批Swift專家的機會呢!現(xiàn)在就讓我們開啟Swift語言的開發(fā)之旅吧!
本章要點
□ Swift語言簡介
□ Swift開發(fā)環(huán)境搭建
□ 創(chuàng)建Swift工程
□ 編寫一段簡單的Swift語言代碼
□ 所見即所得的Playground
1.1 Swift語言的前世今生
在2014年的蘋果WWDC大會上,最大的亮點當屬Swift的出現(xiàn)了。因為蘋果一貫以硬件為主,這次突然弄出了軟件,而且還是生產(chǎn)軟件的軟件:Swift語言。自然會引起各方的廣泛關注。國內(nèi)外在 24 小時內(nèi)推出了大量關于Swift語言的學習資料,甚至視頻 。我就從來沒看過一種新技術被如此關注過,因為當年我趕上了微軟C#的首發(fā)、還有Google的Go語言首發(fā),關注度都沒有Swift語言高,看來業(yè)界對這個一直玩硬件的蘋果突然推出一種新編程語言還是很看好的。這么說當然是有證據(jù)的,就在Swift語言剛推出不到一個月的時間里,已經(jīng)排到了編程語言的第16位,這在以前從未發(fā)生過。
既然說到Swift語言,那么就必須要提一下Swift的發(fā)明者Chris Lattner(可以叫他克里斯),Chris博士畢業(yè),是一個全面發(fā)展的好學生。
據(jù)說Chris最喜歡看的IT著作是龍書,還喜歡在旅游時帶這本書。別人旅游時都看小說或看Video,這家伙卻看編譯原理的書,的確高大上。高手就是與別人不一樣(就在寫這本書時,我已經(jīng)將龍、虎、鯨3本書的英文電子版放到平板電腦里了,準備旅游時看)。
下面主要來談談Chris的光榮事跡。Chris在碩士畢業(yè)時提出了一套完整的運行時編譯思想,奠定了LLVM 的發(fā)展基礎。在博士期間繼續(xù)領導LLVM編譯框架向前發(fā)展,并取得了長足的進步。LLVM已經(jīng)可以基于 GCC 前端編譯器的語義分析結果進行編譯優(yōu)化和代碼生成,所以,Chris在2005年畢業(yè)時已經(jīng)是業(yè)界知名的編譯器專家了。
蘋果在2005年雇傭了Chris。Chris在蘋果的幾年中不僅大幅度優(yōu)化和改進LLVM以適應Objective-C的語法變革和性能要求,同時發(fā)起了CLang項目,旨在全面替換GCC,現(xiàn)在這個目標已經(jīng)實現(xiàn)了。從OS X 10.9和XCode 5開始,LLVM+GCC已經(jīng)被替換成了LLVM+CLang。
在2010年,Chris接到了一個不同尋常的任務,就是為iOS和OS X平臺開發(fā)下一代的編程語言,這就是現(xiàn)在看到的Swift。最初Swift完全是由Chris開發(fā)的。只是在一年后(2011年),才陸續(xù)有若干編譯器專家加入了Swift團隊。終于在4年后的2014年,Swift的第一個版本在蘋果的2014年WWDC大會上向我們展示了她的魅力。
1.2 Swift到底是怎樣的一種語言
Swift是一門博采眾長的現(xiàn)代語言,在設計的過程中,Chris參考了Objective-C、Rust、Haskell、Ruby、Python、C#等優(yōu)秀語言的特點,最終形成了目前Swift的語法特性。這也是為什么使用各種語言的程序員都能從Swift中找到自己熟悉的影子的原因。那么,Swift語言到底是一種怎樣的語言??梢詮南旅鎺追矫娉醪搅私庖幌耂wift語言。
(1)Swift是面向?qū)ο蟮?、編譯型語言。編譯時底層需要通過LLVM 生成本地代碼才能執(zhí)行,所以效率還是很高的。
(2)Swift可以使用Cocoa和Cocoa Touch中的API。這也就意味著Swift與Objective-C一樣,擁有了一個強大的Framework Library。
(3)Swift吸取了很多編程語言的優(yōu)點,同時Swift又具備了很多動態(tài)語言的語法特性和交互方式,當然,Swift本身是靜態(tài)語言。所以,Swift盡可能地在靜態(tài)語言和動態(tài)語言之間尋找平衡點。
(4)既然說Swift是一種擁有動態(tài)特性的靜態(tài)語言,那么Swift自然就是一門類型安全的語言。編譯器可以在編譯過程中檢測出類型異常。例如,如果你期望為一個字符串變量賦值,那么類型安全機制會阻止你為這個變量設置整數(shù)。正是由于類型安全機制的存在,使開發(fā)者可以更早地發(fā)現(xiàn)并修復錯誤。
(5)支持各種高級語言特性,包括閉包、泛型、面向?qū)ο?、多返回值、類型接口、元組、集合等。
(6)Swift能與Objective-C進行混合編程,但代碼分屬不同的文件。
(7)全面支持Unicode編碼。也就是說,可以用任何想用的字符作為變量名,例如,一個笑臉字符或漢字。圖1-1就是使用笑臉圖標和漢字作為變量名的一個典型例子。
▲圖1-1 使用笑臉圖標和漢字作為變量名
(8)使分號(;)變成了可選的符號。通常的靜態(tài)語言,如Java、C#。每條語句結束后,都會在最后加上“;”,而Swift的每條語句不需要加“;”,當然,加上也沒問題。只有在兩條或多條語句寫在同一行時才必須加“;”。
(9)簡化和增強了集合數(shù)據(jù)類型。用過Java和C#的讀者知道。在這兩種語言中,各種集合類型不可謂不全,但太多也有它不好的地方,就是不知道使用哪個。而且這些集合數(shù)據(jù)類型的功能也不夠強大。在Swift語言中只提供了數(shù)組(Array)和字典(Dictionary)兩個集合數(shù)據(jù)類型。其中Array類似List的功能,可以修改、添加、替換和刪除數(shù)組元素。Dictionary類似Map的功能,用于存儲Key-Value 風格的值。
(10)Swift可以通過元組實現(xiàn)函數(shù)返回多個值。這一功能在其他語言中需要通過返回一個對象或結構體(指針)來實現(xiàn)。
(11)提供了優(yōu)雅的閉包解決方案。例如,在排序函數(shù) sort 中可以將函數(shù)作為參數(shù)值傳遞。下面的代碼是一種典型的寫法:
let array1 = ["X", "A", "1", "2", "Z"]
func backwards(s1: String, s2: String) -> Bool
{
return s1 > s2
}
var array2 = sort(array1, backwards)
當然,更簡潔的寫法是var array2 = sort(["X", "A", "1", "2", "Z"] ) { $0 > $1 },如果讀者不明白這么寫是什么意思,那么就繼續(xù)往后看吧!
(12)Swift語言中提供了一種可選變量(Optional)。主要是為了應對一個變量可能存在,也可以是 nil 的情況。例如,將一個字符串(String)轉換為整數(shù)(Int),但這個字符串是否可以成功轉換為整數(shù)呢?如果不確定,就返回一個可選變量。如果成功轉換,則返回正常的整數(shù)值;如果轉換失敗,則返回nil。實現(xiàn)的代碼如下:
let str = "126CB5"
let value = str.toInt() // value是一個可選常量(用let聲明是常量,用var聲明是變量)
這時,value就是一個可選變量。要想判斷轉換是否成功,可以使用下面的代碼:
if value
{
// 如果value是可選變量,引用時需要加上“!”,
// 表示該選項變量中肯定有一個值
println(value!)
}
可選變量的引入解決了大部分需要顯式處理的異常,這部分工作也扔給編譯器去做了。
(13)擁有不同意義的nil。在Swift中的nil和Objective-C中的nil不同。在Objective-C中,nil是指向不存在對象的指針,而在Swift里,nil不是指針,它表示特定類型的值不存在。所有類型的可選值都可以被設置為nil,不僅是對象類型。
(14)Swift中沒有從語言層面支持異步和多核,不過可以直接在Swift中復用GCD(Grand Central Dispatch)的API實現(xiàn)異步功能。
(15)Swift沒有一部處理機制??赡苁钦J為有了可選變量,異常會很少使用,所以未加入異常處理。
1.3 Swift開發(fā)環(huán)境搭建
盡管Swift語言擁有獨立的編譯器,不過,目前Apple并沒有單獨發(fā)布Swift開發(fā)包。所以只能連同XCode 6一起安裝來使用Swift語言。由于XCode 6仍然是Beta版,所以,Apple并未對所有的人開放下載XCode 6,只有擁有蘋果開發(fā)者賬號 的用戶才允許下載XCode 6 Beta版。如果讀者不舍得那99美金也不要緊,我已經(jīng)將XCode 6 Beta的安裝文件上傳到的網(wǎng)盤,下載地址是http://pan.baidu.com/s/1hq7mAOk,下載后是一個dmg文件(2.33G左右),直接在Mac OS X下雙擊安裝即可。XCode 6是可以和Xcode 5或其他版本共存的,所以不必擔心,盡管安裝。
安裝完后,在 Mac的“應用程序”列表中多了一個“Xcode6-Beta.app”,直接雙擊運行即可。成功運行后,點擊XCode6中的“Xcode”>“About Xcode”菜單項,如果能看到如圖1-2 所示的窗口,并且 Version 顯示的是 6.0,則說明 XCode6 已經(jīng)安裝成功了。

▲圖1-2 XCode 6的About 窗口
1.4 創(chuàng)建Swift工程(OS X和iOS平臺)
Swift 語言可以開發(fā) iOS 和 OS X 兩個平臺的程序,讀者可以選擇自己喜歡的平臺學習Swift語言。如果有蘋果開發(fā)者賬號的,最好選擇iOS平臺,因為可以在iPhone上測試全部的功能。如果沒有開發(fā)者賬號,可以考慮選擇OS X 平臺,否則就只能在iOS模擬器上測試Swift 程序了。不管是創(chuàng)建哪個類型的工程,首先需要點擊“File”>“New”>“Project”菜單項打開如圖1-3所示的工程模板選擇窗口。

▲圖1-3 創(chuàng)建 iOS 工程
如果選擇iOS平臺,通常選擇“Application”,然后在右側工程模板列表中選擇一個,如“Single View Application”,如 圖1-3所示。
如果讀者選擇 OS X 平臺,可以選擇“Application”,并在右側的工程模板列表中選擇“Command Line Tool”(一個終端工程模板),如圖1-4所示。

▲圖1-4 創(chuàng)建Mac工程
接下來可以點擊“Next”按鈕進入下一步的設置。在下一步中需要輸入工程名和工程支持的語言(為了測試方便,這里選擇了OS X 平臺,等涉及iOS 部分時,再創(chuàng)建iOS 工程)。當然,我們需要選擇“Swift”,如圖1-5所示,然后點擊“Next”按鈕進入下一步。在下一步中需要選擇一個用于存放工程的目錄,選擇完成后,點擊“Create”按鈕,就會創(chuàng)建一個OS X工程。

▲圖1-5 建立 iOS工程,選擇 Swift 語言
圖1-5是OS X 工程的機構,其中新創(chuàng)建了一個main.swift文件。該文件用于輸入Swift語言的代碼。
在main.swift文件中默認生成了如下的代碼:
import Foundation
println("Hello, World!")
直接運行該工程,就會在輸出視圖中輸出“Hello, World!”。
如果讀者要建立 iOS for Swift 工程,這里假設選擇了圖1-3 所示的“Single View Application”模板,在下一個設置頁面輸入工程名(如 first_swift_ios)后再進入下一個設置頁面,選擇存儲目錄后可創(chuàng)建iOS工程,工程結構如圖1-7所示。
▲圖1-6 OS X 工程結構
▲圖1-7 iOS 工程結構
如果運行這個工程,首先會啟動iOS模擬器(要選擇iOS8模擬器),然后在模擬器中會運行一個 iOS 程序,該程序并沒有任何 UI,背景為白色。本書后面的章節(jié)會介紹如何使用Swift開發(fā)iOS應用和游戲。
對于只想學習一下Swift語言的讀者,建議還是使用OS X終端程序為好,因為OS X終端程序運行快速簡單,可以排除其他的干擾。
1.5 瞧一瞧Swift到底長啥樣
可能很多讀者看到前面的介紹后躍躍欲試,想試一試 Swift 語言,不過先別忙,在正式編寫Swift語言之前,先了解一下Swift語言的語法和樣式是非常必要的。就像搞對象,起碼得先看看對方長啥樣,然后才能進行下一步?,F(xiàn)在就讓我們看看Swift到底長啥樣。
Swift 語言和其他語言(如 Java、C#、Objective-C)類似,也支持一些常規(guī)的操作和語法元素,例如,運算符(+、?、*、/、%、++、&&、||等)、數(shù)據(jù)類型(字符串、數(shù)值等)、控制語句(if、switch、for)、類、方法(函數(shù))等。不過 Swift 添加了很多特有的語法元素(至少是大多數(shù)語言都不具備的技術),例如,類擴展、增強的switch語句、小標、元組類型、返回多種的方法(函數(shù))等。下面是一段標準的Swift語言代碼,盡管沒有枚舉Swift中所有的新特性,但足夠讓我們充分了解 Swift 語言的基本語法規(guī)則。如果讀者對某些表達式不理解也沒關系,在后面的章節(jié)會深入介紹這些特有的語法規(guī)則。
import Foundation
var value1 = 20 // 定義并初始化一個整型變量
value1 += 35
// 輸出:value1=55
println("value1=\(value1)")
let value2 = 42 // 定義并初始化一個整型常量
// 輸出:97
println(value1 + value2)
// 定義并初始化一個數(shù)組變量
var array1 = ["abc","bbb","ccc"]
// 枚舉數(shù)組中的每一個元素值
// 輸出:abc bbb ccc
for element in array1
{
print(element + " ")
}
// 定義函數(shù),返回值類型是String
func getPerson(name: String, age:Int) -> (String)
{
return "name:" + name + " age:" + toString(age)
}
println()
// 調(diào)用getPerson函數(shù)
let person = getPerson("bill", 50)
// 輸出:person:name:bill age:50
println("person:\(person)")
// 定義一個可以返回多個值的函數(shù)(返回兩個值:name和price)
func getProduct() -> (name:String, price:Float)
{
return ("iPhone6", 6666.66)
}
// 輸出:(iPhone6, 6666.66015625)
// 調(diào)用getProduct函數(shù),并輸出其返回值
println(getProduct())
// 輸出:product name: iPhone6
// 輸出getProduct函數(shù)返回name值
println("product name: \(getProduct().name)")
// 定義Country類
class Country
{
var name = "China"
let area: Float = 960
// 定義一個成員方法
func getDescription() -> String {
return "Country:\(name) Area:\(area)"
}
}
// 創(chuàng)建一個Country類型的常量
let country = Country()
// 輸出:Country:China Area:960.0
// 調(diào)用Country.getDescritpion方法,并輸出該方法的返回值
println(country.getDescription())
// 定義一個類擴展,相當于將一個類的某一部分拿出來單獨定義
extension Country
{
// 為Country類添加一個方法
func getAddress() -> (planet: String, location:String)
{
return ("Earth","Asia")
}
}
// 輸出:Planet:Earth
// 調(diào)用擴展方法getAddress,并輸出返回值中的planet
println("Planet:\(country.getAddress().planet)")
// 輸出:Location:Asia
// 調(diào)用擴展方法getAddress,并輸出返回值中的location
println("Location:\(country.getAddress().location)")
如果執(zhí)行上面這段代碼,會輸出如下的信息。
value1=55
97
abc bbb ccc
person:name:bill age:50
(iPhone6,6666.66015625)
productname: iPhone6
Country:China Area:960.0
Planet:Earth
Location:Asia
1.6 所見即所得的Playground
XCode 6新增加了一個Playground,在iOS和OS X工程中都可以使用Playground。這個東西其實就是一個所見即所得的寫代碼的文件。這里的所見即所得就是編寫代碼后,不需要運行,立刻會顯示出結果,并且還可以顯示出代碼中某個變量/常量的當前值。Playground比較適合于測試Swift語言的代碼。但Playground在輸出結果時可能會有些慢,而且寫代碼時會有些遲鈍。這可能是因為需要實時解釋Swift代碼的原因!
要想使用 Playground,需要先創(chuàng)建 Swift 工程(iOS 和 OS X 工程都可以),然后在當前工程中點擊“File”>“New”>“File”菜單項,會彈出一個如圖1-8所示的窗口。在“iOS”和“OS X”中都有一個“source”節(jié)點,在該節(jié)點中都有一個“Playground”模板。不管是什么工程,選擇哪個“source”節(jié)點下的“Playground”都可以。

▲圖1-8 選擇“Playground”模板
選擇“Playground”模板后,進入下一個設置頁面。在該設置頁面中需要選擇playground文件的存儲目錄,通常和 Swift 文件放在同一個目錄中。如果下方的“Targets”列表中的工程未選擇,需要選擇該工程,效果如圖1-9所示。

▲圖1-9 創(chuàng)建 Playground 文件
如果成功創(chuàng)建了Playground文件,在工程目錄中會多了一個文件擴展名為“playground”的文件。默認是 MyPlayground.playground。如果讀者將上一節(jié)的代碼都復制到MyPlayground.playground文件中,就會在代碼右側輸出相應的結果,并且在輸出結果和代碼之間的部分還會顯示當前變量/常量的當前值,效果如圖1-10所示。

▲圖1-10 Playground 的效果
1.7 小結
相信看完本章后,讀者已經(jīng)對 Swift 語言有了一個大致的了解。也學會了如何搭建實驗環(huán)境。不過真正的Swift開發(fā)之旅才剛剛開始。后面還有Swift的語法、內(nèi)置函數(shù)、iOS應用程序開發(fā)、基于SpriteKit游戲引擎的游戲程序開發(fā)等知識要學習。下面就讓我們整裝待發(fā),去欣賞Swift給我們的一次又一次震撼吧!