为什么 Xcode 警告我将其设为常量,为什么它仍然会发生变化?
Why did Xcode warn me about making this a constant, and why does it still change?
在我的 updateBlob 函数中,Xcode 警告我 pos 未更改,应该更改为 let 常量,即使我可以看到它正在更改,而且 运行 程序确实如此更改位置值。当我使用 defer 关键字更新 BlobPos class 以在发送半径值时更新 x/y 坐标时,这一切似乎都发生了。虽然我可以避免使用 defer,但为什么编译器会警告我将 pos 设为常量,而程序仍然能够更改应该是常量的内容?
class BlobPos
{
var x:CGFloat = 0
var y:CGFloat = 0
public init(radius:CGFloat) {
defer {
x = radius + 5
y = radius + 5
}
}
}
class Blob
{
var radius: CGFloat
var pos: BlobPos
init
(
radius: CGFloat,
pos: BlobPos,
)
{
self.radius = radius
self.pos = pos
}
}
func makeBlob() -> Blob
{
let radius = 8
let pos = BlobPos(radius:radius)
return Blob(radius: radius, pos: pos)
}
func updateBlob(blob:Blob)
{
let radius = blob.radius
let pos = blob.pos // compiler warning wanting me to turn this into a let constant instead of var
pos.x += 6
pos.y += 2
blob.pos = pos // strangely, new position is set
}
那是因为 BlobPos
是一个 class 并且改变 class 的属性不会改变它在内存中的位置,这就是 classes 的方式传递(通过引用它们在内存中的位置)。如果 BlobPos
是一个结构,那么你必须将它声明为一个变量,因为结构是通过它们的值(而不是对它们在内存中的位置的引用)传递的。
在我的 updateBlob 函数中,Xcode 警告我 pos 未更改,应该更改为 let 常量,即使我可以看到它正在更改,而且 运行 程序确实如此更改位置值。当我使用 defer 关键字更新 BlobPos class 以在发送半径值时更新 x/y 坐标时,这一切似乎都发生了。虽然我可以避免使用 defer,但为什么编译器会警告我将 pos 设为常量,而程序仍然能够更改应该是常量的内容?
class BlobPos
{
var x:CGFloat = 0
var y:CGFloat = 0
public init(radius:CGFloat) {
defer {
x = radius + 5
y = radius + 5
}
}
}
class Blob
{
var radius: CGFloat
var pos: BlobPos
init
(
radius: CGFloat,
pos: BlobPos,
)
{
self.radius = radius
self.pos = pos
}
}
func makeBlob() -> Blob
{
let radius = 8
let pos = BlobPos(radius:radius)
return Blob(radius: radius, pos: pos)
}
func updateBlob(blob:Blob)
{
let radius = blob.radius
let pos = blob.pos // compiler warning wanting me to turn this into a let constant instead of var
pos.x += 6
pos.y += 2
blob.pos = pos // strangely, new position is set
}
那是因为 BlobPos
是一个 class 并且改变 class 的属性不会改变它在内存中的位置,这就是 classes 的方式传递(通过引用它们在内存中的位置)。如果 BlobPos
是一个结构,那么你必须将它声明为一个变量,因为结构是通过它们的值(而不是对它们在内存中的位置的引用)传递的。