2012-09-01 2 views
5

Bitte diesem Code betrachten:Erster Bezug auf einen Parameter der äußeren Funktion einen widersprüchlichen Namen mit

trait A { 
    def a : Int 
} 

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

Das Problem ist ganz offensichtlich: def a0 = a ist ein typischer ärgerlich Standardcode und die Situation nur verschlimmert, wenn mehrere Parameter erhalten eingeführt.

Ich frage mich, ob es möglich ist, irgendwie eine direkte Referenz auf die a Variable des äußeren Bereichs innerhalb der Deklaration der Instanz des Merkmals zu bekommen und damit das Zwischenprodukt a0 loszuwerden.

Bitte beachten Sie, dass das Ändern des Namens des Eingabeparameters der Funktion nicht zulässig ist, da dies das Merkmal ändert.

Antwort

4

Ich glaube nicht, gibt es direkte Weg, dies zu tun, weil es einige spezielle (hypothetischen) -Kennung thisMethod erfordern würde. Doch je nach Kontext, die folgenden zwei Möglichkeiten, den Namen Abschattung zu vermeiden, könnten möglich sein:

(1) ersetzen anonyme Klasse A mit implementierende Klasse:

case class AImpl(a: Int) extends A 

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

(2) definieren f in einem abstrakten trait und eine konkrete Umsetzung für sie verwenden:

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) 
3

ich denke, die nächstgelegene Sie bekommen können (ohne Ihre API zu ändern) ist:

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

In Scala sind Methoden keine Typen. Daher ist es nicht möglich, sie mit dem Typsystem oder einem ihrer Mitglieder zu referenzieren.

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 
3

Hier ist eine anonyme Lösung.

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) 
    } 
} 
+0

Vielen Dank, anonymer Up-Voter. Ich habe niemals das Vertrauen in dich verloren. Aber der wahre Dank geht an die Leute, die verrückte Fragen stellen, und an die anderen Leute, die ihnen so schnell antworten, dass, wenn ich an etwas denke, es wirklich verrückt sein muss. –

Verwandte Themen