5

このコードを検討してください:

trait A {
  def a : Int
}

def f ( a : Int ) = {
  def a0 = a
  new A {
    def a = a0
  }
}

問題は明らかです。def a0 = aこれは典型的な迷惑なボイラープレート コードであり、より多くのパラメーターが導入されると状況が悪化するだけです。

トレイトのインスタンスの宣言内で外部スコープの変数への直接参照を何らかの方法で取得してa、中間を取り除くことができるかどうか疑問に思っていますa0

関数の入力パラメーターの名前の変更は、特性の変更と同様に許可されていないことに注意してください。

4

3 に答える 3

4

特別な(仮想的な)識別子が必要になるため、直接的な方法はないと思いますthisMethod。ただし、状況によっては、名前のシャドーイングを回避する次の 2 つの方法が考えられます。

(1) 匿名クラスAを実装クラスに置き換えます。

case class AImpl(a: Int) extends A

def f(a : Int): A = AImpl(a)

f(2)抽象トレイトで定義し、具体的な実装を使用します。

trait F {
  def f(a: Int): A
}

object FImpl extends F {
  def f(a0: Int): A = new A { val a = a0 }
}

def test(factory: F): A = factory.f(a = 33)
于 2012-09-01T15:54:30.997 に答える
3

(APIを変更せずに)到達できる最も近いものは次のとおりだと思います:

def f(a: Int) = {
  def ff(a0: Int) = {
    new A {
      def a = a0
    }
  }
  ff(a)
}

Scala では、メソッドは型ではありません。したがって、型システムまたはそのメンバーのいずれかでそれらを参照することはできません。

scala> class X{def f = 0}
defined class X

scala> import reflect.runtime.universe._
import reflect.runtime.universe._

scala> typeOf[X].member(newTermName("f")).isType
res9: Boolean = false
于 2012-09-01T15:59:11.180 に答える
3

これが匿名の解決策です。

package eyeshadow

trait A {
  def a: Int
}

class B {
  def f(a: Int) = {
    val fa: A = new {
      //private val b = a
      private[this] val b = a // crashes, sorry scalac. edit: ok in 2.11
    } with A {
      def a = b
    }
    fa.a
    /*
     * This seems far-fetched, but compare the initial objections in
     * https://issues.scala-lang.org/browse/SI-3836
     * All I want is to alias a symbol, right?
     * Maybe the override means "do not shadow."
    val fa: A = new A {
      //import fa.{ a => b }
      import this.{ a => b }
      override def b = a
    }
     */
  }
}

object Test {
  def main(args: Array[String]) {
    val b = new B
    println(b f 7)
  }
}
于 2012-09-02T20:51:13.527 に答える