2010-09-24 14 views
28

Aşağıdaki Scala kodum var.Seçenek [ile] Scala kalıbı eşleşmesi Seçenek [0]

scala> Test.test 
Int received Some(Hi) 
Int received Some(0) 

Ben çıkışı

String received Some(Hi) 
Int received Some(0) 

açıklama nedir bekliyordum: Test.test yaptıktan sonra

import scala.actors.Actor 

object Alice extends Actor { 
    this.start 
    def act{ 
    loop{ 
     react { 
     case "Hello" => sender ! "Hi" 
     case i:Int => sender ! 0 
     } 
    } 
    } 
} 
object Test { 
    def test = { 
    (Alice !? (100, "Hello")) match { 
     case i:Some[Int] => println ("Int received "+i) 
     case s:Some[String] => println ("String received "+s) 
     case _ => 
    } 
    (Alice !? (100, 1)) match { 
     case i:Some[Int] => println ("Int received "+i) 
     case s:Some[String] => println ("String received "+s) 
     case _ => 
    } 
    } 
} 

ben Çıktı olsun?

C:\scalac -unchecked a.scala 
a.scala:17: warning: non variable type-argument Int in type pattern Some[Int] is unchecked since it is eliminated by erasure 
     case i:Some[Int] => println ("Int received "+i) 
      ^
a.scala:18: warning: non variable type-argument String in type pattern Some[String] is unchecked since it is eliminated by erasure 
     case s:Some[String] => println ("String received "+s) 
      ^
a.scala:22: warning: non variable type-argument Int in type pattern Some[Int] is unchecked since it is eliminated by erasure 
     case i:Some[Int] => println ("Int received "+i) 
      ^
a.scala:23: warning: non variable type-argument String in type pattern Some[String] is unchecked since it is eliminated by erasure 
     case s:Some[String] => println ("String received "+s) 
      ^
four warnings found 

nasıl uyarıları önleyebilirsiniz şu şekildedir:

ikinci soruya gelince, ben yukarıdaki ile unchecked uyarı olsun?

DÜZENLEME: Öneriler için teşekkürler. Daniel'in fikri güzel ama uyarı karşılaşıldığında hatası aşağıdaki

def test[T] = (Alice !? (100, "Hello")) match { 
    case Some(i: Int) => println ("Int received "+i) 
    case Some(t: T) => println ("T received ") 
    case _ => 
} 

aşağıdaki örnekte olduğu gibi, genel türler ile çalışmak görünmüyor: warning: abstract type T in type pattern T is unchecked since it is eliminated by erasure

cevap

36

. JVM, diziler dışında herhangi bir tür parametresi bilmez. Bu nedenle, Scala kodu Option'un Option[Int] veya Option[String] olup olmadığını denetleyemez - bu bilgiler silinmiştir.

Gerçi bu şekilde kodunuzu düzeltmek:

object Test { 
    def test = { 
    (Alice !? (100, "Hello")) match { 
     case Some(i: Int) => println ("Int received "+i) 
     case Some(s: String) => println ("String received "+s) 
     case _ => 
    } 
    (Alice !? (100, 1)) match { 
     case Some(i: Int) => println ("Int received "+i) 
     case Some(s: String) => println ("String received "+s) 
     case _ => 
    } 
    } 
} 

Bu Option türüdür yaradığını test edilmez yolu, ama ne içeriğinin tipi vardır - orada varsayarak içeriktir. Bir None, varsayılan duruma düşecektir.

+0

Teşekkürler! Kevin'in önerdiği çözüm de dahil olmak üzere diğer cevaplar da iyi. Ama bu, kodumu yeniden yazmadan düzeltmenin en zarif yolu gibi görünüyor. – Jus12

+0

Genel türler için benzer bir çözüm önerebilir misiniz? olduğu gibi: 'def testi [T] = (Alice!? (100," Merhaba ")) {case Some (t: T) => println (" T received "); _ => println ("başka bir şey alındı")} ' – Jus12

+1

@ Jus12 Bu yol çalışmaz. Bir "m: Manifest [T]" almanız gerekecek, daha sonra birşey yapmalısınız, eğer m.erasure.isAssignableFrom (t.getClass()) => 'ise. –

8

tip parametreleri hakkında herhangi bir bilgi derleme sırasında yalnızca -time, çalışma zamanında değil (bu tip silme olarak bilinir). Bu, çalışma zamanında Option[String] ve Option[Int] arasında bir fark olmadığı anlamına gelir, bu nedenle Option[String] türünde herhangi bir desen eşlemesi, aynı zamanda çalışma zamanında her ikisi de yalnızca Option olduğu için Option[Int] ile eşleşecektir.

Neredeyse her zaman niyetiniz olmadığı için, bir uyarı alırsınız. Uyarıyı önlemenin tek yolu, çalışma zamanında bir türün genel türünü kontrol etmemek (bu iyi bir şey çünkü bu zaten istediğiniz gibi çalışmıyor).

bir Option (bir Some ise içeriği teftiş hariç) bir Option[Int] veya çalışma zamanında bir Option[String] olup olmadığını kontrol etmek yolu yoktur.

2

Daha önce de belirtildiği gibi, burada silmeye karşı olursunuz.

çözüm için

... Size göndermeye olasıdır her mesaj türü için durum sınıfları tanımlamak için Scala aktörle normaldir: Bu tip-silinmesini kaynaklanmaktadır

case class MessageTypeA(s : String) 
case class MessageTypeB(i : Int) 

object Alice extends Actor { 
    this.start 
    def act{ 
    loop{ 
     react { 
     case "Hello" => sender ! MessageTypeA("Hi") 
     case i:Int => sender ! MessageTypeB(0) 
     } 
    } 
    } 
} 
object Test { 
    def test = { 
    (Alice !? (100, "Hello")) match { 
     case Some(MessageTypeB(i)) => println ("Int received "+i) 
     case Some(MessageTypeA(s)) => println ("String received "+s) 
     case _ => 
    } 
    (Alice !? (100, 1)) match { 
     case Some(MessageTypeB(i)) => println ("Int received " + i) 
     case Some(MessageTypeA(s)) => println ("String received " + s) 
     case _ => 
    } 
    } 
}