TL; DR 이것은 스칼라 2.9.x위한
사용 스칼라 2.10.x위한
def typeOnly[T](seq : Seq[Any])(implicit m : Manifest[T]) : Seq[T] = {
seq.collect {
case t if m.erasure.isInstance(t) => t.asInstanceOf[T]
}
}
scala> typeOnly[String](List(1,2,"3",4))
res1: Seq[String] = List(3)
이 : Seq
로서
def typeOnly[T](seq : Seq[Any])(implicit tag : scala.reflect.ClassTag[T]) = {
seq.collect {
case t if tag.runtimeClass.isInstance(t) => t.asInstanceOf[T]
}
}
가 trait Seq[+A]
로 정의 (키는 +
) Seq[S]
도입니다..
반면에 이미 말했듯이 T는 함수가 컴파일 될 때 "잊혀진"것이므로 직접 사용할 수 없습니다. Class of T를 매개 변수로 전달해야합니다. 스칼라
def typeOnly[T](seq : Seq[Any], c : Class[T]) : Seq[T] = {
seq.flatMap {
case t if c.isInstance(t) => Some(t.asInstanceOf[T])
case _ => None
}
}
, 아파트에서 Class[T]
, 결과적으로 더 관용적 약간 더 강력하고, 이는 또한 Manifest[T]
있다. 특히 Class[T]
을 반환하는 erasure
메서드가 있습니다. 그것을 사용하면 가서 같이 함수를 작성할 수
def typeOnly[T](seq : Seq[Any], m : Manifest[T]) : Seq[T] = {
seq.flatMap {
case t if m.erasure.isInstance(t) => Some(t.asInstanceOf[T])
case _ => None
}
}
우리가 아무것도 얻은없는 것 같다. 그러나 컴파일러에게 (implicit
을 사용하여) 멋지게 질문하면 함수를 호출 할 때 Manifest
이 전달됩니다.
def typeOnly[T](seq : Seq[Any])(implicit m : Manifest[T]) : Seq[T] = {
seq.flatMap {
case t if m.erasure.isInstance(t) => Some(t.asInstanceOf[T])
case _ => None
}
}
예 :
scala> typeOnly[java.lang.Integer](List(1,2,"3",4))
res2: Seq[java.lang.Integer] = List(1, 2, 4)
scala> typeOnly[String](List(1,2,"3",4))
res3: Seq[String] = List(3)
scala> typeOnly[java.lang.Double](List(1,2,"3",4))
res4: Seq[java.lang.Double] = List()
은 그들 중 일부는 아직 더 관용적 더 많은 대안이있다. 당신은, 예를 들어, 는 부분적으로 정의 기능을 collect
을 사용할 수
def typeOnly[T](seq : Seq[Any])(implicit m : Manifest[T]) : Seq[T] = {
seq.collect {
case t if m.erasure.isInstance(t) => t.asInstanceOf[T]
}
}
경고을 : 전 예는 다음과 에서 스칼라 2.9.3와 작동합니다. 스칼라 2.10.x 용으로 개발중인 경우 Manifest#erasure
은 사용되지 않습니다. 대신 runtimeClass
를 사용하여 매니페스트가 곧 (아래에 의견을 참조)도 더 이상 사용되지 않습니다
def typeOnly[T](seq : Seq[Any])(implicit m : Manifest[T]) = {
seq.collect {
case t if m.runtimeClass.isInstance(t) => t.asInstanceOf[T]
}
}
, 당신은 ClassTag을 사용하는 것이 좋습니다.
def typeOnly[T](seq : Seq[Any])(implicit tag : scala.reflect.ClassTag[T]) = {
seq.collect {
case t if tag.runtimeClass.isInstance(t) => t.asInstanceOf[T]
}
}
컴파일러 ** ** 사실을 추론 할 수있다 목록 (1, "2", 3 '이 " 4 ")'는'Seq [Any]'이지만, 당신이 실수로 두 번째 유형을 지정하는 것을 잊었다 고 생각할 때 살 수는 없습니다. Seq 유형은 런타임에 지워지기 때문에 일치가 쓸모 없다는 점에 유의하십시오. –
글쎄, 네 말이 맞아. 클래스 유형으로이 메소드를 다시 작성할 수 있습니까? –
타입 안전을 기꺼이 원한다면'Lists '대신에'HLists'를 사용하는 것을 고려해보십시오. [shapeless 라이브러리] (https://github.com/milessabin/shapeless/)에서 구현하면 원하는 것을 수행하는 메서드 ('filter')가 있습니다. [예] (https://github.com/milessabin/shapeless/blob/master/core/src/test/scala/shapeless/hlist.scala#L604-L632). – folone