비교할 항목이 없으므로 유형을 직접 비교할 수 없습니다 (런타임시 erasure로 인해). 당신은 당신의 클래스의 표현에 일할 수 :
trait TraitA { }
trait TraitB { }
class ClassA extends TraitA { }
class ClassB extends TraitB { }
def myFunc[T](clazz: Class[T]) = {
if (classOf[TraitA] isAssignableFrom clazz) println("A")
else if (classOf[TraitB] isAssignableFrom clazz) println("B")
else println("?")
}
scala> myFunc(classOf[ClassA])
A
scala> myFunc(classOf[String])
?
또는 수있는 클래스의 인스턴스에 패턴 일치 :
이
def myFunc2[T](t: T) = t match {
case _: TraitA => println("A")
case _: TraitB => println("B")
case _ => println("?")
}
scala> myFunc2(new ClassA)
A
scala> myFunc2(Some(5))
?
또한 클래스를 통해 구문 적으로 덜 강요하는 방법으로 첫 번째 방법을 사용할 수 있습니다
def myFunc3[T](implicit mf: ClassManifest[T]) = {
val clazz = mf.erasure
if (classOf[TraitA] isAssignableFrom clazz) println("A")
else if (classOf[TraitB] isAssignableFrom clazz) println("B")
else println("?")
}
scala> myFunc3[ClassA]
A
scala> myFunc3[String]
?
당신은이/다른 휘두르기 쉬운 될 경우에도 경우 파견의 다른 종류를 선택할 수 있습니다 : 명단
을
object MyFunc {
val dispatch = Map(
classOf[TraitA] -> (() => println("A")),
classOf[TraitB] -> (() => println("B"))
)
val default =() => println("?")
def apply[T](implicit mf: ClassManifest[T]) =
dispatch.find(_._1 isAssignableFrom mf.erasure).map(_._2).getOrElse(default)()
}
scala> MyFunc[ClassA]
A
scala> MyFunc[String]
?
여기에서 사용하는 모든 일반 코드는 암시 적 매개 변수 또는 축약어로 [T: ClassManifest]
인 클래스 매니페스트를 사용할 수 있어야합니다.
실제로 내 경우에는 잘 작동하는 2 가지 방법을 발견했습니다. 1) classOf [TraitA] isAssignableFrom clazz – codefly
+1 : 처음에는 대답과 스칼라 모두에 짜증이났다. ("유형이 없기 때문에 유형을 직접 비교할 수 없다. ** * 아무것도 없다. * 비교할 곳이 있습니다 "... ** 유형 **이 있으며 유형은 확실합니다."값이 * 없습니다 * "라는 문구를 작성해야합니다. 그런데 클래스 매니페스트에 대해 설명해 주셨습니다. 감사합니다! – rsenna
@rsenna - "아무 것도 없습니다"라는 말은 "T"는 컴파일러에게 타입을 컴파일 타임에 똑바로 유지해야하는 방법을 알려주기 때문에 거기에 아무것도 없다는 것을 의미했습니다. 그래서 실제로 ... 제네릭 타입은 런타임에 아무 것도 없습니다. 그것은 사라 졌어요. ("타입 소거.") Manifest는 런타임에 컴파일 타임 정보를 제공하는 방법을 제공합니다. ('ClassTag' 또는'TypeTag'는 2.10에서 그것을하기위한 새로운 방법입니다. 그러나 옛날 방식은 여전히 작동합니다.) 어쨌든, 내 말씨가 아주 재치가 없더라도 당신이 유용하다는 것을 알았 기 때문에 기쁩니다! –