문제

나는 다음과 같은 작업을 수행 해야하는 스칼라 코드를 작성하려고합니다.

class Test[Type] { 
   def main {
       SomeFunc classOf[Type]
       val testVal: Type = new Type()
    }
 }

그리고 실패합니다. 나는 분명히 Scala Generic 매개 변수에 대해 이해하지 못합니다. 분명히, 오해는 C ++에서 템플릿이 본질적으로 문자열 대체와 같은 기능을 수행하므로 전달되는 클래스에 기본 생성자가있는 한 New Type ()가 작동한다는 것입니다. 그러나 스칼라에서는 유형이 다른 종류의 물체입니다.

도움이 되었습니까?

해결책

지적한 바와 같이, C ++에는 템플릿이 있습니다. 요컨대, C ++는 "테스트가 컴파일하는 모든 유형 T에 대한 테스트가 있습니다"라고 말합니다. 따라서 T에 제약 조건을 쉽게 추가 할 수 있지만 다운쪽에는 암시 적이며 코드를 읽지 않고도 클래스 사용자가 이해하기 어려울 수 있습니다.

Scala의 파라 메트릭 다형성 (일명 제네릭)은 ML, Haskell, Java 및 C#과 훨씬 비슷합니다. Scala에서 "Class Test [T]를 쓸 때 "모든 T에 대해"제약없이 유형 테스트가 있습니다 "라고 말합니다. 그것은 공식적으로 추론하기가 더 간단하지만, 그것은 당신이 제약에 대해 명시해야한다는 것을 의미합니다. 예를 들어, 스칼라에서 "클래스 테스트 [t <: foo]는 t가 foo의 하위 유형이어야한다고 말할 수 있습니다.

C#은 생성자와 관련하여 T에 제약 조건을 추가하는 방법이 있지만 불행히도 Scala는 그렇지 않습니다.

스칼라에서 문제를 해결하는 몇 가지 방법이 있습니다. 하나는 TypeSafe이지만 BT는 더 장점입니다. 다른 하나는 TypeSafe가 아닙니다.

TypeSafe 방식은 모양입니다

class Test[T](implicit val factory : () => T) {
  val testVal = factory
}

그런 다음 시스템에 유용한 유형에 대한 공장을 가질 수 있습니다.

object Factories {
  implicit def listfact[X]() = List[X]()
  implicit def setfact[X]() = Set[X]()
  // etc
}

import Factories._
val t = new Test[Set[String]]

도서관 사용자가 자신의 공장이 필요한 경우 공장 대상과 동등한 자체를 추가 할 수 있습니다. 이 솔루션의 장점 중 하나는 공장이없는 모든 것이 사용될 수 있다는 것입니다.

Not-So-Typesafe Way는 반사와 Scala의 특징을 사용하여 유형 삭제에 관한 Java 제약을 얻는 방법입니다.

 class Test[T](implicit m : Manifest[T]) {
   val testVal = m.erasure.newInstance().asInstanceOf[T]
 }

이 버전을 사용하면 여전히 씁니다

class Foo
val t = new Test[Foo]

그러나 사용 가능한 ARG 생성자가 없으면 정적 유형 오류 대신 런타임 예외가 발생합니다.

scala> new Test[Set[String]] 
java.lang.InstantiationException: scala.collection.immutable.Set
at java.lang.Class.newInstance0(Class.java:340)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top