Swift 为什么'=';赋值运算符在didSet属性观察器的if语句中不起作用? struct循环{ //性质 变量半径:双{ 迪塞特{ 如果oldValue

Swift 为什么'=';赋值运算符在didSet属性观察器的if语句中不起作用? struct循环{ //性质 变量半径:双{ 迪塞特{ 如果oldValue,swift,property-observer,Swift,Property Observer,记住,didSet是在属性实际更改后调用的旧值将包含以前的值 您要检查新值是否为负值 将代码更新为: struct Circle { // Properties var radius: Double { didSet { if oldValue < 0 { radius = 0 } } } var area:Double { g

记住,
didSet
是在属性实际更改后调用的<代码>旧值将包含以前的值

您要检查新值是否为负值

将代码更新为:

struct Circle {
    // Properties

    var radius: Double {
        didSet {
            if oldValue < 0 {
                 radius = 0
            }
        }
    }
    var area:Double {
        get{
            return Double.pi * pow(radius, 2)
        }
    }
    var circumference: Double {
        get {
            return 2 * radius * Double.pi
        }
    }
    init() {
        radius = 0
    }
    init(radius r: Double) {
        radius = r
    }

}

// test circle

var testCircle = Circle()
print ("radius:", testCircle.radius, "area: ", testCircle.area, "circumference: ", testCircle.circumference)

var testCircle2 = Circle(radius: 2.5)
print("radius: ", testCircle2.radius, " area: ", testCircle2.area, "circumference: ", testCircle2.circumference)

var testCircle3 = Circle(radius: 20)
print("radius: ", testCircle3.radius, "area: ", testCircle3.area, "circumference: ", testCircle3.circumference)

var testCircle4 = Circle(radius: -4.5)
print("radius: ", testCircle4.radius, "area: ", testCircle4.area, "circumference: ", testCircle4.circumference)
这是因为初始化期间未调用
didSet
willSet
。因此,您的
init
方法需要验证参数

作为旁注,可以进一步简化
半径
周长
属性,如下所示:

init(radius r: Double) {
    radius = r >= 0 ? r : 0
}

只读计算机属性不需要
get{}

记住,
didSet
是在属性实际更改后调用的<代码>旧值将包含以前的值

您要检查新值是否为负值

将代码更新为:

struct Circle {
    // Properties

    var radius: Double {
        didSet {
            if oldValue < 0 {
                 radius = 0
            }
        }
    }
    var area:Double {
        get{
            return Double.pi * pow(radius, 2)
        }
    }
    var circumference: Double {
        get {
            return 2 * radius * Double.pi
        }
    }
    init() {
        radius = 0
    }
    init(radius r: Double) {
        radius = r
    }

}

// test circle

var testCircle = Circle()
print ("radius:", testCircle.radius, "area: ", testCircle.area, "circumference: ", testCircle.circumference)

var testCircle2 = Circle(radius: 2.5)
print("radius: ", testCircle2.radius, " area: ", testCircle2.area, "circumference: ", testCircle2.circumference)

var testCircle3 = Circle(radius: 20)
print("radius: ", testCircle3.radius, "area: ", testCircle3.area, "circumference: ", testCircle3.circumference)

var testCircle4 = Circle(radius: -4.5)
print("radius: ", testCircle4.radius, "area: ", testCircle4.area, "circumference: ", testCircle4.circumference)
这是因为初始化期间未调用
didSet
willSet
。因此,您的
init
方法需要验证参数

作为旁注,可以进一步简化
半径
周长
属性,如下所示:

init(radius r: Double) {
    radius = r >= 0 ? r : 0
}

只读计算机属性不需要在
init
期间调用
get{}
didSet
属性观察器。您可以将赋值包装在
defer{…}
语句中,以强制调用
didSet

例如:

var area:Double {
    return Double.pi * pow(radius, 2)
}
如果希望默认半径为
0
,我建议使用
radius
的默认参数值,如下所示:

init(radius r: Double) {
    defer { radius = r }
}

…这样可以避免使用两个init方法,并且仍然将
圆初始化为
圆()
radius=0
)和
圆(radius:3)
radius=3
)。

初始化期间不会调用didSet
属性观察器。您可以将赋值包装在
defer{…}
语句中,以强制调用
didSet

例如:

var area:Double {
    return Double.pi * pow(radius, 2)
}
如果希望默认半径为
0
,我建议使用
radius
的默认参数值,如下所示:

init(radius r: Double) {
    defer { radius = r }
}

…这样可以避免使用两个init方法,并且仍然将
圆初始化为
圆()
半径=0
)和
圆(半径:3)
半径=3
)。

目的是尝试构造半径值小于0的圆。我是新手!这张支票的目的是什么?是否禁止用户设置负值,如果用户设置负值,则将其设置为0?因为如果是这种情况,您应该检查
radius
的当前值,而不是
oldValue
。后者将检查您进行更改之前的值。确保您的代码格式正确。2.你应该在问题的主体中提出你的问题。不在标题或注释中A比较为==。设置为=目的是尝试构造半径值小于0的圆。我是新手!这张支票的目的是什么?是否禁止用户设置负值,如果用户设置负值,则将其设置为0?因为如果是这种情况,您应该检查
radius
的当前值,而不是
oldValue
。后者将检查您进行更改之前的值。确保您的代码格式正确。2.你应该在问题的主体中提出你的问题。不在标题或注释中A比较为==。A set is=FYI-此答案对于解决诸如
someCircle之类的代码问题没有任何作用。r=-4.5
@rmaddy这不是OP的问题。当然是。阅读问题的标题。
didSet
写入错误。在某些情况下,
didSet
没有被调用的事实只是需要解决的另一个问题。仅供参考-这个答案对于解决诸如
someCircle之类的代码问题没有任何帮助。r=-4.5
@rmaddy这不是OP的问题。当然是。阅读问题的标题。
didSet
写入错误。在某些情况下,
didSet
没有被调用这一事实只是需要解决的另一个问题。