2017-05-04 10 views
3

형식 매개 변수의 하위 유형 인 특성이나 믹스 인을 가진 제네릭 클래스를 만드는 방법, 그리고 유사한 특성을 가지고 있나요 그리고 현재이처럼 사용하고 있습니다 : 이러한 클래스를 만들 수있는 일반적인 방법이있을 것 같은가 나는 다른 종류의 추가 데이터를 첨부하려고

class ExternalType1WithExtraData(superType:ExternalType1, bytes:Array[Byte]) extends ExternalType1(superType.a,superType.b, ...) with ExtraData { 
    def getExtraData() : Array[Byte] = bytes 
} 

class ExternalType2WithExtraData(superType:ExternalType2, bytes:Array[Byte]) extends ExternalType2(superType.z,superType.w, ...) with ExtraData { 
    def getExtraData() : Array[Byte] = bytes 
} 

보인다,하지만 난 아직 찾을 수 없어. 원하는 동작을 추가하는 기능

나는 그 함수 내 강화 된 유형을 통과 할 수 있도록하려면
def sendData(ex : ExternalType1) 

을 감안할 때

-

은 --- 편집을 시작합니다.

val data:ExternalType1 = ??? 
val moredata:ExternalType1 = { new ExternalType1 with ExtraData{...} } 
sendData(moredata) 

--- 나는이 라인을 따라 일을 해봤지만 성공이 없었습니다

최종 편집 :

// Compiler wont let me extend T 
class WithExtraData[T](bytes:Array[Byte]) extends T with ExtraData{ 
    def getExtraData() : Array[Byte] = bytes 
} 

:12: error: class type required but T found class WithExtraDataT extends T with ExtraData{ ^ :12: error: illegal inheritance; supertype T is not a subclass of the superclass Object of the mixin trait ExtraData class WithExtraDataT extends T with ExtraData{

// Seems closer, but doesn't work. 
class WithExtraData[T](t:T, bytes:Array[Byte]) extends ExtraData { 
    this : T => t 
    def getExtraData() : Array[Byte] = bytes 
} 

:13: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses self : T => t ^ defined class WithExtraData

scala> new WithExtraData[String]("hi", new ArrayByte) :13: error: class WithExtraData cannot be instantiated because it does not conform to its self-type WithExtraData[String] with String

이 거기를 이것을 달성하는 방법? 그런 다음

class WithExtraData[T](val value: T, bytes: Array[Byte]) extends ExtraData { 
    def getExtraData(): Array[Byte] = bytes 
} 

object WithExtraData { 
    implicit def getValue[T](x: WithExtraData[T]): T = x.value 
} 

당신은 예를 들어, 할 수 있습니다

+0

난 당신이 중요한 요구 사항을 생략하는 것으로 추측하고있다을 사용하는 것입니다. 이 인스턴스를 외부 라이브러리에 전달하고 다시 가져 와서 'ExtraData'와'getExtraData'에 캐스팅 할 수 있도록'ExternalType1'을 확장하려고합니까? 그렇지 않다면 반드시 하위 클래스 화에서 벗어나야합니다. – drstevens

+0

예, 저는 이와 비슷한 것을하려고 합니다만, 커스텀 시리얼 라이저를 사용하는 Kryo에게하십시오. –

답변

2

나는 ExternalType1을 확장 할 수 있지만, 대신에 암시 적 변환을하지 않는 것입니다 당신이 합리적으로 (적어도 매크로없이) 얻을 수있는 가장 가까운 생각 ExternalType1이 필요할 때마다 WithExtraData[ExternalType1]을 전달하십시오.

+0

제 생각에 "extraData"가 찢어져 실제로 전달되지 않습니다. –

+0

"찢어진"것이 무슨 뜻인지 명확하지 않습니다. 이 솔루션에 대한 더 자세한 내용으로 간단히'WithExtraData [A] = (A, Array [Byte]) '형식을 제안하려고했으나 실제로 해결하려고하는 문제를 해결하지 못한다고 생각합니다. – drstevens

+0

예, T에서 작동하는 함수에 WithExtraData [T]를 전달할 수 있기를 원합니다. –

0

당신이 올바르게 이해할 경우 기본적으로 값으로 표시되는 추가 유형 정보로 유형을 풍부하게하려고합니까? 이 경우 찾고자하는 컨셉은 Dependent Types

입니다. 스칼라는이 개념을 기본적으로 지원하지 않습니다 (예 : Idris). 그러나 가까이 갈 수있는 몇 가지 해결 방법이 있습니다.

한 예는 볼품

import shapeless._ 
import SingletonTypes._ 

val test1: ^((20 + 50) > 1) = true 
test1: Boolean(true) = true 

val test2: ^((20 + 50) > 1) = false 
<console>:11: error: type mismatch; 
found : Boolean(false) 
required: Boolean(true) 
+0

매우 멋지다! - 그러나 나는 여분의 데이터를 특정 인스턴스로 만들고 싶다. –