本篇分為兩部分:
一、Swift中的可變參數函數
二、初始化方法的順序
一、Swift中的可變參數函數
可變參數函數指的是可以接受任意多個參數的函數,在 OC 中,拼接字符串的函數就屬於可變參數函數
NSString *name = @"Tom"; NSDate *date = [NSDate date]; NSString *string = [NSString stringWithFormat: @"Hello %@. Date: %@", name, date];
在 swift 中定義可變參數函數:
func sum(input: Int...) -> Int { return input.reduce(0, combine: +) } print("result:\(sum(1,2,3,4,5))")
輸出結果:
注意:可變參數只能作為方法中的最后一個參數來使用,而不能先聲明一個可變參數,然后再聲明其他參數。因為編譯器不知道輸入的參數應該從哪里截斷。另外,在一個方法中,最多只能有一組可變參數。而且傳入的可變參數必須是所指定的類型。
Swift 提供了使用下划線 _ 來作為參數的外部標簽,來使調用時不再需要加上參數名字。我們可以利用這個特性,在聲明方法時就指定第一個參數為一個字符串,然后跟一個匿名的參數列表,這樣在寫起來的時候就好像是所有參數都是在同一個參數列表中進行的處理。
比如:進入到 Swift 中, 就會看到 NSString 格式化的聲明就是這樣處理的:
extension NSString { convenience init(format: NSString, _ args: CVarArgType...) { self.init() } //... }
調用的時候就和在 OC 時幾乎一樣了,非常方便:
let name = "Tom" let date = NSDate() let string = NSString(format: "Hello %@. Date: %@", name, date)
二、初始化方法的順序
讓我們在 Swift 開發中最不習慣的問題之一可能就包含 Swift 的初始化方法需要保證類型的所有屬性都被初始化,所以初始化方法的調用順序就很有講究。我們在保證當前子類實例的成員初始化完成后才能調用父類的初始化方法:
class Animal { var name: String? init() { name = "Animal" } } let animal = Animal() print(animal.name) class Dog: Animal { let age: Int override init() { age = 10 // 如果不先把子類的成員初始化完成,下面就無法調用父類的初始化方法會報錯,Swift 會自動的對父類的對應 init 方法進行調用,如果不需要改變父類屬性的話,可以不寫 super.init() // Property 'self.age' not initialized at super.init call name = "a dog" // 根據實際情況修改 } } print(Dog().name)
綜上,子類的初始化順序是:
1.設置子類自己需要初始化的參數,age = 10 (是條老狗了)
2.調用父類的相應的初始化方法, super.init() (Swift 會自動的對父類的對應 init 方法進行調用,可以不寫)
3.對父類中需要改變的成員進行設定, name = "a dog" (根據實際情況修改)