6

didSet在我在 SO 上看到的许多示例中,此代码将返回0,但是,我无法让它返回原始值以外的任何内容。我究竟做错了什么?

迅速

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

var circ = Circle(radius: -25)

print(circ.radius)

输出

-25
4

5 回答 5

20

didSet在初始化期间不调用,仅在之后调用。如果您想在初始化期间验证数据,您的初始化程序应该这样做。

如果添加:

circ.radius = -50
print(circ.radius)

您会看到它按预期工作,输出将是0.0.

于 2016-01-30T01:39:11.333 回答
13

如果你把它放在一个声明didSet中,你可以确定。也适用于.initdeferdeinit

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

    init(radius: Double) {
        defer { self.radius = radius }
    }
}
于 2018-01-14T02:59:14.537 回答
7

正如 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
于 2016-01-30T01:40:44.623 回答
1

您也可以使用惰性和 init(radius ....

struct Circle {
    lazy var radius: Double = 0.0 {
        didSet {
            print("didSet called")
            if radius < 0 {
                radius = 0
            }
        }
    }
    init(radius:Double) {
        self.radius = radius
    }
}
于 2021-09-20T10:46:18.587 回答
0

为此使用初始化:

struct Circle {
    var radius: Double

    init(radius: Double) {
        self.radius = radius < 0 ? 0 : radius
    }
}

var circ = Circle(radius: -25)

print(circ.radius)

0.0
于 2020-10-05T15:31:37.363 回答