📅  最后修改于: 2020-12-25 04:34:06             🧑  作者: Mango
Swift 4语言为类,枚举或结构提供属性以关联值。属性可以进一步分为存储属性和计算属性。
存储的属性与计算的属性之间的区别
Stored Property | Computed Property |
---|---|
Store constant and variable values as instance | Calculate a value rather than storing the value |
Provided by classes and structures | Provided by classes, enumerations and structures |
存储属性和计算属性都与实例类型相关联。当属性与其类型值相关联时,则将其定义为“类型属性”。存储和计算的属性通常与特定类型的实例相关联。但是,属性也可以与类型本身关联。这样的属性称为类型属性。还使用属性观察器
Swift 4引入了存储属性的概念来存储常量和变量的实例。常量的存储属性由’let’关键字定义,变量的存储属性由’var’关键字定义。
struct Number {
var digits: Int
let pi = 3.1415
}
var n = Number(digits: 12345)
n.digits = 67
print("\(n.digits)")
print("\(n.pi)")
当我们使用游乐场运行上述程序时,我们得到以下结果-
67
3.1415
考虑以上代码中的以下行-
let pi = 3.1415
在此,实例pi = 3.1415将变量pi初始化为存储的属性值。因此,无论何时引用该实例,它都将单独拥有值3.1415。
具有存储属性的另一种方法是具有恒定的结构。因此,结构的整个实例将被视为“常量的存储属性”。
struct Number {
var digits: Int
let numbers = 3.1415
}
var n = Number(digits: 12345)
n.digits = 67
print("\(n.digits)")
print("\(n.numbers)")
n.numbers = 8.7
当我们使用游乐场运行上述程序时,我们得到以下结果-
error: cannot assign to 'numbers' in 'n'
n.numbers = 8.7
而不是将“数字”重新初始化为8.7,而是返回一条错误消息,指出“数字”被声明为常量。
Swift 4提供了一个名为“惰性存储属性”的灵活属性,该属性在首次初始化变量时不会计算初始值。 ‘lazy’修饰符用于变量声明之前,以使其具有惰性存储属性。
使用惰性属性-
class sample {
lazy var no = number() // `var` declaration is required.
}
class number {
var name = "Swift 4"
}
var firstsample = sample()
print(firstsample.no.name)
当我们使用游乐场运行上述程序时,我们得到以下结果-
Swift 4
在目标C中,存储属性还具有实例变量,以用于备份目的,以存储在存储属性中声明的值。
Swift 4将这两个概念集成到单个“存储属性”声明中。代替具有相应的实例变量和备份值,“存储的属性”包含在单个位置中通过变量名称,数据类型和内存管理功能定义的关于变量属性的所有集成信息。
与其存储值,不如通过计算属性来提供属性,而是提供一个getter和一个可选的setter来间接检索和设置其他属性和值。
class sample {
var no1 = 0.0, no2 = 0.0
var length = 300.0, breadth = 150.0
var middle: (Double, Double) {
get {
return (length / 2, breadth / 2)
}
set(axis){
no1 = axis.0 - (length / 2)
no2 = axis.1 - (breadth / 2)
}
}
}
var result = sample()
print(result.middle)
result.middle = (0.0, 10.0)
print(result.no1)
print(result.no2)
当我们使用游乐场运行上述程序时,我们得到以下结果-
(150.0, 75.0)
-150.0
-65.0
当计算的属性未定义新值时,将为该特定变量设置默认值。
计算属性中的只读属性定义为具有getter但不包含setter的属性。它始终用于返回值。通过“。”进一步访问变量。语法,但不能设置为其他值。
class film {
var head = ""
var duration = 0.0
var metaInfo: [String:String] {
return [
"head": self.head,
"duration":"\(self.duration)"
]
}
}
var movie = film()
movie.head = "Swift 4 Properties"
movie.duration = 3.09
print(movie.metaInfo["head"]!)
print(movie.metaInfo["duration"]!)
当我们使用游乐场运行上述程序时,我们得到以下结果-
Swift 4 Properties
3.09
在Swift 4中,观察和响应属性值使用了属性观察器。每次设置属性值时,都会调用属性观察器。除了惰性存储的属性,我们还可以通过“覆盖”方法将属性观察者添加到“继承的”属性中。
可以通过以下任一方式定义属性观察者
在存储值之前-willset
存储新值之后-didset
在初始化程序中设置属性时,将无法调用willset和didset观察者。
class Samplepgm {
var counter: Int = 0 {
willSet(newTotal){
print("Total Counter is: \(newTotal)")
}
didSet {
if counter > oldValue {
print("Newly Added Counter \(counter - oldValue)")
}
}
}
}
let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800
当我们使用游乐场运行上述程序时,我们得到以下结果-
Total Counter is: 100
Newly Added Counter 100
Total Counter is: 800
Newly Added Counter 700
声明局部变量和全局变量用于计算和观察属性。
Local Variables | Global Variables |
---|---|
Variables that are defined within a function, method, or closure context. | Variables that are defined outside function, method, closure, or type context. |
Used to store and retrieve values. | Used to store and retrieve values. |
Stored properties is used to get and set the values. | Stored properties is used to get and set the values. |
Computed properties are also used. | Computed properties are also used. |
在类型定义部分使用大括号{}定义属性,并且变量的范围也已在前面定义。为了为值类型定义类型属性,使用“ static”关键字,对于类类型使用“ class”关键字。
struct Structname {
static var storedTypeProperty = " "
static var computedTypeProperty: Int {
// return an Int value here
}
}
enum Enumname {
static var storedTypeProperty = " "
static var computedTypeProperty: Int {
// return an Int value here
}
}
class Classname {
class var computedTypeProperty: Int {
// return an Int value here
}
}
就像实例属性一样,查询类型属性并设置为“。”。语法仅针对类型,而不是指向实例。
struct StudMarks {
static let markCount = 97
static var totalCount = 0
var InternalMarks: Int = 0 {
didSet {
if InternalMarks > StudMarks.markCount {
InternalMarks = StudMarks.markCount
}
if InternalMarks > StudMarks.totalCount {
StudMarks.totalCount = InternalMarks
}
}
}
}
var stud1Mark1 = StudMarks()
var stud1Mark2 = StudMarks()
stud1Mark1.InternalMarks = 98
print(stud1Mark1.InternalMarks)
stud1Mark2.InternalMarks = 87
print(stud1Mark2.InternalMarks)
当我们使用游乐场运行上述程序时,我们得到以下结果-
97
87