我该如何在Swift中声明一个带有'throws'的计算属性?

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

对于上面的代码,Swift二进制文件会抱怨“错误没有被处理,因为未声明包含函数“throws”。

我如何在上述代码中声明“someProperty”会“throws”呢?

class SomeClass {
  var someProperty throws: Int {
  }
}

class SomeClass {
  var someProperty: throws Int {
  }
}

class SomeClass {
  var someProperty: Int throws {
  }
}

似乎不起作用。

4个回答

106

这个功能是在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》末尾的声明部分中只将throws(和rethrows)列为函数和初始化程序声明的关键字。


谢谢您提供的语言参考,它非常有说服力。我意识到这不是我所问的原始问题,但在我的情况下,我有一个容器类型,我只想在每个元素本身可哈希时实现'hashValue'。您知道我可以做什么来解决这个问题吗? - math4tots
将容器作为仅适用于Hashable元素的通用类型,这样做是否合理,就像Swift Dictionary键必须是Hashable一样?如果不是,我想你可能需要做一些工作来设计一个哈希函数,以防您的元素不可哈希,因为Hashable协议不允许nil响应并且无法抛出异常。如果适当的话,您也可以使用fatalError() - Charles A.
1
@math4tots,这可能来得太晚了,但请记住您可以添加约束扩展。例如,如果您定义了一个容器,如 struct Container<Element> {},则可以添加扩展,如 extension Container where Element: Hashable {} 并在扩展中定义计算属性。仅当 Container 实例内的 Element 类型为 Hashable 时,计算属性才可用。 - justinpawela
我认为Swift文档并没有详细说明这一点,但是请查看“类型约束”和“Where子句”部分泛型文档 - justinpawela

61

虽然在Swift的计算属性中目前还不能使用throw,但是我发现Chris Lattner本人在苹果开发者论坛帖子中回答了类似的问题:

我们同意你应该能够在下标和计算属性的getter和setter方法中使用"throws"关键字,但我们还没有实现。我们可能会在某个时候支持这个功能,但目前还不清楚它是否会及时添加到Swift 2中。


43
请注意,这在Swift 3中没有改变。 - mcfedr
43
请注意,这在Swift 4中没有改变。 - Wladek Surala
38
请注意,这在Swift 4.1中没有改变。 - imike
39
请注意,这在 Swift 4.2 中仍然没有改变。 - user652038
44
请注意,这在 Swift 5.0 中没有改变。 - CrossProduct
显示剩余9条评论

3

0
如果有人需要在协议要求中声明一个抛出异常和/或异步计算属性的话:
1. 抛出异常
protocol DatabaseProtocol {
    var isEmpty: Bool { get throws }
}

struct Database {
    var isEmpty: Bool {
        get throws {
            ...
        }
    }
}

2. 异步
protocol DatabaseProtocol {
    var isEmpty: Bool { get async }
}

struct Database {
    var isEmpty: Bool {
        get async {
            ...
        }
    }
}

3. 抛出和异步

protocol DatabaseProtocol {
    var isEmpty: Bool { get async throws }
}

struct Database {
    var isEmpty: Bool {
        get async throws {
            ...
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接