Swift中的观测器方法中的抛出误差

Swift中的观测器方法中的抛出误差,swift,validation,error-handling,Swift,Validation,Error Handling,我试图在属性观察者方法(didSet和willSet)中实现一些验证规则,并试图在闭包中使用throw。下面是一个示例: enum SomeClassError: ErrorType { case NumberNotPositive } class SomeClass { var PositiveNumber: Int { willSet(value) { guard value > 0 else { throw SomeClassError.

我试图在属性观察者方法(
didSet
willSet
)中实现一些验证规则,并试图在闭包中使用
throw
。下面是一个示例:

enum SomeClassError: ErrorType {
  case NumberNotPositive
}

class SomeClass {
  var PositiveNumber: Int {
    willSet(value) {
      guard value > 0 else {
        throw SomeClassError.NumberNotPositive
      }
    }
  }
}
当然,编译器抱怨没有处理
错误,因为封闭函数没有声明为“throws”
,我真的不知道在哪里声明
didSet
实际上
throws


您知道在property observer方法中是否有抛出错误的方法吗?

您可以调用属性observer中的函数
Do try catch`子句来抛出错误,例如

enum SomeClassError: ErrorType {
    case NumberNotPositive
}

class SomeClass {
    var positiveNumber: Int {
        willSet {
            do {
                try newValueIsPositive(newValue)
            } catch SomeClassError.NumberNotPositive {
                print("Error: Number not positive")
            } catch {
                print("Error: Unknown error")
            }
        }
    }

    init() {
        positiveNumber = 1
    }

    func newValueIsPositive(newValue: Int) throws {
        guard newValue > 0 else {
            throw SomeClassError.NumberNotPositive
        }
    }
}

/* Example */
var a = SomeClass()
a.positiveNumber = 2
a.positiveNumber = -1   // Error: Number not positive
print(a.positiveNumber) // -1

请注意,在使用
willSet
属性观察器时,我使用了默认可访问的
newValue
属性(而不是为
willSet
之后设置的值显式定义属性名称
value
)。还要注意的是,在您当前的表单中,类属性
positiveEnumber
仍然会被分配
-1
(尽管会抛出与此相关的
ErrorType
案例)。

请包括您的代码,我认为没有。获取或设置属性时,调用代码不希望抛出任何错误,因此观察者必须自己处理所有错误。如果您试图使用属性观察者进行验证,您可以还原为旧值或将属性重置为某个sentinel值。此代码不会阻止
positiveEnumber
假定无效值。实现这一点的一个可能的调整是将
willSet
转换为
didSet
,调用
newValueIsPositive(positiveEnumber)
,并在每个
catch
positiveEnumber=oldValue
@catalander的末尾添加,你说得对,正如我在您的评论之前添加的那样:)因为问题是关于在属性观察家中抛出错误,所以我将仅讨论该问题(但是,提及该免责声明)。但事实上,现在你已经开始练习投掷了,你似乎可以找到答案了!如果你不想完全隐藏错误,而是想把它吐给客户端怎么办?@dfri我在问你是否可以完全省略
do catch
设置,用
throws
标记
willSet
,并将错误发送给调用方,而不是完全在内部处理它。我想这就是OP最初想知道的。(即原始post能否将其行更改为“
willSet(value)throws{
”并完成它?@CTMacUser我认为这是(当前)Swift的限制,既不是setters/getter,也不是计算属性(以及属性观察器和下标)目前可以投掷,但在Swift的未来版本中自然会有兴趣包括这些投掷,参见例如Chris Lattner:s对的回应,以及。