swift值类型struct的初始化

2018-07-23  本文已影响22人  flionel

1. 不带参数的构造器init

struct Fahrenheit {
    var temperature: Double
    init() {
        self.temperature = 32.0
    }
}


var f = Fahrenheit()
print("the default temperature is \(f.temperature)")

2. 构造参数

struct Celsius {
    var temperatureInCelsius: Double
    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
}

第一个构造器有一个构造参数,其外部名字为fromFahrenheit,内部名字为fahrenheit;
第二个构造器拥有一个构造参数,其外部名字为fromKelvin,内部名字为kelvin。
这两个构造起都将为宜的参数转换成摄氏温度值,并保存在属性temperatureInCelsius中

let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
print(boilingPointOfWater.temperatureInCelsius)

let freezingPointOfWater = Celsius.init(fromKelvin: 273.15)
print(freezingPointOfWater.temperatureInCelsius)

3. 参数标签

struct Color {
    let red, green ,blue: Double
    init(red: Double, green: Double, blue: Double) {
        self.red = red
        self.green = green
        self.blue = blue
    }
    
    init(white: Double) {
        self.red = white
        self.green = white
        self.blue = white
    }
}

4. 无参数标签的构造器参数

extension Celsius {
    init(_ celsius: Double) {
        temperatureInCelsius = celsius
    }
}

let bodyTemperature = Celsius(37.0)
print(bodyTemperature.temperatureInCelsius)

5. 可选属性类型

class SurveyQuestion {
    var text: String
    var response: String?
    init(text: String) {
        self.text = text
    }
    
    func ask() {
        print(text)
    }
}

let cheeseQuestion = SurveyQuestion.init(text: "Do you like cheese?")
cheeseQuestion.ask()
cheeseQuestion.response = "Yes, i do like cheese"

6. 常量属性的赋值

对于类的实例来说,它的敞亮只能在定义它的类的构造过程中修改,不能在子类中修改。

class SurveyQuestion1 {
    let text: String
    var response: String?
    init(text: String) {
        self.text = text
    }
}

7. 默认构造器

如果结构体或类的所有属性都有默认值,同时没有自定义的构造器,那么swift会给这个结构体或类提供一个默认构造器(default initializer)。这个默认构造器将简单地创建一个所有属性值都设置为默认值的实例,

class ShoppingListItem {
    var name: String?
    var quantity = 1
    var purchased = false
}
// 若属性为可选值,例如`var name: String?`,则默认值为nil
var item = ShoppingListItem()

8. 结构体的逐一成员构造器

除了上面提到的默认构造器,如果结构体没有提供自定义的构造器,他将自动获得一个逐一成员构造器(memberwise initializer),急事结构体的存储属性没有默认值

struct Size {
    var width = 0.0, height = 0.0
}
// 结构体Size自动获得一个逐一成员共造器`init(width:height:)`
let twoByTwo = Size.init(width: 2.0, height: 2.0)

如果你为某个值类型定义了一个自定义的构造器,你将无法访问到默认构造器(如果是结构体,还将无法访问逐一成员构造器)。这种限制可以防止你为值类型添加一个额外的且十分复杂的构造器之后,仍然有人错误的使用自动生成的构造器。

9. 值类型的构造器代理

构造器可以通过其他构造器来完成实例的部分构造过程,这一过程称为构造器代理,它能够避免多个构造器之间的代码重复。

struct Size {
    var width = 0.0, height = 0.0
}

struct Point {
    var x = 0.0, y = 0.0
}

struct Rect {
    var origin = Point()
    var size = Size()
    init() {}
    
    init(origin: Point, size: Size) {
        self.origin = origin
        self.size = size
    }
    
    // 代理构造器
    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        // 代理构造过程
        self.init(origin: Point.init(x: originX, y: originY), size: size)
    }
}

10. 参考链接

上一篇 下一篇

猜你喜欢

热点阅读