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