[SCALA] 매개 변수 유형 스칼라 asInstanceOf
SCALA매개 변수 유형 스칼라 asInstanceOf
내가 캐스트가를 입력 할 수있는 함수를 작성하고 싶습니다 A는 될 수있는 예를 들어, 목록 [지능], 또는 맵 [INT, 목록 [지능]]와 같은 더 복잡한 파라미터 화 된 형태.
def castToType[A](x: Any): A = {
// throws if A is not the right type
x.asInstanceOf[A]
}
유형이 정확하지 않은 경우에도 지금 (내가 믿는) 삭제를 입력하기 때문에,이 코드는 명랑하게 작동합니다. 오류 액세스 만 매니페스트, witha의의는 ClassCastException.
val x = List(1, 2, 3)
val y = castToType[List[String]](x)
y(0) --> throws java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
내가 제대로이 작품을 만들기 위해 매니페스트를 사용할 수있는 방법이 있나요? 감사!
해결법
-
==============================
1.불행하게도, asInstanceOf의 고유 제한이. 나는 실제로 세부 사항을 언급 scaladoc을보고 놀라게하고 있습니다 :
불행하게도, asInstanceOf의 고유 제한이. 나는 실제로 세부 사항을 언급 scaladoc을보고 놀라게하고 있습니다 :
당신은 주로 사용자의 DB / memcached를 인터페이스에서 물건을 다시 가져올 때 가능성이 주요 문제가 될 것입니다에 이동에 대한 잘못된 캐스트에 빠른 실패에 대해 우려하는 경우, 나는에 이동 객체의 머리의 캐스팅을 강제 주위를 연주했다 :
def failFastCast[A: Manifest, T[A] <: Traversable[A]](as: T[A], any: Any) = { val res = any.asInstanceOf[T[A]] if (res.isEmpty) res else { manifest[A].newArray(1).update(0, res.head) // force exception on wrong type res } }
간단한 예에 그것은 작동합니다 :
scala> val x = List(1, 2, 3): Any x: Any = List(1, 2, 3) scala> failFastCast(List[String](), x) java.lang.ArrayStoreException: java.lang.Integer [...] scala> failFastCast(List[Int](), x) res22: List[Int] = List(1, 2, 3)
하지만 좀 더 복잡한 하나에 :
val x = Map(1 -> ("s" -> 1L)): Any failFastCast(Map[Int, (String, String)](), x) // no throw
재귀 적으로 더 이상 유형 매개 변수가 없을 때까지 캐스팅 유지하기 위해 드릴 다운 할 수있는 방법이 있는지 궁금합니다 ...
-
==============================
2.당신은 참으로 정확 - 타입 삭제 수단 당신 예를 들어, 목록 [지능]과 목록 [문자열]을 구별하는 방식으로하지 "캐스트"할 수 있습니다. 당신은 지능과 문자열 사이에 구별 할 수 있음을 의미하지만, 당신은이 같은 방식으로 삭제된다 수행중인 캐스트에 향상시킬 수 있습니다 :
당신은 참으로 정확 - 타입 삭제 수단 당신 예를 들어, 목록 [지능]과 목록 [문자열]을 구별하는 방식으로하지 "캐스트"할 수 있습니다. 당신은 지능과 문자열 사이에 구별 할 수 있음을 의미하지만, 당신은이 같은 방식으로 삭제된다 수행중인 캐스트에 향상시킬 수 있습니다 :
def cast[A](a : Any) = a.asInstanceOf[A] //... is erased to def erasedCast(a : Any) = a.asInstanceOf[Any]
당신은 무엇을 매니페스트를 사용하여 제네릭을 구체화하는 필요
def cast[A <: AnyRef : Manifest](a : Any) : A = manifest[A].erasure.cast(a).asInstanceOf[A]
최종 캐스트 AnyRef에 삭제되는 동안, 적어도 당신은 최고 수준의 종류가 올바르지 얻을 수있는 올바른 클래스 [_] 예 (manifest.erasure)을 가져야한다. 행동 :
scala> cast[String]("Hey") res0: String = Hey scala> cast[java.lang.Integer]("Hey") java.lang.ClassCastException at java.lang.Class.cast(Class.java:2990) at .cast(<console>:7) at .<init>(<console>:9) scala> cast[List[String]](List("Hey")) res2: List[String] = List(Hey) scala> cast[List[Int]](List("Hey")) res3: List[Int] = List(Hey)
내 조언이 대상이 목록은 정말 여부를 결정하는 중첩 된 반사를 사용하지 않는 것입니다 [지능] :이 일반적으로 가능하지 않다. 무엇을 다음과 반환해야합니다 위해?
cast[List[Int]](List[AnyVal](1, 2))
-
==============================
3.당신은 마일 사빈에서 무형의 Typeable을 사용할 수 있습니다 :
당신은 마일 사빈에서 무형의 Typeable을 사용할 수 있습니다 :
형식 매개 변수를 사용하여 주조 입력
그것은 특정 것들이지만, 많은 경우에 삭제를 처리합니다 :
scala> import shapeless._; import syntax.typeable._ import shapeless._ import syntax.typeable._ scala> val x = List(1, 2, 3) x: List[Int] = List(1, 2, 3) scala> val y = x.cast[List[String]] y: Option[List[String]] = None
당신은 그것의 소스를 참조 할 수 있습니다 처리하는 경우 세트를 보려면 :
https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/typeable.scala
-
==============================
4.예, 문제 유형의 삭제로 인해 발생합니다. 당신이하려고하면
예, 문제 유형의 삭제로 인해 발생합니다. 당신이하려고하면
val x = List(1,2,3) val y = castToType[Int](x)
예상대로 예외는, 바로 발생합니다. 배열 [문자열] 또는 배열 [지능]에 캐스팅하려고 할 때 같은가 발생합니다.
난 당신이 일반적인 형식 변환기를 만들 수 있다고 생각하지 않는 컬렉션과 다른 개체 내부 작품 것이다 종류. 각 객체 유형에 대한 변환기를 만들어야합니다. 예를 들면 :
def castToType[A](x: List[A]) = x.map(i => i.asInstanceOf[A])
-
==============================
5.이 솔루션을 고려 :
이 솔루션을 고려 :
trait -->[A, B] { def ->(a: A): B } implicit val StringToInt = new -->[String, Int] { def ->(a: String): Int = a.toInt } implicit val DateToLong = new -->[java.util.Date, Long] { def ->(a: java.util.Date): Long = a.getTime } def cast[A,B](t:A)(implicit ev: A --> B):B= ev.->(t)
장점은 것입니다 :
이제 당신은 그것을 있도록 사용할 수 있습니다 :
scala> cast(new java.util.Date()) res9: Long = 1361195427192 scala> cast("123") res10: Int = 123
편집하다
나는 약간의 시간을 보냈다이 고급 코드를 작성했습니다. 첫 번째는 내가 그것을 사용하는 방법을 보여 보자 :
scala> "2012-01-24".as[java.util.Date] res8: java.util.Date = Tue Jan 24 00:00:00 CET 2012 scala> "2012".as[Int] res9: Int = 2012 scala> "2012.123".as[Double] res12: Double = 2012.123 scala> "2012".as[Object] // this is not working, becouse I did not provide caster to Object <console>:17: error: could not find implicit value for parameter $greater: -->[String,Object] "2012".as[Object] ^
꽤 좋은? 스칼라 마법을 참조하십시오 :
trait -->[A, B] { def ->(a: A): B } implicit val StringToInt = new -->[String, Int] { def ->(a: String): Int = a.toInt } implicit val StringToDate = new -->[String, java.util.Date] { def ->(a: String): java.util.Date = (new java.text.SimpleDateFormat("yyyy-MM-dd")).parse(a) } implicit val StringToDouble = new -->[String, Double] { def ->(a: String): Double = a.toDouble } trait AsOps[A] { def as[B](implicit > : A --> B): B } implicit def asOps[A](a: A) = new AsOps[A] { def as[B](implicit > : A --> B) = > ->(a) }
from https://stackoverflow.com/questions/6686992/scala-asinstanceof-with-parameterized-types by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 유형 매개 변수 대 추상 유형 (0) | 2019.11.16 |
---|---|
[SCALA] 스칼라 피보나치 수의 시퀀스를 생성 [중복] (0) | 2019.11.16 |
[SCALA] 어떻게 스칼라에 열거하는 방법을 추가? (0) | 2019.11.15 |
[SCALA] 스칼라 세트 같은 요소를 포함하지만, sameElements ()는 false를 돌려줍니다 (0) | 2019.11.15 |
[SCALA] 볼품를 사용하는 경우 클래스에 맵 [문자열, 어떤] 변환 (0) | 2019.11.15 |