2017-12-11 1 views
0

다음 코드에서 Array[A]을 반환 할 수 있지만 A을 반환 할 수없는 이유는 무엇입니까? A은 어떻게 반납합니까? 음 ... 대답은 간단합니다, 당신은이 두 가지 예에서 다른 일을하고있는왜 [A] 배열을 반환 할 수 있습니까?하지만 A를 사용하지 않는 이유는 무엇입니까? 어떻게 A를 반환 할 수 있습니까?

scala> import scala.reflect._ 

import scala.reflect._ 

scala> class Covariant[+A]{ 
    | def m[A:ClassTag]:Array[A] = new Array[A](1) 
    | } 
defined class Covariant 

scala> class Covariant[+A]{ 
    | def m[A:ClassTag]:A = new A 
    | } 
<console>:15: error: class type required but A found 
     def m[A:ClassTag]:A = new A 
           ^

답변

0

,

당신은 당신이 당신의 Array 예와 같은 일을하려고하면 같은 오류를 얻을 것이다

scala> import scala.reflect._ 
// import scala.reflect._ 

scala> def m[A:ClassTag]:Array[A] = List(new A).toArray 
// <console>:16: error: class type required but A found 
//  def m[A:ClassTag]:Array[A] = List(new A).toArray 
//           ^

scala> def m[A:ClassTag]:A = new A 
// <console>:16: error: class type required but A found 
//  def m[A:ClassTag]:A = new A 
//        ^

원하는 경우 작동하도록 설정하십시오. 당신은

import scala.reflect._ 

def createNewInstance[A: ClassTag] = { 
    val clazz = classOf[A] 
    val constructors = clazz.getConstructors 
    val defaultConstructor = constructors(0) 
    val instance = defaultConstructor.newInstance() 
    instance.asInstanceOf[A] 
} 

def m[A:ClassTag]: Array[A] = List(createNewInstance[A]).toArray 

def m[A:ClassTag]: A = createNewInstance[A] 
2

문제가없는 기본 생성자와 클래스 (즉, 매개 변수가없는)이 있다는 사실에서 유래는 TypeTag 증거에서 생성자를 얻을 필요가있다. 예를 들어 Int 값을 제공하지 않고

case class IntWrapper(value:Int) 

의 인스턴스를 만들 수 없습니다. 게다가 스칼라에는 타입이 그러한 생성자를 가져야한다는 제한을 표현할 방법이 없다. 따라서 Scala 컴파일러는 new A에 대한 유효한 코드를 생성 할 수 없습니다. 컴파일러는 여기에서 유효한 호출을 생성 할 수 있도록 모든 배열의 모양이 동일하므로 정확히 모두 Int 매개 변수가있는 생성자가 있으므로 배열에서 작동합니다.

은 아마 당신이 할 수있는 가장 좋은 해결 방법은 기본 생성자와 유형에 대한 자신의 typeclass를 만드는 것입니다 다음 새로운 키워드 클래스의 새 인스턴스를 만드는 데 사용됩니다

trait DefaultConstructor[A] { 
    def create(): A 
} 

class Covariant[+A] { 
    def m[A](implicit ctr:DefaultConstructor[A]): A = ctr.create() 
} 
0

. Array는 유효한 클래스이므로 새로운 배열 [A] (1)은 유효한 문입니다. 그러나 A가 유효한 클래스 유형이 아니기 때문에 새로운 A은 유효하지 않습니다 (오류는 이미 나타냅니다). 따라서 컴파일 시간 오류.

def m[A:ClassTag](a:A) = a 
:

나는 당신이해야하지만, 대신 다음은 간단하게 사용할 수있는 A 형의 결과를 반환 할 것을, 확실하지 않다

관련 문제