11

型パラメーターではなく抽象型を使用したい。

私のジェネリック クラス コンストラクターでは、ジェネリック型のパラメーターが必要ですが、コードがコンパイルされません。

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

scala コンパイラ エラーは「見つかりません: タイプ S」です。

抽象型の代わりに型パラメーターを使用すると、次のように機能します。

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

コンストラクターにジェネリックパラメーターが必要な場合、scala は抽象型ではなく型パラメーターを使用するように強制しますか?

これを行う別の方法はありますか?

4

5 に答える 5

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
于 2012-08-07T12:03:37.137 に答える
1

抽象型が指定されていない場合、クラスは抽象である必要があります。したがって、パラメーターはまったく必要ありません。抽象型と同等のものは次のようになります。

abstract class SomeOtherClass {
  type S
  val s: S 
}

次に、使用サイトで:

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

パラメータがなければ、ここでの抽象クラスはトレイトと同等です。制限が少ないため、トレイトを使用する方が適切です (1 つの基本クラスしか拡張できません)。

于 2012-08-07T17:14:34.760 に答える
0

コンパイラは、そこで使用するタイプをどのように知る必要がありますか?タイプを直接指定する必要がありますが、これはあまり意味がありません。または、ジェネリックを使用します。それを機能させる方法は1つありますが、それが役に立たないと思います。

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

ただし、SomeClass#Sが定義されていないため、そのインスタンスはありません。

于 2012-08-07T11:59:45.347 に答える
0

多分あなたはこのようなものが欲しいですか?このようにして、異なる値の s を持つAbstractFooFactory各生成s の複数のインスタンスを持つことができます。Foo

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
于 2012-08-07T12:02:56.730 に答える
0

ここでの他の回答はどれも、以下のように、この状況で使用される非常に一般的なパターンの両方の部分を捉えていません。trait(Luigiの回答のように) aまたは anabstract classのいずれかを使用するSomeOtherClassと、コンパニオンオブジェクトのapplyメソッドはインスタンスを簡単に作成するためのファクトリになります。val を取り、s型パラメーターSを推論できるため、どこで使用してもオブジェクトのインスタンス化が簡単になります。

trait SomeOtherClass {
  type S
  val something: S 
}

object SomeOtherClass {
  def apply[S0](s:S0) = new SomeOtherClass {
    type S = S0
    val something = s
  }
}

// usage
SomeOtherClass(12)
于 2018-06-27T01:14:52.223 に答える