Fork me on GitHub

新手指南

本文將會教你如何開始使用 Swift 程式語言。

如果你從沒用過 Swift ,請參考Swift 程式語言 中的 A Swift Tour(英文) ,來快速了解 Swift 最重要的概念和功能。

安裝 Swift

第一步是下載並安裝 Swift 編譯器和其它必要的元件。請至下載頁面,參考你的作業系統平台的說明。

為了讓下面的範例能正常運作,請將 Swift 加進你的$PATH

在OS X上

在OS X上,工具鏈的預設位置是/Library/Developer/Toolchains 。你可以使用以下指令讓 Swift 能在終端機中使用:

$ export PATH=/Library/Developer/Toolchains/swift-latest.xctoolchain/usr/bin:"${PATH}"

在Linux上

首先,安裝Clang:

$ sudo apt-get install clang

如果 Swift 工具鏈不是安裝在Linux的系統根目錄時, 則需要執行下面的指令,將其中的 /path/to/Swift/ 改為你實際的 Swift 安裝路徑:

$ export PATH=/path/to/Swift/usr/bin:"${PATH}"

你可以透過 swift --version 來確認你執行的 Swift 版本

$ swift --version
Apple Swift version 2.2-dev (LLVM ..., Clang ..., Swift ...)

版本號上的-dev代表它開發版 ,而不是正式發行版。

使用REPL

如果你不帶參數地執行swift ,REPL就會啟動,它是一個互動式的shell,可以執行你輸入的 Swift 程式。

$ swift
Welcome to Apple Swift version 2.2. Type :help for assistance.
  1>

使用 REPL 是體驗 Swift 的好方法。 舉例來說,如果你輸入 1 + 2, 就會在下一行顯示運算結果 3 :

  1> 1 + 2
$R0: Int = 3

你可以定義常數和變數,然後使用它們。例如,可以定義String Hello, world!為常數greeting ,然後當作參數傳給print(_:) 函式:

  2> let greeting = "Hello!"
greeting: String = "Hello!"
  3> print(greeting)
Hello!

如果輸入一個無效的運算式,REPL會標示出有錯誤的地方:

let answer = "forty"-"two"
error: binary operator '-' cannot be applied to two 'String' operands
let answer = "forty"-"two"
             ~~~~~~~^~~~~~

你可以使用上下方向鍵來使用之前輸入過的程式碼。讓你可以對之前輸入的程式碼做小修改,用來修改像上一個例子中的錯誤時特別方便:

let answer = "forty-two"
answer: String = "forty-two"

REPL 的另一個好用的功能是自動完成。例如在一個String執後面輸入.re,然後按下tab(⇥)鍵,REPL會列出可能的選項,像是removeAtIndex(_:)replaceRange(_:with:)

5> "Hi!".re⇥
Available completions:
	removeAll() -> Void
	removeAll(keepCapacity: Bool) -> Void
	removeAtIndex(i: Index) -> Character
	removeRange(subRange: Range<Index>) -> Void
	replaceRange(subRange: Range<Index>, with: C) -> Void
	replaceRange(subRange: Range<Index>, with: String) -> Void
	reserveCapacity(n: Int) -> Void

如果你開始了一個程式區塊, 比方說for-in,REPL會自動縮排下一行,並把提示字元從>改成.來提示這段程式只有在整個程式區塊完成後才會被執行。

  6> let numbers = [1,2,3]
numbers: [Int] = 3 values {
  [0] = 1
  [1] = 2
  [2] = 3
}
  7> for n in numbers.reverse() {
  8.     print(n)
  9. }
3
2
1

REPL 包含完整的 Swift 功能,從控制流程到定義 Struct 和 Class。

你還可以import任何可用的系統 module,如OS X上的Darwin和Linux上的Glibc

OS X上

1> import Darwin
2> arc4random_uniform(10)
$R0: UInt32 = 4

Linux上

1> import Glibc
2> random() % 10
$R0: Int32 = 4

使用Build System

Swift 的 build system 讓大家可以 build 函式庫和執行檔,還有在各 Project 間共用程式碼.

這些範例需要你將swift加到你的 path 中;方法請看安裝。設定好後,你就可以使用swift build 來執行 build system:

$ swift build --help
OVERVIEW: Build sources into binary products
...

建立一個 Package

要建立一個新 Swift Package,首先要建立一個Hello 資料夾並進入它:

$ mkdir Hello
$ cd Hello

每個 Package 都必須在它的根目錄有一個名為Package.swift的資訊清單檔。如果資訊清單檔是空白的,Package Manager會使用慣例的預設值來build Package。建立空的Package.swift :

$ touch Package.swift

當使用預設值時,Package Manager 預期所有程式碼都在Sources/目錄中。建立 Sources 資料夾:

$ mkdir Sources

Build 一個執行檔

預設情況下,會將程式碼資料夾內的main.swift編譯成執行檔,檔名就是 Package 名稱。

在這個例子中,編譯來出的Hello執行檔會輸出"Hello, world!" 。

