2016-11-21 5 views
2

여기 내 문제입니다. FloatCaller을 추가하려면 parseEntity을 다시 작성해야하지만 구현은 동일합니다.스칼라 implicits 및 재정 문제

Caller에 parseEntity의 implentation을 작성하여 하위 특성에 동일한 코드를 반복해서 쓸 필요가 없도록하려면 어떻게해야합니까?

면책 조항 : 이것은 실제 문제를 단순화 한 것으로 SprayJsonSupport부터 akka.http.scaladsl.marshallers.sprayjson까지입니다.

답변

4

변환 기능이 주어진 Caller의 인스턴스를 빌드 할 수있는 팩토리 메소드를 사용하는 것이 더 나을 것입니다. IntCallerDoubleCaller 사이의 유일한 차이점은 toInttoDouble입니다 (물론 유형도 포함).


상속을 계속 사용하려면

trait Caller { 
    type EntityType 
    def parseEntity(entity: String): EntityType 
} 

object Caller { 
    def apply[A](f: String => A): Caller = new Caller { 
     type EntityType = A 
     def parseEntity(entity: String): EntityType = f(entity) 
    } 
} 

scala> val IntCaller = Caller(_.toInt) 
scala> IntCaller.parseEntity("123") 
res1: IntCaller.EntityType = 123 

scala> val DoubleCaller = Caller(_.toDouble) 
scala> DoubleCaller.parseEntity("1.23") 
res2: DoubleCaller.EntityType = 1.23 

parseEntity로 변환을 구현하는 서브 클래스 나 특성을 강제로 계속합니다. 그러나 암시 적 변환을 사용하는 것은 실제로 필요하지 않습니다. 반복되는 코드가있는 유일한 이유는 암시 적 변환을 수행하면 parseEntity이 실제로 구현되지 않았지만 (다른 암시 적을 해결해야하기 때문에) 각 구현에 대해 동일하게 보이기 때문입니다.

trait Caller { 
    type EntityType 
    def parseEntity(entity: String): EntityType 
} 

trait IntCaller { 
    type EntityType = Int 
    def parseEntity(entity: String): EntityType = entity.toInt 
}