[SCALA] 매개 변수 목록에서 경우 클래스를 인스턴스화
SCALA매개 변수 목록에서 경우 클래스를 인스턴스화
주어진:
case class Foo(a: Int, b: String, c: Double)
당신은 말할 수있다 :
val params = Foo(1, "bar", 3.14).productIterator.toList
그리고 얻다:
params: List[Any] = List(1, bar, 3.14)
"뒤로 이동"과 즉이 목록에서 직접 푸 개체를 다시 만들려면 방법이 있나요 :
Foo.createFromList(params) // hypothetical
대신 작성 :
Foo(params(0).asInstanceOf[Int], params(1).asInstanceOf[String], params(2).asInstanceOf[Double])
편집 : 그것은 예컨대, 명시 적으로를 작성하지 않고 함수에 매개 변수로리스트의 요소를 보낼 수있는 귀결 것 같다 :
def bar(a: Int, b: Int, c: Int) = //...
val list = List(1, 2, 3, 4, 5)
bar(list.take(3)) // hypothetical, instead of:
bar(list(0), list(1), list(2))
나는 종류의 할 수 있기를 기대 :
bar(list.take(3): _*)
그러나 그것은 작동하지 않습니다.
편집 : 솔루션은 즉석의 답변에 따라,하지만 생성자를 호출하는 대신 직접의이 방법을 적용하여 :
case class Foo(a: Int = 0, b: String = "bar", c: Double = 3.14) {
val cs = this.getClass.getConstructors
def createFromList(params: List[Any]) =
cs(0).newInstance(params map { _.asInstanceOf[AnyRef] } : _*).asInstanceOf[Foo]
}
지금 당신은 할 수 있습니다 :
scala> Foo().createFromList(List(4, "foo", 9.81))
res13: Foo = Foo(4,foo,9.81)
또한 특성에 생성 방법을 리팩토링 할 수 있습니다 :
trait Creatable[T <: Creatable[T]] {
val cs = this.getClass.getConstructors
def createFromList(params: List[Any]) =
cs(0).newInstance(params map { _.asInstanceOf[AnyRef] } : _*).asInstanceOf[T]
}
case class Bar(a: Int = 0, b: String = "bar", c: Double = 3.14) extends Creatable[Bar]
그리고 예컨대을 :
scala> val bar = Bar()
bar: Bar = Bar(0,bar,3.14)
scala> bar == bar.createFromList(bar.productIterator.toList)
res11: Boolean = true
해결법
-
==============================
1.
scala> case class Foo(a: Int, b: String, c: Double) defined class Foo scala> val params = Foo(1, "bar", 3.14).productIterator.toList params: List[Any] = List(1, bar, 3.14) scala> Foo.getClass.getMethods.find(x => x.getName == "apply" && x.isBridge).get.invoke(Foo, params map (_.asInstanceOf[AnyRef]): _*).asInstanceOf[Foo] res0: Foo = Foo(1,bar,3.14) scala> Foo(1, "bar", 3.14) == res0 res1: Boolean = true
편집 : 그런데, 구문 지금까지 만 인수가 같은 튜플을 공급하기 위해 주위에 춤을 추되고 :
scala> case class Foo(a: Int, b: String, c: Double) defined class Foo scala> Foo.tupled((1, "bar", 3.14)) res0: Foo = Foo(1,bar,3.14)
-
==============================
2.글쎄, 당신은 확실히 튜플이 작업을 수행 할 수 있습니다 :
글쎄, 당신은 확실히 튜플이 작업을 수행 할 수 있습니다 :
(Foo _).tupled apply (1, bar, 3.14)
S. 물론 HLists와 함께이 일을하는 방법이있을 수 있습니다 : 그러나 목록 [S]을 (A, B, C) A에 대한, B에, C는 <에서 얻을 수있는 실제적인 방법이 없습니다
-
==============================
3.당신은 패턴 매칭 등을 사용할 수 있습니다 :
당신은 패턴 매칭 등을 사용할 수 있습니다 :
params match { case List(x:Int, y:String, d:Double) => Foo(x,y,d) }
from https://stackoverflow.com/questions/4290955/instantiating-a-case-class-from-a-list-of-parameters by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 플레이 2.X : Iteratees와 반응성 파일 업로드 (0) | 2019.11.18 |
---|---|
[SCALA] 어떻게 스파크의 분류에 대한 정확한 데이터 프레임을 만들 수 있습니다 ML (0) | 2019.11.18 |
[SCALA] 주장을 테스트하는 것은 무엇인가 컴파일되지해야 (0) | 2019.11.18 |
[SCALA] 스칼라 2.8 및 스칼라 2.7 사이의 가장 큰 차이점은 무엇입니까? (0) | 2019.11.18 |
[SCALA] 스칼라 : 스칼라 컬렉션에 이동과의 Iterable 특성의 차이점은 무엇입니까? (0) | 2019.11.18 |