Scala: How to access a shadowed function variable

2019-08-14 06:37发布

问题:

I would like to make the following work:

def foo(x:Int = 1) = {
  object obj {
    val x = foo.this.x
  }
}

But I don't know how to reference x from within the object. Can this be done without renaming x in one of the two spots?

Renaming the variables may not be easy when, for example, foo is a widely used API function with x as a named variable, while obj extends a 3rd party trait that has x as an abstract member.

回答1:

Why not just introduce a new variable that has the same value as foo's argument x, but is not shadowed?

def foo(x: Int): Unit = {
  val foo_x = x
  object obj {
    val x = 13
    def doStuff: Unit = printf("%d %d\n", x, foo_x);
  }
  obj.doStuff
}

foo(42)


回答2:

No, this is not possible. There is no way to identify the outer block of the function definition.

For your syntax to work foo would have to be an object with a member x. i.e. this works:

class foo{
  val x = 1
  object obj {
    val x = foo.this.x
  }
}

foo also could be a singleton object extending FunctionX, which gives you something very similar to a method. But it is probably easier to just rename one of the values.



回答3:

It is not possible in Scala.

You write the code, so the easiest option will be to rename one of the xs and problem solved.

However, if from some reason you really need it - you can do a trick and create an object that will behave like your method

object Foo {
  self =>

  val x = 1

  def apply() = {
    object obj {
      val x1 = self.x
      val x2 = Foo.x
      // x1 == x2, just 2 different ways of doing this
    }
  }
}

Because the apply method is implemented you can use it as you would use a function Foo()