2012-12-18 18 views
9
Ben çirkin görünüyor tahmin değiştirici, rutin kendim

Scala iyi uygulamalar: Basit Seçenek [] kullanımı

val itemOpt: Option[Item] = items.get(coords) // "items" is something like a Map 
if (itemOpt.isDefined) { 
    val item = itemOpt.get 
    // do something with item, querying item fields a lot of times, for example 
    if (item.qty > 10) { 
    storeInVault(item.name, item.qty, coords) 
    } else { 
    storeInRoom(item) 
    } 
} 

gibi boş taşıma şeyler yeniden bulmak Java to-Scala bir olarak

ve gerçekten bir benziyor Java'nın dan yeniden yazılmış kod parçası:

Item item = items.get(coords); 
if (item != null) { 
    // do something with item, querying item fields a lot of times, for example 
} 

Ayrıca Java çirkin görünüyor, ama en azından bir satır az. Scala'da bu gibi basit durumlarla başa çıkmak için en iyi uygulama nedir? Option[Stuff] koleksiyonlarını işlemek için flatMap ve flatten'u zaten biliyorum ve varsayılan değerleri işlemek için getOrElse'u biliyorum. Ben böyle bir şey hayal:

items.get(coords).doIfDefined(item => 
    // do stuff with item 
) 

ama Option API böyle bir şey görmüyorum.

+4

Bu yardımcı olabilir: http://dibblego.wordpress.com/2008/01/16/scalaoption-cheat-sheet/ – dhg

cevap

12

Çok popüler kullanım deseni: onu tanımlanan eğer

val item: Option[Int] = None 
val result = item map (_ + 1) getOrElse 0 

yüzden sadece değerini dönüştürmek amacıyla map kullanın. sadece değerini kullanmak istiyorsanız

, bu bir Option içinde saklanır, o zaman sadece foreach kullanın: aslında gerekmez

item foreach { it => 
    println(it) 
} 

Gördüğünüz gibi, Option da, birçok toplama yöntemleri destekler yeni API öğrenmek için. Sadece 1 veya 0 elementli bir koleksiyon olarak kullanabilirsiniz.

7

Bu Yapmanız aradıklarını başarmak olmalıdır:

items.get(coords).foreach{ item => 
    //do stuff 
} 
+6

Alternatif sadece (öğe <- maybeItem) için comprehensions 'için kullanmak {.. .} 'belki de '' seçeneğiniz budur. –

+0

Daha da alçakgönüllü olmak için not: 'items.get (coords) map {item => // ...' –

5

Bu Morris Morris kontrol edin post. Option'u anlamaya çalıştığımda bana çok yardımcı oldu. Kodunuz böyle bir şekilde yeniden yazılabilir:

for (item <- items.get(coords)) { // "items" is something like a Map 
    // do something with item, querying item fields a lot of times, for example 
    if (item.qty > 10) { 
    storeInVault(item.name, item.qty, coords) 
    } else { 
    storeInRoom(item) 
    } 
} 
3

Ayrıca Seçenek if bekçi ile Desen eşleştirmesi de kullanılabilir. kişisel olarak bu senaryoda kullanmayı seviyorum ve okumayı daha kolay olduğunu düşünüyorum. Eğer ilk yapmak ve ardından itemOpt Some veya None bir olup olmadığını görmek için incelemek için Eşleştirme Desen kullanarak böylece sen Seçeneği None olmadığında

bir Opsiyonu'ndaki map Çünkü etkiye sahip tek olacaktır.

def shouldInVault(item: Item) = item.qty > 10 

val itemOpt: Option[Item] = items.get(coords).map(...) 

itemOpt match { 
    case Some(item) if shouldInVault(item) => storeInVault(item.name, item.qty, coords) 
    case Some(item) => storeInRoom(item) 
    case None => 
} 
İlgili konular