Swift'de İsteğe Bağlı için varsayılan bir değer mi sunuyorsunuz?


141

Swift'teki seçeneklerle uğraşma deyimi aşırı derecede ayrıntılı görünüyor, tek yapmanız gereken sıfır olduğu durumda varsayılan bir değer sağlamaksa:

if let value = optionalValue {
    // do something with 'value'
} else {
    // do the same thing with your default value
}

gereksiz şekilde çoğaltan kod içeren veya

var unwrappedValue
if let value = optionalValue {
    unwrappedValue = value
} else {
    unwrappedValue = defaultValue
}

unwrappedValuesabit olmayı gerektirmez .

Scala'nın Option monad'ı (temel olarak Swift'in Opsiyoneliyle aynı fikirdir) getOrElsebu amaç için metoda sahiptir :

val myValue = optionalValue.getOrElse(defaultValue)

Bir şey mi kaçırıyorum? Swift'in bunu yapmanın kompakt bir yolu var mı? Ya da başarısız olursa, getOrElseİsteğe bağlı için bir uzantıda tanımlamak mümkün mü?


Yanıtlar:


289

Güncelleme

Apple şimdi bir birleştirme operatörü ekledi:

var unwrappedValue = optionalValue ?? defaultValue

Üçlü operatör bu durumda arkadaşınızdır

var unwrappedValue = optionalValue ? optionalValue! : defaultValue

İsteğe bağlı numaralandırma için kendi uzantınızı da sağlayabilirsiniz:

extension Optional {
    func or(defaultValue: T) -> T {
        switch(self) {
            case .None:
                return defaultValue
            case .Some(let value):
                return value
        }
    }
}

Sonra sadece şunları yapabilirsiniz:

optionalValue.or(defaultValue)

Bununla birlikte, diğer geliştiricilerin oryöntemi araştırmak zorunda kalmadan çok daha hızlı anlayacağı için üçlü operatöre bağlı kalmanızı öneririm

Not : Bir başlatan modülü böyle ortak yardımcıları eklemek için orüzerine OptionalSwift için.


benim karşılaştırıcı bana unwrappedValueSwift 1.2 bu durumda hala isteğe bağlı türü olduğunu gösterir : var unwrappedValue = optionalValue ? optionalValue! : defaultValue(xcode 6 beta 4). Bu değişti mi?
SimplGy

2
Sürümümde yanılıyorum. 6.4'üm. Unutmayın: ??varsayılan tür çıkarım davranışı, isteğe bağlı olarak döndürülmesidir; Değişkeni isteğe bağlı olmayan olarak bildirebilirsiniz ve bu iyi çalışır.
SimplGy

29

Ağustos 2014 itibariyle Swift, buna izin veren birleştirme operatörüne (??) sahiptir. Örneğin, isteğe bağlı bir myOptional String için şunu yazabilirsiniz:

result = myOptional ?? "n/a"

4

yazdıysanız:

let result = optionalValue ?? 50

ve optionalValue != nilsonra da resultolacak optionalve gelecekte onu açmanız gerekecek

Ama operatör yazabilirsiniz

infix operator ??? { associativity left precedence 140 }

func ???<T>(optLeft:T?, right:T!) -> T!
{
    if let left = optLeft
    {
        return left
    }
    else { return right}
}

Şimdi yapabilirsin:

 let result = optionalValue ??? 50

Ve optionalValue != nilo zaman ne zaman resultolacakunwraped


3

Aşağıdaki işe yarıyor gibi görünüyor

extension Optional {
    func getOrElse<T>(defaultValue: T) -> T {
        if let value = self? {
            return value as T
        } else {
            return defaultValue
        }
    }
}

ancak oyunculara olan ihtiyaç value as Tçirkin bir hack. İdeal olarak, Tİsteğe Bağlı'da bulunan türle aynı olduğunu iddia etmenin bir yolu olmalıdır . TDurduğu gibi, getOrElse için verilen parametreye dayalı olarak çıkarım setleri yazın ve sonra İsteğe bağlı ve İsteğe bağlı sıfırdan farklıysa çalışma zamanında başarısız olur:

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

TYöntem için belirtmeniz gerekmez . Bu aslında mevcut Tolanı İsteğe Bağlı'dan geçersiz kılar . Sadece şunu yapabilirsiniz: func getOrElse(defaultValue: T) -> To zaman T isteğe bağlı gerçek değer türünü ifade eder ve kontrol etmek zorunda
kalmazsınız

Teşekkürler! Yanıtınızın ikinci yarısından tam olarak çıkarımda bulundum. Genel türün bu şekilde tanımlandığını bilmek için İsteğe bağlı tanımını incelemenin bir yolu var mı T? (sadece konvansiyona dayalı olduğunu varsaymanın ötesinde)
Wes Campaigne

Optionalenum Optional<T>
Xcode'un

Mükemmel. Tahmin etmeliydim. Buradaki tanımlar faydalı olacaktır; henüz belgelerde olmayan birçok şey var. Tekrar teşekkürler.
Wes Campaigne
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.