shapeless.Generic을 사용할 때 '매개 변수가 이름으로 선언되지 않으면 수퍼 생성자가 자체 참조를 전달할 수 없습니다'라는 오류를 피하는 방법은 무엇입니까?

Tribbloid

다음 간단한 프로그램은 기성품 스칼라 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] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관