你可以通過輸入?yún)?shù)和可選屬性類型來定制構(gòu)造過程,也可以在構(gòu)造過程中修改常量屬性。這些都將在后面章節(jié)中提到。
你可以在定義構(gòu)造器時(shí)提供構(gòu)造參數(shù),為其提供定制化構(gòu)造所需值的類型和名字。構(gòu)造器參數(shù)的功能和語法跟函數(shù)和方法參數(shù)相同。
下面例子中定義了一個(gè)包含攝氏度溫度的結(jié)構(gòu)體Celsius。它定義了兩個(gè)不同的構(gòu)造器:init(fromFahrenheit:)和init(fromKelvin:),二者分別通過接受不同刻度表示的溫度值來創(chuàng)建新的實(shí)例:
struct Celsius {
var temperatureInCelsius: Double = 0.0
init(fromFahrenheit fahrenheit: Double) {
temperatureInCelsius = (fahrenheit - 32.0) / 1.8
}
init(fromKelvin kelvin: Double) {
temperatureInCelsius = kelvin - 273.15
}
}
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius 是 100.0
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius 是 0.0”
第一個(gè)構(gòu)造器擁有一個(gè)構(gòu)造參數(shù),其外部名字為fromFahrenheit,內(nèi)部名字為fahrenheit;第二個(gè)構(gòu)造器也擁有一個(gè)構(gòu)造參數(shù),其外部名字為fromKelvin,內(nèi)部名字為kelvin。這兩個(gè)構(gòu)造器都將唯一的參數(shù)值轉(zhuǎn)換成攝氏溫度值,并保存在屬性temperatureInCelsius中。
跟函數(shù)和方法參數(shù)相同,構(gòu)造參數(shù)也存在一個(gè)在構(gòu)造器內(nèi)部使用的參數(shù)名字和一個(gè)在調(diào)用構(gòu)造器時(shí)使用的外部參數(shù)名字。
然而,構(gòu)造器并不像函數(shù)和方法那樣在括號前有一個(gè)可辨別的名字。所以在調(diào)用構(gòu)造器時(shí),主要通過構(gòu)造器中的參數(shù)名和類型來確定需要調(diào)用的構(gòu)造器。正因?yàn)閰?shù)如此重要,如果你在定義構(gòu)造器時(shí)沒有提供參數(shù)的外部名字,Swift 會為每個(gè)構(gòu)造器的參數(shù)自動生成一個(gè)跟內(nèi)部名字相同的外部名,就相當(dāng)于在每個(gè)構(gòu)造參數(shù)之前加了一個(gè)哈希符號。
注意:
如果你不希望為構(gòu)造器的某個(gè)參數(shù)提供外部名字,你可以使用下劃線_來顯示描述它的外部名,以此覆蓋上面所說的默認(rèn)行為。
以下例子中定義了一個(gè)結(jié)構(gòu)體Color,它包含了三個(gè)常量:red、green和blue。這些屬性可以存儲0.0到1.0之間的值,用來指示顏色中紅、綠、藍(lán)成分的含量。
Color提供了一個(gè)構(gòu)造器,其中包含三個(gè)Double類型的構(gòu)造參數(shù):
struct Color {
let red = 0.0, green = 0.0, blue = 0.0
init(red: Double, green: Double, blue: Double) {
self.red = red
self.green = green
self.blue = blue
}
}
每當(dāng)你創(chuàng)建一個(gè)新的Color實(shí)例,你都需要通過三種顏色的外部參數(shù)名來傳值,并調(diào)用構(gòu)造器。
let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)
注意,如果不通過外部參數(shù)名字傳值,你是沒法調(diào)用這個(gè)構(gòu)造器的。只要構(gòu)造器定義了某個(gè)外部參數(shù)名,你就必須使用它,忽略它將導(dǎo)致編譯錯(cuò)誤:
let veryGreen = Color(0.0, 1.0, 0.0)
// 報(bào)編譯時(shí)錯(cuò)誤,需要外部名稱
如果你定制的類型包含一個(gè)邏輯上允許取值為空的存儲型屬性--不管是因?yàn)樗鼰o法在初始化時(shí)賦值,還是因?yàn)樗梢栽谥竽硞€(gè)時(shí)間點(diǎn)可以賦值為空--你都需要將它定義為可選類型optional type??蛇x類型的屬性將自動初始化為空nil,表示這個(gè)屬性是故意在初始化時(shí)設(shè)置為空的。
下面例子中定義了類SurveyQuestion,它包含一個(gè)可選字符串屬性response:
class SurveyQuestion {
var text: String
var response: String?
init(text: String) {
self.text = text
}
func ask() {
println(text)
}
}
let cheeseQuestion = SurveyQuestion(text: "Do you like cheese?")
cheeseQuestion.ask()
// 輸出 "Do you like cheese?"
cheeseQuestion.response = "Yes, I do like cheese.