2

2つの内部クラスの内部複合を持つ外部クラスを想定します。

class Outer(val times: Int) {

  class Inner(val count: Int)
  object Inner {
    def apply(i: Int) = new Inner(i)
  }

  class InnerWrap(val i: Inner)
  object InnerWrap {
    def apply(i: Inner) = new InnerWrap(i)
  }
  def method(i: Inner) = i.count * times
}
object Outer {
  def apply(times: Int) = new Outer(times)
}

class PathDependentExpl {
  val o = new Outer(3)
  val i = o.Inner(2)
  val p = new Outer(5)
  val j = p.Inner(3)
  println(o.method(i))
  println(p.method(j))
}

すべて素敵でダンディ。パスに依存する型を介してOuter、あるメソッドから別のメソッドに内部をフィードすることに対するコンパイラの保護もあります。Outer

しかし、構文は少し面倒です。のようなものを書けるようになりたい

implicit val p = new Outer(5)
val k = Inner(3) // same as p.Inner(3)
val l = InnerWrap(Inner(3))

...暗黙が有効なブロックの外部インスタンスを省略します。そこで、暗黙のパラメータとしてOuterオブジェクトを使用してデリゲートメソッドを急いで追加します。

object Outer {
  def apply(times: Int) = new Outer(times)
  def Inner(c: Int)(implicit o: Outer) = o.Inner(c)
  def InnerWrap(i: o.Inner)(implicit o: Outer) = o.InnerWrap(i)
}

その最後のInnerWrap定義は次のようになります:「違法な依存メソッドタイプ:パラメーターは同じセクションまたは以前のパラメーターの別のパラメーターのタイプに表示されます」これは実際には理にかなっています。私は他の変種を試しdef InnerWrap[O <: Outer#Inner](i: O)(implicit o: Outer) = o.InnerWrap(i)ましたが無駄になりました。

問題は、どうすればよりクリーンな構文を使用できるようになるのかということです。InnerWrapinオブジェクトの宣言をsまたは同等のOuterものを受け入れるようにするにはどうすればよいですか?o.Inner

4

1 に答える 1

2

上記のコメントで述べたように、必要なオブジェクト(またはメソッド)をからインポートすることpができます。これにより、探しているクリーンな構文が得られる場合があります。

scala> val p = new Outer(5)
p: Outer = Outer@4fe2fe5d

scala> import p._
import p._

scala> val k = Inner(3)
k: p.Inner = Outer$Inner@b90ffa7

scala> val l = InnerWrap(Inner(3))
l: p.InnerWrap = Outer$InnerWrap@3bd6bff7
于 2012-09-27T18:14:24.100 に答える