2013-11-04 19 views
13

Scala (2.1) için bir oyunla çalışıyorum ve bir "Option [Long]" değerini "Long" 'a çevirmem gerekiyor.“Convert” Seçeneği [x] x in x Scala

def toOption[Long](value: Long): Option[Long] = if (value == null) None else Some(value) 

Ama benim durumumda, ben, "Uzun süren bir yöntem haline türü olarak "Opsiyon [Long]" değeri geçmek zorunda: Ben tam tersini nasıl yapılacağını biliyorum

, yani ". Herhangi bir yardım lütfen.

cevap

22

Her şeyden önce, "tam tersi" uygulamanızın bazı ciddi sorunları vardır. Yönteme, Long adlı bir tür parametresi koyarak, standart kitaplıktan Long türünü gölgelediniz. Acı davetiye çıkarıyor java.lang.Long ve bahsediyorsan sürece, (scala.Long bir başvuru türü olmadığından ve null olamaz)

def toOption(value: Long): Option[Long] = 
    if (value == null) None else Some(value) 

Hatta bu tür saçma geçerli: Muhtemelen yerine aşağıdaki anlamına karışıklığı. ve ancak valuenull ise

def toOption(value: String): Option[String] = Option(value) 

Bu yöntem None döndürür: Son olarak, bir referans türü ile uğraşan olsalar bile (gibi String), tam olarak eşdeğerdir aşağıdakileri, yazma daha iyi olurdu . daha ziyade "kaldırma" foo ait Optionmap aracılığıyla içine Genellikle foo bir Option[Long] geçen açısından düşünmek gerekir

def foo(x: Long) = x * 2 

:

sorunuzu çözmek için, aşağıdaki yöntemi olduğunu varsayalım :

scala> val x: Option[Long] = Some(100L) 
x: Option[Long] = Some(100) 

scala> x map foo 
res14: Option[Long] = Some(200) 

Option bütün noktası bir bütün önlemek için (tip düzeyinde) "boş" bir değer olasılığını modellemektir NullPointerException sınıfı -y sorunları. kullanarak, Option, Option adresindeki değerlerle ilgili hesaplamalar yapmanıza olanak tanır ve boş olma olasılığını modellemeye devam eder.

Başka bir yanıt notu olarak, getOrElse'u Option'un "kurtarılması" için de kullanmak mümkündür, ancak bu genellikle Scala'daki deyimsel yaklaşım değildir (makul bir varsayılan değerin olduğu durumlar hariç).

1

Seçenek None olduğunda ne olacağına karar vermeniz gerekir. Varsayılan bir değer sağlıyor musunuz?

def unroll(opt: Option[Long]): Long = opt getOrElse -1L // -1 if undefined 

unroll(None) // -> -1 

Ayrıca bir özel durum: Eğer (opt.orNull) kullanmak için çok iyi nedenleri var olmadıkça durumda

def unroll(opt: Option[Long]): Long = opt.getOrElse(throw 
    new IllegalArgumentException("The option is expected to be defined at this point") 
) 

unroll(None) // -> exception 

, null kullanmaktan kaçının.

2

Seçenek, yan etkiyi yerelleştirmenin bir yoludur (işleviniz boş değeri döndürebilir).Ve iyi tarzı (Seçenek harita & flatMap yöntemleri ile Monad olan) Seçenek için hesaplama kaldırmaya karar verdi. yan etkinin manuel işleme ile

val x = Option[Long](10) 
x.map { a => a + 10 } 

ve ekstrakt değeri:

val res = x match { 
    case Some(a) => s"Value: $a" 
    case None => "no value" 
} 
+2

+1. –

5

Bu yöntem, daha önce, [A] Seçenek tanımlanır ve adı olsun:

scala> val x = Some(99L) 
x: Some[Long] = Some(99) 

scala> x.get 
res0: Long = 99 

sorun Hiçbiri Yok Etme Çağrısı Yoktur Bir ÖzelEkleme İstisnası:

scala> None.get 
java.util.NoSuchElementException: None.get 

Böylece, bir Option türünü kullanmanın herhangi bir faydası elde edemezsiniz.

Bu nedenle, daha önce de belirtildiği gibi, mantıklı bir varsayılan değer sağlayabiliyorsanız veya Özel Durumu işleme alabiliyorsanız getOrElse'u kullanabilirsiniz.

deyimsel scala yolu harita kullanarak olacağını veya for-anlama

x map (_ + 1) 
res2: Option[Long] = Some(100) 

ya da zaten getOrElse sözü edildiği gibi

for (i <- x) yield i +1 
res3: Option[Long] = Some(100) 
+1

Bu tam olarak aradığım şey. Teşekkürler Andreas. – Nandakishore

0

Eğer sorusuna cevap verirken aradığınızı muhtemelen direkt olarak.

sadece can bu bir seçenek dönüştürmek için de unutmayın:

val myOption = Option(1) 

myOption şimdi bazı (1)

val myOption = Option(null) 

myOption şimdi hiçbiri olacaksa olacaktır.

28

X seçeneğine sahipseniz [Long], x.get size Long verecektir. İsteğe bağlı değerleri ayıklamak için desen eşleştirmeyi kullanmak için

+3

Bu cevap yanlış. Eğer x "Yok" ise (Opsiyon [Long] 'ın olası bir değeridir),' get 'ibaresi bir hata verecektir. –

+5

x.getOrElse (None) – user3886907

+1

'u kullanabiliyoruz Basit, saçma sapan bir cevap yok. –