9

次のようなクラスがあります。

class X[A <: Throwable, B, C](b: B, c: C)

A、B、C は推論できるので、次のようにインスタンス化できます。

val x = new X(3, 4)

これにより、 X[Nothing, Int, Int] が得られます-多くの場合、私が望むものです。

しかし、A を Nothing 以外のものに指定したい場合があります (AssertionError など)。これは、B と C も指定せずに可能ですか。次の行に沿った構文を想像しました。

val x = new X[AssertionError](3, 4)
val x = new X[AssertionError, _, _](3, 4)
val x = new X[AssertionError,,](3, 4)

しかし、明らかにこれは機能しません。

これにはいくつかの構文がありますか、または同じ結果を達成できる方法はありますか?

4

5 に答える 5

5

私の主な関心事は、使用時にこれを簡単にすることでした(例外タイプはしばしば異なるため、使用ごとに新しいタイプを定義する必要はありません)。コンパニオンオブジェクトを使用して、中間ファクトリをファクトリできることがわかりました。

class X[A <: Throwable, B, C](b: B, c: C) {
}

trait XFactory[A <: Throwable] {
  def apply[B, C](b: B, c: C): X[A, B, C]
}

object X {
  def apply[A <: Throwable: Manifest](): XFactory[A] = {
    new XFactory[A] {
      override def apply[B, C](b: B, c: C): X[A, B, C] = {
        new X(b, c)
      }
    }
  }
}

val x = X[AssertionError].apply(3,3)

私が見ることができる唯一の欠点は、あなたが「適用」を綴らなければならないということです。

于 2013-03-01T12:29:35.540 に答える
4

これが私の解決策です:

scala> class X[A <: Throwable, B, C](b: B, c: C)
defined class X

scala> class Builder[A <: Throwable] {
     |   def apply[B, C](b: B, c: C) = new X[A,B,C](b,c)
     | }
defined class Builder

scala> def X[A <: Throwable]: Builder[A] = new Builder[A]
X: [A <: Throwable]=> Builder[A]

scala> val x = X[AssertionError](3, 4)
x: X[AssertionError,Int,Int] = X@2fc709
于 2013-03-01T14:20:19.370 に答える
3

簡潔でハードコアな構文が怖くない場合は、これにラムダ型を使用することをお勧めします。

Welcome to Scala version 2.10.0-20121205-235900-18481cef9b (OpenJDK 64-Bit Server VM, Java 1.7.0_15).
Type in expressions to have them evaluated.
Type :help for more information.

scala> case class X[A <: Throwable, B, C](b: B, c: C)
defined class X

scala> type P[A,B] = ({type l[a,b] = X[AssertionError, a, b]})#l[A,B]
defined type alias P

scala> val x = new P(1,2)
x: X[AssertionError,Int,Int] = X(1,2)

それでも、Frank S. Thomas が提案したように、型エイリアスを定義することは、ここに行くための方法です。

于 2013-03-01T12:18:53.973 に答える
3

最初の型パラメーターが に固定されている型エイリアスを定義できますAssertionError

scala> class X[A <: Throwable, B, C](b: B, c: C)
defined class X

scala> type XAssertionError[B, C] = X[AssertionError, B, C]
defined type alias XAssertionError

scala> val x = new XAssertionError(3,4)
x: X[java.lang.AssertionError,Int,Int] = X@22fe135d
于 2013-03-01T12:20:20.927 に答える
1

デフォルトの引数でコンストラクターを定義するだけです。

scala> class X[A <: Throwable, B, C](b: B, c: C, clz:Class[_ <: A] = classOf[Nothing])
defined class X

scala> new X(1,2)
res0: X[Nothing,Int,Int] = X@16de4e1

scala> new X(1,2, classOf[AssertionError])
res1: X[AssertionError,Int,Int] = X@1e41869
于 2013-03-01T15:53:44.640 に答える