Swift10 - 属性、方法、下标

2020-06-09  本文已影响0人  暗物质
// # 判定两个常量或者变量是否引用同一个类实例有时很有用。为了达到这个目的,Swift 提供了两个恒等运算符

// 存储属性用于类和结构体,计算属性用于类、结构体和枚举

struct FixedLengthRange {
    var firstValue: Int
    let length: Int
}

var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
rangeOfThreeItems.firstValue = 6

//延时加载存储属性:
//当属性的值依赖于一些外部因素且这些外部因素只有在构造过程结束之后才会知道的时候,延时加载属性就会很有用
//或者当获得属性的值因为需要复杂或者大量的计算,而需要采用需要的时候再计算的方式,延时加载属性也会很有用。
class DataImporter {
    /*
    DataImporter 是一个负责将外部文件中的数据导入的类。
    这个类的初始化会消耗不少时间。
    */
    var fileName = "data.txt"
    // 这里会提供数据导入功能
}

class DataManager {
    lazy var importer = DataImporter()
    var data = [String]()
}

// 计算属性
//计算属性不直接存储值,而是提供一个 getter 和一个可选的 setter,来间接获取和设置其他属性或变量的值。
struct Point {
    var x = 0.0, y = 0.0
}
struct Size {
    var width = 0.0, height = 0.0
}
struct Rect {
    var origin = Point()
    var size = Size()
    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set(newCenter) {
            origin.x = newCenter.x - (size.width / 2)
            origin.y = newCenter.y - (size.height / 2)
        }
        //newValue
//        set {
//            origin.x = newValue.x - (size.width / 2)
//            origin.y = newValue.y - (size.height / 2)
//        }
        
        //简化getter
//        get {
//            Point(x: origin.x + (size.width / 2), y: origin.y + (size.height / 2))
//
//        }
        
    }
}

//只读计算属性
//只有 getter 没有 setter 的计算属性叫只读计算属性
struct Cuboid {
    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {
        return width * height * depth
    }
}

class StepCounter {
    var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            print("将 totalSteps 的值设置为 \(newTotalSteps)")
        }
        didSet {
            if totalSteps > oldValue  {
                print("增加了 \(totalSteps - oldValue) 步")
            }
        }
    }
}

//属性的包装器
// http://www.srcmini.com/23534.html#heading_1

//定义一个属性包装器,你需要创建一个定义 wrappedValue 属性的结构体、枚举或者类。
@propertyWrapper
struct TwelveOrLess {
    //TwelveOrLess 结构体确保它包装的值始终是小于等于 12 的数字
//    private var number = 0
//    init(number: Int) {
//        self.number = number
//    }
    
    var number = 0
   
    var wrappedValue: Int {
        get {
            return number
        }
        set {
            number = min(newValue, 12)
        }
    }
}

//把一个包装器应用到一个属性上去
struct SmallRectangle {
    @TwelveOrLess public var height: Int
    
    @TwelveOrLess public var width: Int
}

var rectangle = SmallRectangle()
print(rectangle.height)

rectangle.height = 11
print(rectangle.height)

rectangle.width = 20
print(rectangle.width) //12


// 设置被包装属性的初始值
@propertyWrapper
struct SmallNumber {
    private var max: Int
    private var number: Int
    
    var wrappedValue: Int {
        get {
            return number
        }
        set {
            number = min(newValue, max)
        }
    }
    
    init() {
        max = 12
        number = 0
    }
    
    init(wrappedValue: Int) {
        max = 12
        number = min(wrappedValue, max)
    }
    
    init(wrappedValue: Int, max: Int) {
        self.max = max
        number = min(wrappedValue, max)
    }
}


struct ZeroRectangle {
    @SmallNumber var height: Int
    @SmallNumber var width: Int
}

var zeroRectangle = ZeroRectangle()
print(zeroRectangle.height, zeroRectangle.width)


//当你为属性指定初始值时,Swift 使用 init(wrappedValue:) 构造器来设置包装器
struct UnitRectangle {
    @SmallNumber var height: Int = 1
    @SmallNumber var width: Int = 1
}
var unitRectangle = UnitRectangle()
print(unitRectangle.height, unitRectangle.width)
// 打印 "1 1"


// 使用 init(wrappedValue:maximum:) 构造器:
struct NarrowRectangle {
    @SmallNumber(wrappedValue: 2, max: 5)
    var height: Int
    
    @SmallNumber(wrappedValue: 3, max: 4)
    var width: Int
}
var narrowRectangle = NarrowRectangle()
print(narrowRectangle.height, narrowRectangle.width)
// 打印 "2 3"

narrowRectangle.height = 100
narrowRectangle.width = 100
print(narrowRectangle.height, narrowRectangle.width)
// 打印 "5 4"
上一篇 下一篇

猜你喜欢

热点阅读