web-dev-qa-db-ja.com

Swiftでオプションのデフォルト値を提供しますか?

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を定義することは可能ですか?

128
Wes Campaigne

更新

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に追加するために モジュール を開始しました。

265
drewag

2014年8月現在、Swiftにはそれを可能にする合体演算子(??)があります。たとえば、オプションのString myOptionalの場合、次のように記述できます。

result = myOptional ?? "n/a"
27
MirekE

あなたが書いた場合:

let result = optionalValue ?? 50

optionalValue != nilその後resultoptionalになります。今後は展開する必要があります

しかし、あなたは演算子を書くことができます

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の場合、resultunwrapedになります

3
UnRewa

以下はうまくいくようです

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
2
Wes Campaigne