1.什么是參數的內部名稱和外部名稱?
struct Color { let red, green, blue: Double init(red redColor: Double,green greenColor: Double,blue blueColor: Double) { red = redColor green = greenColor blue = blueColor } }
1.1 Color這個結構體的構造方法中提供了三個參數,其中red是第一個參數的外部名稱,redColor是第一個參數的內部名稱;同理green和blue分別是第二、三個參數的外部名稱,greenColor和blueColor分別是第二、三個參數的內部名稱。外部名稱在創建實例時的提示中顯示,內部名稱只能在構造方法內部使用,兩個名稱指的是同一個參數。在創建實例時會顯示外部名稱截圖:
1.2 如果只有參數的內部名稱,沒有外部名稱,編譯器會自動為參數創建一個和內部名稱相同的外部名稱。看實例:
這個只有一個參數的構造函數的外部參數名稱和內部參數名稱相同。
1.3 內部參數名稱可以用來區分是傳入的參數還是實例的屬性,也可以用self來區分
struct Color { let red, green, blue: Double init(RED redColor: Double,GREEN greenColor: Double,BLUE blueColor: Double) { red = redColor green = greenColor blue = blueColor } init(white: Double) { red = white green = white blue = white } init(red: Double,green: Double,blue: Double) { self.red = red self.green = green self.blue = blue } }
1.4 編譯器根據外部參數名稱去檢查構造器是重載還是重名的。
1.5 如果不希望提供參數的外部名稱,可以用_顯示代替參數的外部名稱,創建實例的時候,編譯器會顯示參數的內部名稱。
struct Color { let red, green, blue: Double init(red redColor: Double,green greenColor: Double,blue blueColor: Double) { red = redColor green = greenColor blue = blueColor } init(white: Double) { red = white green = white blue = white } init(_ red1: Double,_ green1: Double,_ blue1: Double) { self.red = red1 self.green = green1 self.blue = blue1 } }
2.類的構造器和結構體構造器的區別
實體類的構造器,定義普通類型的屬性時,必須初始化(聲明時就初始化或者在構造函數中初始化),如果不初始化會報錯。可選類型的屬性可以不初始化,因為可選類型不初始化的時候,默認值時nil。
結構體的構造器,普通類型和可選類型的屬性均可不初始化,編譯器會默認提供一個帶全參的構造器,這個構造器實體類是沒有的。如果結構體中有普通類型的屬性未初始化,則編譯器不會提供結構體名稱+括號的默認構造器,只會提供一個帶全參的構造器,這樣避免創造一個未初始化過的結構體。
實體類構造器:
class ShoppingListItem { var name: String? var quantity: String? var purchased: String? }
以上構造器默認全部初始化為nil,所以編譯器會默認提供一個ShoppingListItem()的構造器,也可以在類中添加其他構造器從而讓編譯器提供其他的構造器。默認構造器截圖:
結構體構造器:
a.結構體聲明中有未初始化的屬性
struct Car { var name: String? var quantity: Int var purchased: String? }
編譯器默認只提供全參的構造器:
b.結構體聲明中沒有未初始化的屬性
struct Car { var name: String? var quantity: String? var purchased: String? }
編譯器會提供2個默認的構造器:
3.類的指定構造器和便利構造器(構造器中屬性前有沒有self.結果都是一樣,屬性名前面默認會自帶self.)
3.1 指定構造器的作用就是為了初始化屬性值,便利構造器需要添加關鍵字convenience,並且便利構造器無法直接訪問屬性,必須通過指定構造器間接訪問
class Food { var name: String //指定構造器 init(name: String) { self.name = name } //便利構造器 convenience init() { self.init(name: "[Unnamed]") //name = "CCC" //會報錯 } }