Swift —— 属性
1. 存储属性
存储属性是一个作为特定类和结构体实例一部分的常量或变量。存储属性要么是变量存储属性 (由 var 关键字引入)要么是常量存储属性(由 let 关键字引入)。存储属性这里没有什么特 别要强调的,因为随处可⻅。 比如这里的 age 和 name 就是我们所说的存储属性,这里我们需要加以区分的是 let 和 var 两者的区别:从定义上: let 用来声明常量,常量的值一旦设置好便不能再被更改; var 用来声明变量,变量的值可以在将来设置为不同的值。
1.1 let 和 var 的区别
代码角度
class LGTeacher{
var age: Int
var name: String
}
这里我们来看几个案例:
class LGTeacher{
let age: Int
var name: String
init( age: Int, name: String){
self.age = age
self.name = name }
}
struct LGStudent{
let age: Int
var name: String
}
let t = LGTeacher(age: 18, name: "Hello")
t.age = 20
t.name = "Logic"
t = LGTeacher(age: 30, name: "Kody")
var t1 = LGTeacher(age: 18, name: "Hello")
t.age = 20
t.name = "Logic"
t = LGTeacher(age: 30, name: "Kody")
let s = LGStudent(age: 30, name: "Kody")
s.age = 25
s.name = "Doman"
s = LGStudent(age: 30, name: "Kody")
var s1 = LGStudent(age: 30, name: "Kody")
s.age = 25
s.name = "Doman"
s = LGStudent(age: 30, name: "Kody")
从这里可以看到,对于类t来说,t.age是不能被修改的,t.name是可以被修改的,t是不能被修改的。所以这里可以知道,let修饰的变量,只确保当前变量的值是不能够被修改的。这里t存的是实例对象的内存地址,这个地址是不能在变得,所以当在给t重新赋值一个实例对象的时候, 相当于修改了t的值,所以这里是不允许的。age是用let修饰的,所以这里也是不能修改的。
而对于结构体s来说,对于值类型来说,当前的age和name都是不能被修改的,因为s里面存储的就是age和name的值,修改age和name就相当于修改s,由于s是用let声明,所以都不能修改。
汇编角度
从汇编角度来看var 和 let。
var age = 18
let x = 20
从这里可以知道var 和 let在汇编角度是没有什么区别的。
SIL角度
再到SIL里面查看var和let 的区别。
这里可以看到两者都是存储属性,都有初始值。但是这里不同的是,age是有setter 的,而x是没有setter的。本质上,对于存储属性来说,当前的编译器都会给存储属性默认合成setter和getter,访问使用getter,赋值使用setter。而对于let来说,是不生成setter的,而无法对x进行赋值也是因为无法找到其的setter。所以从SIL角度来说,var 和 let 也是一种语法糖。
2. 计算属性
存储的属性是最常⻅的,除了存储属性,类、结构体和枚举也能够定义计算属性,计算属性并不 存储值,他们提供 getter 和 setter 来修改和获取值,计算属性的本质是getter和setter。对于存储属性来说可以是常量或变量,但计算属性必须定义为变量。于此同时我们书写计算属性时候必须包含类型,因为编译器需要知道期望返回值是什么。
struct square{
var width: Double
var area: Double{
get {
return width * hegith
}
set {
self.width = newValue
}