(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
じゃない(∴そのモジュール内で完結する)プロパティで使用すると便利な(場面がある)のではないかと考えています。
-
ここでいう「評価」とはエラーが生じたかどうかを確認するという意味 ↩