2012-08-07 2 views
11

형식 매개 변수가 아닌 추상 형식을 사용하고 싶습니다. 내 일반적인 클래스 생성자에서스칼라 클래스 생성자 및 추상 형식

, 나는 일반적인 유형의 매개 변수를 갖고 싶어하지만, 코드는 컴파일되지 않습니다 :

class SomeOtherClass(val s: S){ 
    type S 
} 

스칼라 컴파일러 오류 "를 찾을 수 없습니다 타입 S"입니다

을 내가 추상 형식 대신 형식 매개 변수를 사용하는 경우

, 다음 작품 : 나는이하려는 경우

class SomeClass[T](val t: T){ 
    //... 
} 

합니까 스칼라 힘이 나, 추상적 인 형태가 아닌 유형의 매개 변수를 사용하여 생성자의 일반 매개 변수?

다른 방법이 있습니까?

답변

3

이 경우 일반 형식 매개 변수를 사용해야합니다. 클래스 외부에서 유형을 선언함으로써 해결할 수 있지만 래퍼와 객체를 인스턴스화해야하므로 꽤 빨리 추악 해집니다.

trait FooDef { 
    type T 
    class Foo(val x: T) 
} 
val ifd = new FooDef { type T = Int } 
val ifoo = new ifd.Foo(5) 
val sfd = new FooDef { type T = String } 
val sfoo = new sfd.Foo("hi") 
def intFoos(f: fd.Foo forSome { val fd: FooDef {type T = Int} }) = f.x + 1 
0

컴파일러는 어떤 유형을 사용해야하는지 어떻게 알 수 있습니까? 유형을 직접 지정해야하며, 그렇지 않으면 일반을 사용해야합니다. 그것을 작동시키는 한 가지 방법이 있지만, 그것이 당신을 도울 것이라고는 생각하지 않습니다.

class SomeClass(s: SomeClass#S) { 
    type S 
} 

그러나 SomeClass # S는 정의되지 않았으므로 인스턴스가 없습니다.

+0

재미있게 충분히'새로운 SomeClass (5.asInstanceOf [SomeClass # S]) {type S = Int}'인스턴스를 생성 할 수 있습니다. 안전성이 없다는 것을 유의하십시오. S는 여전히 캐스트에서 정의되지 않습니다. – Kaito

+0

기본적으로 제대로하기 위해서는 다른 두 답변을 살펴 봐야합니까? –

+0

@AntKutschera 예. – Nicolas

0

어쩌면 당신이 뭔가를 원합니까? 이 방법을 사용하면 AbstractFooFactory의 인스턴스를 각각 Foo이고 s가 다른 값을 가질 수 있습니다.

trait AbstractFooFactory { 
    type S 
    def makeFoo(s:S):Foo 
    class Foo(val s:S) {} 
} 

object StringFooFactory extends AbstractFooFactory { 
    override type S = String 
    override def makeFoo(s:String) = new Foo(s) 
} 

val b = StringFooFactory.makeFoo("bar") 
val s:String = b.s 
1

추상 형식을 지정하지 않으면 클래스가 추상이어야합니다. 따라서 매개 변수가 전혀 필요하지 않습니다. 추상적 인 형태와 등가은 다음과 같습니다

사용 현장에서 그런
abstract class SomeOtherClass { 
    type S 
    val s: S 
} 

: 매개 변수없이

val x = new SomeOtherClass { 
    type S = String 
    val s = "abc" 
} 

, 여기에 추상 클래스는 특성에 해당합니다. 제한이 적기 때문에 특성을 사용하는 것이 더 좋습니다 (하나의 기본 클래스 만 확장 할 수 있음).