我试图弄清楚如何创建一个以嵌套对象作为参数的方法。对于嵌套类,我可以执行以下操作:
scala> class Outer {
| class Inner
| def method(i:Outer#Inner) = { "inner class" }
| }
defined class Outer
但是,如果我尝试使用某个对象,我会收到错误:
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" }
该方法的参数类型应该如何实现?另外,我想引用Inner
对象的类型,而不是将参数概括为Any
。
答案 0 :(得分:13)
Inner
是一个对象,因此它不是一个类型,不能用作类型。 Inner
的类型为Inner.type
。在你的例子中,这意味着。不幸的是,Outer的每个实例都有自己的Inner对象,并且不能使用类型Outer#Inner.type
,因为它不稳定。解决方法是使用:this.Inner.type
。
def method(i:this.Inner.type) = { "inner object" }
但这意味着您只能将您调用method
的实例的Inner对象作为参数传递。
答案 1 :(得分:7)
一个简单的例子来说明这里发生了什么(在REPL中):
object A
def foo(a : A) = "Does not compile"
def bar(a : A.type) = "Does compile!"
bar(A) // returns "Does compile!"
正如尼古拉斯所说,内心不是一种类型,所以你不能这样使用它。
试图了解你的动机,我想出了类似的东西:
class Outer(i : Int) {
object Inner {
def getI : Int = i
}
def foo(x : Inner.type) = x.getI
}
这有点无意义,因为我们只是直接引用内部 - 毕竟,只有一个:
class Outer(i : Int) {
object Inner {
def getI : Int = i
}
def foo = Inner.getI
}
我猜你要做的就是从外面的任何一个实例接受一个内心。我们可以检查这种事情的类型:
val o = new Outer(1)
:type o.Inner
o.Inner.type
所以我们可能希望能够做到这样的事情:
class Outer(i : Int) {
object Inner {
def getI : Int = i
}
def foo(x : Outer#Inner.type) = x.getI
}
然而,这无法编译。我不知道为什么。输入别名来救援!
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
我猜这只是解析器的一个限制,它无法读取A#B.type
形式的内容。您可能会提交错误请求。
答案 2 :(得分:1)
每个Scala object
都有自己的类型,并且该类型只有一个值 - 对象本身。因此,Scala object
的类型不比类型Unit
更有用。
例如,假设您有一个object A
并声明一个带有A.type
参数的方法或函数:
def foo(arg: A.type) = {}
由于始终只存在A.type
类型的一个值,因此我们不会在方法foo
内直接引用它而失去一般性。
如果您发现自己想要这样做,那么您真正想要抽象的内容更可能是该对象的特征或基类:
trait Useful { def usefulness: Int }
object A extends Useful { override val usefulness = 42 }
class Foo {
def foo(arg: Useful) = arg.usefulness
}