为什么没有setSet工作?

nip*_*ese 4 swift swift-structs

didSet我看到的很多例子中,这个代码会返回0,但是,我不能让它返回除原始值之外的任何东西.我究竟做错了什么?

迅速

struct Circle {
    var radius: Double {
        didSet {
            if radius < 0 {
                radius = 0
            }
        }
    }
}

var circ = Circle(radius: -25)

print(circ.radius)
Run Code Online (Sandbox Code Playgroud)

产量

-25
Run Code Online (Sandbox Code Playgroud)

Cro*_*man 16

didSet在初始化期间,仅在之后才调用.如果要在初始化期间验证数据,则初始化程序应该执行此操作.

如果你添加:

circ.radius = -50
print(circ.radius)
Run Code Online (Sandbox Code Playgroud)

你会看到它按照你的预期工作,输出就会如此0.0.


dfr*_*fri 6

正如 Paul 在评论中所写,在值初始化期间不会调用属性观察者didSetwillSet

如果你想在初始化时调用它们的值,你可以添加一个函数调用来radius在初始化器中初始设置后重新设置属性:

struct Circle {
    var radius: Double {
        didSet {
            if radius < 0 {
                radius = 0
            }
        }
    }

    init(radius: Double) {
        self.radius = radius
        setRadius(radius) // <-- this will invoke didSet
    }

    mutating func setRadius(radius: Double) {
        self.radius = radius
    }
}

var circ = Circle(radius: -25)

print(circ.radius) // 0.0
Run Code Online (Sandbox Code Playgroud)

  • 尝试删除它,您将收到一个非常明显的错误提示:“在所有存储的属性初始化之前使用了`'self'”。尝试访问 (`mutating`) 函数 `setRadius(radius:)` 等同于尝试使用 `self`,这在 `self` 完全初始化之前是不允许的。 (2认同)

Dan*_*row 6

如果将其放在语句中,则可以确保didSetinitdefer。也适用于deinit

class Circle {
    var radius: Double {
       didSet {
          if radius < 0 {
             radius = 0
          }
       }
    }

    init(radius: Double) {
        defer { self.radius = radius }
    }
}
Run Code Online (Sandbox Code Playgroud)