Sources/目錄下建立一個名為main.swift的檔案,並使用你喜歡的編輯器輸入以下程式碼:

print("Hello, world!")

使用swift build指令來編譯 Package:

$ swift build

指令完成後,編譯的成品會放在.build目錄。使用下面的指令來執行Hello程式:

$ .build/debug/Hello
Hello, world!

再來,讓我們在另一個檔案定義一個sayHello(_:)函式,再讓執行檔呼叫他,而不是直接呼叫print(_:)

使用多個程式檔

Sources/目錄下建立一個新的Greeter.swift檔案並輸入以下程式碼:

func sayHello(name: String) {
    print("Hello, \(name)!")
}

sayHello(_:)函式只有一個String參數,會輸出 Hello 加上傳入的參數。

現在打開main.swift,並把之前的內容更換成下面程式碼:

if Process.arguments.count != 2 {
    print("Usage: hello NAME")
} else {
    let name = Process.arguments[1]
    sayHello(name)
}

main.swift現在會讀取command line參數而不是像以前那樣使用寫死的名字。而且main.swift現在不會直接呼叫print(_:)而是呼叫sayHello(_:)函式。因為這個函式是Hello module 的一部分,我們不需要import它。

執行swift build與試試新的Hello程式

$ swift build
$ .build/debug/Hello `whoami`

要了解更多有關 Swift Package Manager,包括如何build module,import dependencies,以及使用系統函式庫,請參考Swift Package Manager

使用LLDB Debugger

你可以使用LLDB debugger 來一步一步地執行 Swift 程式,設置中斷點,檢查和修改程式狀態。

下面的 Swift 例子會定義一個factorial(_:)函式,並輸出呼叫該函式的結果:

func factorial(n: Int) -> Int {
    if n <= 1 { return n }
    return n * factorial(n - 1)
}

let number = 4
print("\(number)! is equal to \(factorial(number))")

將上面的程式碼存成一個名為 Factorial.swift 檔案,並執行swiftc,將檔案名當​​作參數,同時使用-g選項產生除錯資訊。這樣會在現在的目錄下產生一個Factorial執行檔。

$ swiftc -g Factorial.swift
$ ls
Factorial.dSYM
Factorial.swift
Factorial*

不要直接執行Factorial,改為把它當成參數來透過lldb執行它。

$ lldb Factorial
(lldb) target create "Factorial"
Current executable set to 'Factorial' (x86_64).

這會啟動一個互動式 console,可以執行LLDB指令。

有關LLDB指令的詳細資訊,請參閱LLDB教學(英文)

使用breakpoint set (b)指令來在factorial(_:)函數第二行設定中斷點,這樣每次執行這個函式的時候就會暫停。

(lldb) b 2
Breakpoint 1: where = Factorial`Factorial.factorial (Swift.Int) -> Swift.Int + 12 at Factorial.swift:2, address = 0x0000000100000e7c

使用run (r)來執行程式。程式會在factorial(_:)函式處暫停。

(lldb) r
Process 40246 resuming
Process 40246 stopped
* thread #1: tid = 0x14dfdf, 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2
   1    func factorial(n: Int) -> Int {
-> 2        if n <= 1 { return n }
   3        return n * factorial(n - 1)
   4    }
   5
   6    let number = 4
   7    print("\(number)! is equal to \(factorial(number))")

使用print (p)來檢查參數n的值。

(lldb) p n
(Int) $R0 = 4

print也可以用來直接執行 Swift 程式碼。

(lldb) p n * n
(Int) $R1 = 16

backtrace (bt)可以顯示factorial(_:)被呼叫的 frame。

(lldb) bt
* thread #1: tid = 0x14e393, 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2
    frame #1: 0x0000000100000daf Factorial`main + 287 at Factorial.swift:7
    frame #2: 0x00007fff890be5ad libdyld.dylib`start + 1
    frame #3: 0x00007fff890be5ad libdyld.dylib`start + 1

使用continue (c)來繼續執行直到下一個中斷點。

(lldb) c
Process 40246 resuming
Process 40246 stopped
* thread #1: tid = 0x14e393, 0x0000000100000e7c Factorial`Factorial.factorial (n=3) -> Swift.Int + 12 at Factorial.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100000e7c Factorial`Factorial.factorial (n=3) -> Swift.Int + 12 at Factorial.swift:2
   1    func factorial(n: Int) -> Int {
-> 2        if n <= 1 { return n }
   3        return n * factorial(n - 1)
   4    }
   5
   6    let number = 4
   7    print("\(number)! is equal to \(factorial(number))")

再使用一次print (p)來檢查第二次呼叫factorial(_:)時參數n的值。

(lldb) p n
(Int) $R2 = 3

breakpoint disable (br di)可以關閉所有中斷點,再用continue (c)讓程式執行到結束。

(lldb) br di
All breakpoints disabled. (1 breakpoints)
(lldb) c
Process 40246 resuming
4! is equal to 24
Process 40246 exited with status = 0 (0x00000000)

現在你應該稍微了解 Swift REPL,build system 和 debugger了,再來你可以參考下面的頁面: