Swift 提供了一些和 C 語言的基本類型如 char,int,float,double
等價的 Swift 基本數據類型。然而,這些 Swift 的核心基本類型之間並不能隱式的相互轉換,如 Int
。所以,只有你的代碼明確要求它們時再使用這些類型,而 Int
能夠在任何你想使用它的時候使用。編程
C 類型 | Swift 類型 |
---|---|
bool |
CBool |
char, signed char |
CChar |
unsigned char |
CUnsignedChar |
short |
CShort |
unsigned short |
CUnsignedShort |
int |
CInt |
unsigned int |
CUnsignedInt |
long |
CLong |
unsigned long |
CUnsignedLong |
long long |
CLongLong |
unsigned long long |
CUnsignedLongLong |
wchar_t |
CWideChar |
char16_t |
CChar16 |
char32_t |
CChar32 |
float |
CFloat |
double |
CDouble |
Swift 引進了用宏 NS_ENUM
來標記的任何 C 風格的枚舉類型。這意味着不管枚舉值是在系統框架仍是在自定義的代碼中定義的,當他們導入到 Swift 時,他們的前綴名稱將被截斷。swift
NS_OPTIONS
宏選項。而選項的行爲相似於引進的枚舉,選項還能夠支持一些位操做,如 &,| 和 ~
。在 Objective-C 中,你用一個空的選項設置標示恆爲零 (0)。在 Swift 中,使用 nil 表明沒有任何選項。數組
看這個 Objective-C 枚舉安全
// Objective-C typedef NS_ENUM(NSInteger, UITableViewCellStyle) { UITableViewCellStyleDefault, UITableViewCellStyleValue1, UITableViewCellStyleValue2, UITableViewCellStyleSubtitle };
在 Swift 中這樣來實現框架
// Swift enum UITableViewCellStyle: Int { case Default case Value1 case Value2 case Subtitle }
當你須要指向一個枚舉值時,使用以點 (.) 開頭的枚舉名稱ide
// Swift let cellStyle: UITableViewCellStyle = .Default
Swift 儘量避免讓你直接訪問指針。然而,當你須要直接操做內存的時候,Swift 也爲你提供了多種指針類型。下面的表使用 Type 做爲佔位符類型名稱來表示語法的映射。函數
對於參數,使用如下映射:測試
C 句法 | Swift 句法 |
---|---|
const void * |
CConstVoidPointer |
void * |
CConstPointer<Type> |
const Type * |
CUnsignedChar |
Type * |
CMutablePointer<Type> |
對於返回類型,變量和參數類型的多層次指針,使用如下映射:ui
C 句法 | Swift 句法 |
---|---|
void * |
COpaquePointer |
Type * |
UnsafePointer<Type> |
對於類(class)類型,使用如下映射:命令行
C 句法 | Swift 句法 |
---|---|
Type * const * |
CConstPointer<Type> |
Type * __strong * |
CMutablePointer<Type> |
Type ** |
AutoreleasingUnsafePointer<Type> |
當一個函數被聲明爲接受 CMutablePointer<Type>
參數時,這個函數能夠接受下列任何一個類型做爲參數。
nil
,做爲空指針傳入CMutablePointer<Type>
類型的值Type
類型的左值的輸入輸出表達式,做爲這個左值的內存地址傳入一個輸入輸出 Type[]
值,做爲一個數組的起始指針傳入,而且它的生命週期將在這個調用期間被延長
若是你像這樣聲明瞭一個函數
// Swift func takesAMutablePointer(x: CMutablePointer<Float>) { /*...*/ }
那麼你能夠使用如下任何一種方式來調用這個函數
// Swift var x: Float = 0.0 var p: CMutablePointer<Float> = nil var a: [Float] = [1.0, 2.0, 3.0] takesAMutablePointer(nil) takesAMutablePointer(p) takesAMutablePointer(&x) takesAMutablePointer(&a)
當函數被聲明使用一個 CMutableVoidPointer
參數,那麼這個函數接受任何和 CMutablePointer<Type>
類似類型的 Type
操做數。
若是你這樣定義了一個函數
// Swift func takesAMutableVoidPointer(x: CMutableVoidPointer) { /*...*/ }
那麼你能夠使用如下任何一種方式來調用這個函數
// Swift var x: Float = 0.0, y:Int = 0 var p: CMutablePointer<Float> = nil, q: CMutablePointer<Int> = nil var a: [Float] = [1.0, 2.0, 3.0], b: Int = [1, 2, 3] takesAMutableVoidPointer(nil) takesAMutableVoidPointer(p) takesAMutableVoidPointer(q) takesAMutableVoidPointer(&x) takesAMutableVoidPointer(&y) takesAMutableVoidPointer(&a) takesAMutableVoidPointer(&b)
當一個函數被聲明爲接受 CConstPointer<Type>
參數時,這個函數能夠接受下列任何一個類型做爲參數。
nil
,做爲空指針傳入CMutablePointer<Type>,CMutableVoidPointer,CConstPointer<Type>,CConstVoidPointer
,或者在必要狀況下轉換成 CConstPointer<Type>
的 AutoreleasingUnsafePointer<Type>
值Type
類型的左值的輸入輸出表達式,做爲這個左值的內存地址傳入一個 Type[]
數組值,做爲一個數組的起始指針傳入,而且它的生命週期將在這個調用期間被延長
若是你這樣定義了一個函數
// Swift func takesAConstPointer(x: CConstPointer<Float>) { /*...*/ }
那麼你能夠使用如下任何一種方式來調用這個函數
// Swift var x: Float = 0.0 var p: CConstPointer<Float> = nil takesAConstPointer(nil) takesAConstPointer(p) takesAConstPointer(&x) takesAConstPointer([1.0, 2.0, 3.0])
當函數被聲明使用一個 CConstVoidPointer
參數,那麼這個函數接受任何和 CConstPointer<Type>
類似類型的 Type
操做數。
若是你這樣定義了一個函數
// Swift func takesAConstVoidPointer(x: CConstVoidPointer) { /*...*/ }
那麼你能夠使用如下任何一種方式來調用這個函數
// Swift var x: Float = 0.0, y: Int = 0 var p: CConstPointer<Float> = nil, q: CConstPointer<Int> = nil takesAConstVoidPointer(nil) takesAConstVoidPointer(p) takesAConstVoidPointer(q) takesAConstVoidPointer(&x) takesAConstVoidPointer(&y) takesAConstVoidPointer([1.0, 2.0, 3.0]) takesAConstVoidPointer([1, 2, 3])
當一個函數被聲明爲接受 AutoreleasingUnsafePointer<Type>
參數時,這個函數能夠接受下列任何一個類型做爲參數。
nil
,做爲空指針傳入AutoreleasingUnsafePointer<Type>
值其操做數是原始的,複製到一個臨時的沒有全部者的緩衝區的一個輸入輸出表達式,該緩衝區的地址傳遞給調用,並返回時,緩衝區中的值加載,保存,並從新分配到操做數。
注意:這個列表沒有包含數組。
若是你這樣定義了一個函數
// Swift func takesAnAutoreleasingPointer(x: AutoreleasingUnsafePointer<NSDate?>) { /*...*/ }
那麼你能夠使用如下任何一種方式來調用這個函數:
// Swift var x: NSDate? = nil var p: AutoreleasingUnsafePointer<NSDate?> = nil takesAnAutoreleasingPointer(nil) takesAnAutoreleasingPointer(p) takesAnAutoreleasingPointer(&x)
注意:C 語言函數指針沒有被 Swift 引進。
在 C 和 Objective-C 中一般使用的 #define
指令定義的一個宏常數,在 Swift 中能夠使用全局常量來代替。因爲簡單的用於定義常量的宏會被直接被映射成 Swift 全局量,Swift 編譯器會自動引進在 C 或 Objective-C 源文件中定義的簡單宏。
例如: 一個全局定義 #define FADE_ANIMATION_DURATION 0.35
,在 Swift能夠使用 let FADE_ANIMATION_DURATION = 0.35
來更好的表述。
Swift 代碼和 Objective-C 代碼以不一樣的方式進行條件編譯。Swift 代碼能夠根據生成配置的評價配進行有條件的編譯。生成配置包括 true
和 false
字面值,命令行標誌,和下表中的平臺測試函數。你能夠使用 -D <#Flag#>
指定命令行標誌。
函數 | 有效參數 |
---|---|
os() |
OSX, iOS |
arch() |
x86_64, arm, arm64, i386 |
arch(arm)
的生成配置不會爲 64 位 arm 設備返回 true
,當代碼運行在爲 32 位的 iOS 模擬器器時,arch(i386)
的生成配置返回 true
。一個簡單的條件編譯須要如下代碼格式。
#if build configuration statements #else statements #endif
一個由零個或多個有效的 Swift 語句聲明的 statements
,能夠包括表達式,語句和控制流語句。你能夠添加額外的構建配置要求,條件編譯說明用 &&
和 ||
操做符以及 !
操做符,添加條件控制塊用 #elseif
。
#if build configuration && !build configuration statements #elseif build configuration statements #else statements #endif
與 C 語言編譯器的條件編譯相反,Swift 條件編譯語句必須徹底是自包含和語法有效的代碼塊。這是由於 Swift 代碼即便沒有被編譯,也要所有進行語法檢查。