(2021年9月追記)
Swift 5.5以降、computed propertyでもthrow
できるようになりました。
参照: https://github.com/apple/swift-evolution/blob/main/proposals/0310-effectful-readonly-properties.md
この記事はSwift 5.4以前を前提としています。
最初に結論
Result
をcomputed propertyで使うのはどうですか?(※推奨ではなく提案)
Computed propertyでもthrow
したい!
Swiftでは次のようなコードは書けません(Swift 5現在)。
enum E: Error {
case someError
}
struct S {
var someProperty: throws Int { // ⛔️ コンパイルできない
if Bool.random() {
return 0
} else {
throw E.someError
}
}
}
なぜならば、そもそもプロパティに対してthrows
というキーワードを使うことができないからです。throws
はfunc
(またはクロージャ)でしか使えないので、同様のことをしたい場合、普通はこうします:
enum E: Error {
case someError
}
struct S {
func someProperty() throws -> Int {
if Bool.random() {
return 0
} else {
throw E.someError
}
}
}
…ところで、Result
を使うという手もありませんかね??
enum E: Error {
case someError
}
struct S {
var someProperty: Result<Int, Error> {
return .init(catching: {
if Bool.random() {
return 0
} else {
throw E.someError
}
})
}
}
Result
を使うメリット?
特にメリットはありませんけども…あえて挙げるなら:
- *“プロパティはあくまでプロパティであってほしい。
func
は使いたくない。”*と思う気持ちを実現する。 -
.get()
を呼び出すまで評価1を遅延できる。
おわりに
単なる思いつきですが、個人的には*public
じゃない(∴そのモジュール内で完結する)プロパティ*で使用すると便利な(場面がある)のではないかと考えています。
-
ここでいう「評価」とはエラーが生じたかどうかを確認するという意味 ↩