【问题标题】:How do I declare that a computed property 'throws' in Swift?如何在 Swift 中声明计算属性“抛出”?
【发布时间】:2015-12-30 04:51:12
【问题描述】:
class SomeClass {
  var someProperty: Int {
    throw Err("SNAFU")
  }
}

对于像上面这样的代码,swift 二进制文件抱怨“错误没有被处理,因为封闭函数没有被声明为“抛出”。

如何在上面声明“someProperty”“抛出”?

class SomeClass {
  var someProperty throws: Int {
  }
}

class SomeClass {
  var someProperty: throws Int {
  }
}

class SomeClass {
  var someProperty: Int throws {
  }
}

好像没用。

【问题讨论】:

    标签: swift exception swift2


    【解决方案1】:

    在 Swift 5.5 中为只读计算属性添加了此功能,作为 SE-0310 的一部分(包含在 Xcode 13 中)。

    基于 SE-0310,语法为:

    class SomeClass {
      var someProperty: Int {
        get throws {
          throw Err("SNAFU")
        }
      }
    }
    

    这是 Swift 5.5 之前版本的先前答案:

    您不能从计算属性中抛出。如果你想抛出,你必须使用一个函数。 The Swift Programming Language 末尾的 Declarations section of the Language Reference 部分仅将 throws(和 rethrows)列为函数和初始化程序声明的关键字。

    【讨论】:

    • 感谢您的语言参考;这很有说服力。我意识到这不是我问的原始问题,但在我的场景中,我有一个容器类型,我只想在每个元素本身都是可哈希的时实现“hashValue”。你知道我能做些什么来解决这个问题吗?
    • 让你的容器成为只适用于Hashable元素的泛型类型是否合理,就像快速Dictionary键必须是Hashable一样?如果不是,我想你可能需要做一些工作来提出一个散列函数,因为Hashable protocol 不允许nil 响应并且你不能throw。如果合适的话,你也可以使用fatalError()
    • @math4tots 这肯定来得太晚了,但请记住,您可以添加约束的扩展。例如,如果你有一个像struct Container<Element> {} 这样定义的容器,那么你可以添加一个像extension Container where Element: Hashable {} 这样的扩展,并在扩展中定义你的计算属性。仅当 Container 实例中的 Element 类型为 Hashable 时,计算属性才可用。
    • 我认为 Swift 文档并没有真正说明这一点,但请查看 Generics docs 的“类型约束”和“Where 子句”部分。
    【解决方案2】:

    虽然从 Swift 的计算属性中不可能(还)throw,但我发现 Chris Lattner 本人在 one of Apple Developer Forums threads 上解决了同样的问题:

    我们同意您应该能够在下标和计算属性中将 getter 和 setter 标记为“抛出”,但还没有实现。我们可能会在某个时候支持此功能,但尚不清楚它是否会在 Swift 2 中及时实现。

    【讨论】:

    • 请注意,这在 swift 3 中没有改变。
    • 请注意,这在 Swift 4 中没有改变。
    • 请注意,这在 Swift 4.1 中没有改变。
    • 请注意,这在 Swift 4.2 中没有改变。
    • 请注意,这在 Swift 5.0 中没有改变。
    【解决方案3】:

    让我建议一个解决方法:可以将属性声明为具有Result<DesiredPropertyType, Error> 的类型。这样就可以像这样访问它:

    do {
        try self.failableProperty.get()
    } catch {
        ...
    }
    

    get() 是 Swift 的 Resultbuilt-in 方法。

    更新:这在 Swift 5.5 中通过“有效的只读属性”得到解决:https://github.com/apple/swift-evolution/blob/main/proposals/0310-effectful-readonly-properties.md

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-07
      • 1970-01-01
      • 2019-04-18
      • 1970-01-01
      • 1970-01-01
      • 2017-11-03
      • 2018-03-17
      • 1970-01-01
      相关资源
      最近更新 更多