Swiftのオプションを処理するイディオムは、過度に冗長に思えますが、nilの場合にデフォルト値を提供するだけでよい場合は、次のようになります。
if let value = optionalValue {
// do something with 'value'
} else {
// do the same thing with your default value
}
不必要にコードを複製すること、または
var unwrappedValue
if let value = optionalValue {
unwrappedValue = value
} else {
unwrappedValue = defaultValue
}
unwrappedValue
が定数でないことを要求します。
Scalaのオプションモナド(基本的にはSwiftのオプションと同じアイデアです)には、この目的のためのメソッドgetOrElse
があります。
val myValue = optionalValue.getOrElse(defaultValue)
何か不足していますか? Swiftには既にそれを行うコンパクトな方法がありますか?または、それが失敗した場合、Optionalの拡張でgetOrElse
を定義することは可能ですか?
更新
Appleは合体演算子を追加しました:
var unwrappedValue = optionalValue ?? defaultValue
この場合、三項演算子はあなたの友達です
var unwrappedValue = optionalValue ? optionalValue! : defaultValue
オプションの列挙型に独自の拡張機能を提供することもできます。
extension Optional {
func or(defaultValue: T) -> T {
switch(self) {
case .None:
return defaultValue
case .Some(let value):
return value
}
}
}
その後、あなたはちょうどすることができます:
optionalValue.or(defaultValue)
ただし、他の開発者はor
メソッドを調査する必要なく、より迅速にそれを理解するため、三項演算子に固執することをお勧めします。
注:or
on Optional
のような一般的なヘルパーをSwiftに追加するために モジュール を開始しました。
2014年8月現在、Swiftにはそれを可能にする合体演算子(??)があります。たとえば、オプションのString myOptionalの場合、次のように記述できます。
result = myOptional ?? "n/a"
あなたが書いた場合:
let result = optionalValue ?? 50
optionalValue != nil
その後result
もoptional
になります。今後は展開する必要があります
しかし、あなたは演算子を書くことができます
infix operator ??? { associativity left precedence 140 }
func ???<T>(optLeft:T?, right:T!) -> T!
{
if let left = optLeft
{
return left
}
else { return right}
}
次のことができます。
let result = optionalValue ??? 50
optionalValue != nil
の場合、result
はunwraped
になります
以下はうまくいくようです
extension Optional {
func getOrElse<T>(defaultValue: T) -> T {
if let value = self? {
return value as T
} else {
return defaultValue
}
}
}
ただし、value as T
をキャストする必要はいハックです。理想的には、T
がOptionalに含まれるタイプと同じであることをアサートする方法があるはずです。現状では、型推論はgetOrElseに指定されたパラメーターに基づいてT
を設定し、これがOptionalと一致せずOptionalが非nilの場合、実行時に失敗します。
let x: Int?
let y = x.getOrElse(1.414) // y inferred as Double, assigned 1.414
let a: Int? = 5
let b: Double = a.getOrElse(3.14) // Runtime failure casting 5 to Double