내가 대략 다음과 같은 지금,하는 클래스 계층 구조를 가지고 [아래 수정 됨] :
sealed trait Foo {
def method: Any
}
case class Bar extends Foo {
def method: Array[String] = // implementation
}
case class Baz extends Foo {
def method: Map[String, Array[String]] = // implementation
}
나는 추상적 인 방법을 Any
의 반환 유형을주고있다을 왜냐하면 사례 클래스의 반환 유형은 반드시 다르지만 비슷한 목적을 공유하기 때문입니다. 이런 이유로, 나는 공통적 인 행동을 모델로 삼으면서 특성을 유지하고 싶습니다. 그리고 이것이 이것이 컴파일되도록 만드는 유일한 방법입니다. 이것은 스칼라 타입 시스템의 정신에 위배된다는 것을 알기 때문에 아래 첫 번째 질문을합니다.
그런 다음, 다른 클래스는 생성자 매개 변수로 Foo
의 서브 클래스는 기대하고, 나는 다음이 아닌 다른이, 표시하기 위해 방법을 모른다 : 기대
class Qux(foo: Foo) {
val m = foo.method
...
...
}
Qux
있다 방법을 발 m
는 Foo
의 특정 서브 클래스 (Bar
또는 Baz
)에 해당하는 유형이어야합니다,하지만 난
... type mismatch;
[error] found : Any
[error] required: Array[String]
같은 컴파일 오류를 얻고있다
- 나는 이것이 내 특정 문제를 표현하는 올바른 방법이라고 생각하기에 충분 스칼라 익숙하지만, 그것에 대해 이동하는 방법을 알고 충분히 익숙하지 :
그래서 나는 몇 가지 질문이 있습니다. 내가하려는 일을하는 적절한 방법은 무엇입니까?
또한
- ,
m
이Foo
에서 추상적 인 방법을Bar
또는Baz
에서 특정method
에 의해 반환되는 값으로 처리, 그리고해야Qux
클래스 말할 수있는 방법은 무엇입니까?
편집 : (추상 형식의 멤버를 사용) @marios에 의해 제안 된 접근 방식을 복용은 올바른 방향으로 단계가 될 것 같다,하지만 형식이 일치 이제 나타납니다. 클래스 Qux
내에서, 지금
class Qux[X <: Foo](sc: SparkContext, val foo: X) {
val m: foo.A = foo.method
def process(rows: DataFrame) = foo match {
case Bar(sc, _) => BarProcessor(sc, m).doStuff(rows)
case Baz(sc, _) => BazProcessor(sc, m.keys).doStuff(rows, m.values)
}
}
예를 들어
BarProcessor
가 인스턴스화되고
, Array[String]
및 BazProcessor
이 물건을 할 Baz
의 method
에 의해 반환 된 값에서 키 - 값 쌍을 필요로한다. 나는 foo
이 (value keys is not a member of Qux.this.foo.A
의 라인을 따라, 등) Baz
때 m
에 Map
- 특정 메서드를 호출 할 때 그러나, 지금
[error] Qux.scala:4: type mismatch;
[error] found : Qux.this.foo.A
[error] required: Array[String]
[error] case Bar(sc, _) => BarProcessor(sc, m).doStuff(rows)
[error] ^
비슷한 오류와 같은 오류를 얻고있다가 표시됩니다. m
은 이 아니며 실제로이고 Array[String]
인 것으로 알고 있습니다. 유형은 A
입니다. 그러나 스칼라에게 이것을 원하는 타입으로 "번역"한다고 말하는 방법이 있을까요?
는 "경계"에 의해 제한 될 수있다 "형식 매개 변수를"(반환 유형을보고). –