다음 간단한 프로그램은 기성품 스칼라 2.12 및 형태없는 2.3.2에서 컴파일 할 수 없습니다.
import shapeless.Generic
object InferGeneric {
class WithGeneric[T](implicit ev: Generic[T])
case class Impl() {}
object Impl extends WithGeneric[Impl]
}
컴파일러에서 다음 오류가 발생합니다.
/.../InferGeneric.scala:11: super constructor cannot be passed a self reference unless parameter is declared by-name
object Impl extends WithGeneric[Impl]
흥미로운 점은 object Impl
이름이 바뀌면 문제없이 컴파일 할 수 있다는 것입니다 . Generic 추론에 사용되는 매크로는 컴패니언 객체와 결합 할 때 일부 주기적 해결을 유발할 수있는 것으로 보입니다. 이 상황을 피하는 방법?
귀하의 의견에 감사드립니다!
문제는 매크로 생성 코드이지만 실제로는 매크로에만 국한되지는 않습니다. 명시 적으로 정의 된 인스턴스로 문제를 재현 할 수 있습니다.
import shapeless._
class WithGeneric[T](implicit ev: Generic[T])
case class Impl()
object Impl extends WithGeneric[Impl]()(
new Generic[Impl] {
type Repr = HNil
def to(p: Impl): Repr = HNil
def from(p: Repr): Impl = Impl()
}
)
또는 관련된 매크로가 없는지 확인하려는 경우 :
trait Generic[A] { def mk: A }
class WithGeneric[T](ev: Generic[T])
case class Impl()
object Impl extends WithGeneric[Impl](
new Generic[Impl] { def mk: Impl = Impl() }
)
일반적으로 컴패니언 객체를 Impl.apply
인스턴스화 할 때 생성자 호출 을 호출 하는 코드를 전달할 수 없습니다 Impl
.
.NET으로 무엇을 하려는지에 대해 더 많이 알지 못하고 해결 방법을 제안하기는 어렵습니다 WithGeneric
. 이와 같은 간단한 경우에는 Generic[Impl]
명시 적으로 정의 하고 new Impl
생성자 만 사용할 수 있습니다 (아님 Impl.apply
). 원하는 것이 케이스 클래스를 추상화하는 정의와 함께 컴패니언 객체 편의 메서드를 제공 할 수있는 것이라면 다음과 같이 할 수 있습니다.
import shapeless._
abstract class WithGeneric[T] {
def ev: Generic[T]
}
case class Impl()
object Impl extends WithGeneric[Impl] {
def ev: Generic[Impl] = Generic[Impl]
}
약간의 상용구이지만 사용 사례에 대해 더 많이 알지 못하면 아마도 최선의 선택 일 것입니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다