我在Swift上阅读了许多关于“自我”的出版物,我开始对它有所了解,但仍有一件事我不清楚。
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
用于区分'{1}}中参数中'''和init()与'color'。
所以当func paint(color: String)
中设置'自我颜色'时,它指的是'颜色'?来自func paint(color: String)
的“颜色”或来自init()
的参数的颜色?
答案 0 :(得分:3)
self
是对运行代码的类的当前实例的引用。
在init
方法和paint
方法中,它允许您指定您希望使用值设置名为color
的成员变量将参数传递给也称为color
的方法。
paint
方法根本无法引用传递给init
的参数(反之亦然)。
因此,在您的示例代码中,两种方法都将对象的color
设置为作为参数传递给方法的某个指定值。
init
方法设置对象的初始颜色。
paint
方法允许您从初始颜色更改对象的颜色。
如果参数的名称不同,例如:
,这可能会更清楚required init(initialMake: String, initialColor: String) {
self.make = initialMake
self.color = initialColor
}
func paint(newColor: String) {
self.color = newColor
}
在这种情况下,由于函数是成员方法,self
现在完全是可选的,因为编译器知道color
现在只能 表示名为{{的成员1}}因为没有其他变量或参数具有该名称,即color
方法可以简单地写为:
paint
这将具有完全相同的行为。
但是,为了清晰起见,有些人更喜欢保留func paint(newColor: String) {
color = newColor
}
前缀,即使不严格要求,因为除了明确意图外,如果变量或成员名称发生变化,它可以帮助避免意外错误。
答案 1 :(得分:1)
self
引用对象实例。在大多数情况下,在Swift中使用self
是可选的。
您发布的代码需要它,因为在init
和paint
方法中您有一个名为color
的参数,并且您还想访问名为{的属性{1}}。在方法内部,对color
的引用始终是参数。因此,指示您要引用名为color
的属性的唯一方法是,必须在引用前添加color
。如果您重命名参数使其与该属性名称不同,则您不需要self.
。
self
始终表示对self.color
属性的引用。 color
将首先查找同名的最近的局部变量/参数。如果找到,那就是使用的。如果不是,则使用相同名称的属性。
答案 2 :(得分:1)
init函数和paint函数中的self.color
引用Car对象上的实例变量。
要理解,请考虑没有self
的代码:
func paint(color: String) {
color = color
}
该功能的目的是将汽车的颜色属性作为传递给它的颜色。但是使用此代码,它将不会引用汽车的颜色属性,并且该功能无法按预期工作。因此,您的功能需要以self
关键字的形式提供一些帮助。
同样,为什么init()被设置为自动初始化“make”和“color”的值,然后要求你自己初始化?
您使用init函数传递值,您不是“自动初始化”make“和”color“的值。您为Car对象创建的实例变量是非可选值({{ 1}} s),所以它们不能为零。所以如果你初始化一个Car,你必须在init函数完成后正确设置它们的值。