I am trying to figure out how to create a method that takes a nested object as an argument. For a nested class I can do the following:
scala> class Outer {
| class Inner
| def method(i:Outer#Inner) = { "inner class" }
| }
defined class Outer
However, if I try something like that with an object instead i get an error:
scala> class Outer {
| object Inner
| def method(i:Outer#Inner) = { "inner object" }
| }
<console>:11: error: type Inner is not a member of Outer
def method(i:Outer#Inner) = { "inner object" }
What should the type of the argument to the method be to accomplish this? Also I want to refer to the type of Inner
object not generalize the argument to say Any
.
Inner
is an object, thus it is not a type, and can't be use as a type. the type of Inner
is Inner.type
. It means, in your example. Unfortunately, each instance of Outer will have it's own Inner object and type Outer#Inner.type
can not be used, since it is not stable. A workaround is to use: this.Inner.type
.
def method(i:this.Inner.type) = { "inner object" }
But it means that you can only pass as a parameter the Inner object of the instance on which you call method
.
A simple example to illustrate what's going on here (in the REPL):
object A
def foo(a : A) = "Does not compile"
def bar(a : A.type) = "Does compile!"
bar(A) // returns "Does compile!"
As Nicholas says, Inner is not a type, so you can't use it as such.
Trying to understand your motivation, I came up with something like this:
class Outer(i : Int) {
object Inner {
def getI : Int = i
}
def foo(x : Inner.type) = x.getI
}
This is a bit pointless, since we would just directly reference Inner - after all, there's only one of it:
class Outer(i : Int) {
object Inner {
def getI : Int = i
}
def foo = Inner.getI
}
I'm guessing that what you want to do is accept an Inner from any instance of Outer. We can check the type of such a thing:
val o = new Outer(1)
:type o.Inner
o.Inner.type
So we might expect to be able to do something like this:
class Outer(i : Int) {
object Inner {
def getI : Int = i
}
def foo(x : Outer#Inner.type) = x.getI
}
This, however, fails to compile. I'm not sure why. Type aliases to the rescue!
class Outer(i : Int) {
type Inner = Inner.type
object Inner {
def getI : Int = i
}
def foo(x : Outer#Inner) = x.getI
}
val a = new Outer(1)
val b = new Outer(2)
a.foo(b.Inner) //returns 2
I'm guessing it's just a restriction of the parser that it's unable to read something of the form A#B.type
. You could potentially submit a bug request.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With