2014-09-03 2 views
1

내 응용 프로그램의 사례 클래스에 의해 확장되는 몇 가지 간단한 특성 (아래 예제의 엔터티)이 있습니다. 엔티티 특성 (아래 예제에서 Foo)을 확장하는 사례 클래스를 처리하기위한 인터페이스를 제공하는 EntityMapper 특성을 만들고 싶습니다. 제네릭과 경계를 사용하여이 작업을 상당히 쉽게 처리 할 수있을 것이라고 생각했지만 이미 몇 시간을 보냈으며 제대로 작동하지 못했습니다. 아래 코드는 내가 할 수 있어야한다고 생각하지만 컴파일러 오류로 실패합니다. 오류 : 값의 ID가 난을 해결하기 위해 여러 가지를 시도했습니다스칼라에서 제네릭으로 특성을 구현하는 올바른 방법은 무엇입니까?

package experiment 

trait Entity { 
    val id: Option[Long] 
} 

case class Foo(val id: Option[Long] = None) extends Entity 

trait EntityMapper { 
    def create[E <: Entity](e: E): E 
} 

object FooMapper extends EntityMapper { 
    def create[Foo](e: Foo): Foo = { 
     println(e.id) 
     e 
    } 
} 

object Main extends App { 
    val foo = FooMapper.create(Foo(None)) 
} 

유형 매개 변수 푸 \ 에 println (e.id)의 구성원이 아닌 15 : 오류는 Test.scala

입니다 문제는 없었지만 아무 것도 효과가 없었다. 질문에 "println (e.id)"행을 주석 처리하면 컴파일되지만 유용하지 않으므로 Foo의 속성을 액세스하거나 수정할 수 없습니다.

mapper 특성에 공변 인수를 사용하고 FooMapper 개체 정의에 형식을 제공하려고 시도했지만 동일한 오류가 발생합니다. 그 시도에 대한 코드는 다음과 같습니다 : 나는 또한 간단한 상속과 같은 일을 달성하는 시도했지만 내가 제대로 만, FOOS를 취할 FooMapper의 형식 매개 변수를 제한 할 수 없습니다

trait EntityMapper[+Entity] { 
    def create[E <: Entity](e: E): E 
} 

object FooMapper extends EntityMapper[Foo] { 
... 
} 

, 나는 메소드 서명이 일치 확인해야 특성을 정확하게 사용하여 유형 바인딩 된 제네릭을 사용하여 구현하기 시작했습니다. 그 시도에 대한 코드는 다음과 같습니다 : 반환

trait EntityMapper { 
    def create(e: Entity): Entity 
} 

object FooMapper extends EntityMapper { 
    def create(e: Foo): Foo = { 
     println(e.id) 
     e 
    } 
} 

오류 코드는 다음과 같습니다

Test.scala : 13 : 오류 : 불가능 객체 생성, 방법은 유형의 특성 EntityMapper (전자에서 만든 이후 : 실험. 패키지 실험 수업 푸 패키지 실험의 특성 법인의 서브 클래스이지만, 메소드 매개 변수 유형은 정확히 일치해야합니다)

: 엔티티) experiment.Entity이

을 정의되지 않은 (experiment.Entity이 experiment.Foo과 일치하지 않습니다.
object FooMapper extends EntityMapper { 
    ^

모든 도움을 주시면 감사하겠습니다. 스칼라 버전 2.10.3을 사용하고 있습니다.

답변

3

당신은 특성에 제네릭 형식 제약 조건을 지정하는 방법

  1. 의 몇 오류를 해결할 수 있습니다.

    특성 EntityMapper [E < : 엔티티 { 데프 (: E E) : 생성 E }를

    오브젝트 FooMapper는 (: 푸 E) EntityMapper는 [푸] { 데프 생성 연장 푸 = { println (예 :ID) 전자 } }

  2. 를 사용하여 매개 변수 유형

    특성 EntityMapper { 형 E < :

    객체 FooMapper가 EntityMapper를 {확장 E } : E) : 엔티티 데프 (예를 생성 유형 E = Foo def create (e : Foo) : Foo = { println (e.id) e } }

두 가지 접근 방법에 대해 더 많은 배경 지식을 보려면 Scala: Abstract types vs generics을 확인하십시오.

관련 문제