我在斯威夫特阅读了许多关于“自我”的出版物,我开始了解它的要点,但仍有一件事我不清楚。
class Car {
// 1
let make: String
// 2
private(set) var color: String
init() {
make = "Ford"
color = "Black"
}
required init(make: String, color: String) {
self.make = make
self.color = color
}
// 3
func paint(color: String) {
self.color = color
}
}
let car = Car(make: "Tesla", color: "Red")
car.paint("Blue")
我试图通过上面的例子来证明我的观点。
我读到的几个出版物表明self
用于区分init()中的“颜色”和func油漆(颜色:字符串)
参数中的“颜色”。
因此,当在func油漆(颜色:字符串)
中设置“自颜色”时,它指的是哪个“颜色”?来自init()
的“颜色”或来自func油漆(颜色:字符串)
的参数的颜色?
self
是对运行代码的类的当前实例的引用。
在init
方法和油漆
方法中,它允许您使用传递给方法的参数中的值来指定您希望设置名为颜色
的成员变量,该方法也称为颜色
。
油漆
方法根本不能引用传递给init
的参数(反之亦然)。
因此,在您的示例代码中,这两个方法都将对象的颜色
设置为作为参数传入方法的某个指定值。
init
方法为对象设置初始颜色。
然后,油漆
方法允许您从初始颜色更改对象的颜色。
如果简单地以不同的方式命名参数,这可能会更清楚,例如:
required init(initialMake: String, initialColor: String) {
self.make = initialMake
self.color = initialColor
}
func paint(newColor: String) {
self.color = newColor
}
在这种情况下,由于函数是成员方法,self
现在是完全可选的,因为编译器知道颜色
现在只能表示名为颜色
的成员,因为没有其他具有该名称的变量或参数,即油漆
方法可以简单地写成:
func paint(newColor: String) {
color = newColor
}
这将具有完全相同的行为。
但是,有些人更喜欢保留self
前缀以保持清晰,即使它不是严格要求的,因为它也可以使意图清晰,如果变量或成员名称发生更改,它可以帮助避免意外错误。
init函数和油漆函数中的self. Color
都引用Car对象上的实例变量。
要理解,请考虑没有self
的代码:
func paint(color: String) {
color = color
}
该函数的目的是让汽车的颜色属性成为传递给它的颜色。但是使用此代码,它不会引用汽车的颜色属性,并且该函数将无法按预期工作。因此,您的函数需要以self
关键字的形式提供一些帮助。
此外,设置init()以自动初始化“make”和“Color”的值,然后要求您自己初始化的原因是什么?
你用你的init函数传入值,你没有“自动初始化”make“和”chro“的值。你为Car对象创建的实例变量是非可选值(String
s),所以它们永远不能为nil。所以如果你初始化一个Car,你必须在init函数完成后正确设置它们的值。
self
引用对象实例。在Swift中使用self
在大多数情况下是可选的。
在您发布的代码中需要它,因为在init
和色
方法中,您有一个名为色
的参数,并且您还希望访问名为色
的属性。在方法内部,对色
的引用将始终指向该参数。因此,指示您要引用名为色
的属性的唯一方法,您必须在引用前缀加上self。
。如果您重命名参数,使其与属性的名称不相同,则不需要self
。
self.颜色
将始终表示对颜色
属性的引用。颜色
将首先查找最近的同名局部变量/参数。如果找到,则使用该属性。如果没有,则使用同名属性。