轉自譯者:shockinglee(git主頁)
作爲與Objective-C語言的互操作性的一部分,Swift也保持了一些與C語言的類型和功能的兼容性,如果你的代碼有需要,Swift還提供了使用常見的C結構和模式的方式,如果你的代碼需要的話。
基本數據類型
Swift提供了一些等同於C語言基本類型,如char、int、float和double等。然而,這些類型和Swift核心基本類型之間沒有隱式轉換,如Int。因此,只有你的代碼明確要求它們時再使用這些類型,而Int可以在任何你想使用它的時候使用。
枚舉
Swift引進了Swift枚舉標作爲任何用宏NS_ENUM來標記的C風格的枚舉。這意味着無論枚舉值是在系統框架還是在自定義的代碼中定義的,當他們導入到Swift時,他們的前綴名稱將被截斷。例如,看這個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
- }
當您需要指向一個枚舉值時,使用以點(.)開頭的枚舉名稱:
- //Swift
- let cellStyle: UITableViewCellStyle = .Default
Swift也引進了標有NS_OPTIONS宏選項。而選項的行爲類似於引進的枚舉,選項還可以支持一些位操作,如&,|以及?。在Objective-C中,你用一個空的選項設置標示恆爲零(0)。在Swift中,使用nil代表沒有任何選項。
指針
只要可能,Swift儘可能避免讓您直接訪問指針。然而,當您需要直接操作內存的時候,Swift也爲您提供了多種指針類型。下面的表使用Type作爲佔位符類型名稱來表示語法的映射。
對於參數,以下映射適用:
對於返回類型,變量和參數類型的多層次指針,以下映射應用:
對於類(class)類型,以下映射適用:
當一個函數被聲明爲接受CMutablePointer<Type>參數時,這個函數可以接受下列任何一個類型作爲參數:
1.nil,作爲空指針傳入。
2.一個CMutablePointer<Type>值。
3.一個操作數是Type類型的左值的 in-out 表達式,作爲這個左值的內存地址傳入。
4.一個in-out 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)
C 常指針
當一個函數被聲明爲接受CConstPointer<Type>參數時,這個函數可以接受下列任何一個類型作爲參數:
1.nil,作爲空指針傳入。
2.一個CMutablePointer<Type>, CMutableVoidPointer, CConstPointer<Type>, CConstVoidPointer, 或者在必要情況下轉換成CConstPointer<Type>的AutoreleasingUnsafePointer<Type>值。
3.一個操作數是Type類型的左值的in-out表達式,作爲這個左值的內存地址傳入。
4.一個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>參數時,這個函數可以接受下列任何一個類型作爲參數:
1.nil,作爲空指針傳入。
2.一個AutoreleasingUnsafePointer<Type>值。
3.其操作數是原始的,複製到一個臨時的沒有所有者的緩衝區的一個輸入輸出表達式,該緩衝區的地址傳遞給調用,並返回時,緩衝區中的值加載,保存,並重新分配到操作數。
注:這個列表沒有包含數組。
如果您這樣定義了一個函數:
- //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語言源文件中定義的全局常量會自動地被Swift編譯引進並做爲Swift的全局常量。
預處理指令
Swift編譯器不包含預處理器。取而代之的是,它充分利用了編譯時屬性,生成配置和語言特性來完成相同的功能。因此,Swift沒有引進預處理指令。
簡單宏
在C和Objective-C,您通常使用的#define指令定義的一個基本常數,在Swift,您可以使用全局常量來代替。例如:一個全局定義#define FADE_ANIMATION_DURATION 0.35,在Swift可以使用let FADE_ANIMATION_DURATION = 0.35來更好的表述。由於簡單的用於定義常量的宏會被直接被映射成Swift全局量,Swift編譯器會自動引進在C或Objective-C源文件中定義的簡單宏。
複雜宏
在C和Objective-C中使用的複雜宏在Swift中並沒有副本。複雜宏是那些不用來定義常量的宏,包含帶括號的函數式宏。您在C和Objective-C使用複雜的宏以避免類型檢查的限制,或避免重新鍵入大量的樣板代碼。然而,宏也會產生Bug和重構的困難。在Swift中你可以使用函數和泛型來達到同樣的效果,無需任何的妥協。因此,在C和Objective-C源文件中定義的複雜宏在Swift是不能使用的。
編譯配置
Swift代碼和C、Objective-C代碼被有條件地,以不同方式編輯。SWIFT代碼可以根據生成配置的評價可以有條件地編譯。生成配置包括true和false字面值、命令行標誌以及下表中的平臺測試函數。您可以使用-D <#Flag#>指定命令行標誌。
注意: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代碼也是被進行語法檢查。