结构体struct,类class
1.struct,值类型,结构体会自动生成初始化方法,class是引用类型
struct Person { var name : String var age : Int func simpleDescription() -> String { return "name = \(name) , age = \(age)" } } let p = Person(name: "ly", age: 9) let k = p.simpleDescription() print(k)
2.1个结构体=另一个结构体,修改一个结构体的属性,另一个不变
let hd = Resolution(width: 1920, height: 1080) // cinema 其实是 hd 的一个拷贝副本,而不是 hd 本身。尽管 hd 和 cinema 有着相同的宽(width)和高(heigh t),但是在幕后它们是两个完全不同的实例 var cinema = hd //修改cinema属性,hd的不会变 cinema.width = 2000 //如果是类class,修改的话,是会改变的
3.恒等运算符 等价于(===) 不等价于( !== )
作用:用于判定两个常量或者变量是否引用同一个类实例
4.选择结构体还是类来定义自定义数据类型
按照通用的准则,当符合一条或多条以下条件时,请考虑构建结构体:
• 该数据结构的主要目的是用来封装少量相关简单数据值。
• 有理由预计该数据结构的实例在被赋值或传递时,封装的数据将会被拷贝而不是被引用。
• 该数据结构中储存的值类型属性,也应该被拷贝,而不是被引用。
• 该数据结构不需要去继承另一个既有类型的属性或者行为。
举例来说,以下情境中适合使用结构体:
• 几何形状的大小,封装一个width 属性和height 属性,两者均为Double 类型。
• 一定范围内的路径,封装一个start 属性和length 属性,两者均为Int 类型。
• 三维坐标系内一点,封装x ,y 和 z属性,三者均为double 类型。
在所有其它案例中,定义一个类,生成一个它的实例,并通过引用来管理和传递。实际中,这意味着绝大部分的自定义数据构造都应该是类,而非结构体。
5.计算属性
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 { origin.x = newValue.x - (size.width / 2) origin.y = newValue.y - (size.height / 2) } } } var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height: 10.0)) let initialSquareCenter = square.center square.center = Point(x: 15.0, y: 15.0) print("square.origin is now at (\(square.origin.x), \(square.origin.y))") // 打印 "square.origin is now at (10.0, 10.0)”
6.只读计算属性 只读计算属性的声明可以去掉 get 关键字和花括号
struct Cuboid { var width = 0.0, height = 0.0, depth = 0.0 var volume: Double { return width * height * depth } } let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)") // 打印 "the volume of fourByFiveByTwo is 40.0"
7.属性观察器 (重要)
注意:你不可以为继承来的常量存储型属性或继承来的只读计算型属性添加属性观察器。这些属性的值是不可以被设置 的,所以,为它们提供willSet或didSet实现是不恰当
防止重写 :在方法/属性前加 final 例:final var
class StepCounter { var totalSteps: Int = 0 { didSet { if totalSteps > oldValue { print("Added \(totalSteps - oldValue) steps") } } } } let stepCounter = StepCounter() stepCounter.totalSteps = 200
8.类型属性
struct SomeStructure { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { get { return 1 } set { storedTypeProperty = "help" } } } SomeStructure.computedTypeProperty = 1 print(SomeStructure.storedTypeProperty) //输出:help enum SomeEnumeration { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { return 6 } } class SomeClass { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { return 27 } class var overrideableComputedTypeProperty: Int { return 107 } }
9.在实例方法中修改值类型 (结构体和枚举) mutating
struct Point { var x = 0.0, y = 0.0 mutating func moveByX(deltaX: Double, y deltaY: Double) { x += deltaX y += deltaY } } var somePoint = Point(x: 1.0, y: 1.0) somePoint.moveByX(deltaX: 2.0, y: 3.0)