scala中嵌套对象的类型是什么

Emi*_*l H 8 types scala nested object

我试图弄清楚如何创建一个将嵌套对象作为参数的方法.对于嵌套类,我可以执行以下操作:

scala> class Outer { 
 | class Inner
 | def method(i:Outer#Inner) = { "inner class" }
 | }
defined class Outer
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用对象尝试类似的东西,我会收到错误:

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" }
Run Code Online (Sandbox Code Playgroud)

该方法的参数类型应该如何实现?另外我想引用Inner对象的类型而不是概括说出的论点Any.

Nic*_*las 13

Inner是一个对象,因此它不是一个类型,不能用作类型.的类型InnerInner.type.在你的例子中,这意味着.不幸的是,Outer的每个实例都有自己的Inner对象,并且Outer#Inner.type不能使用类型,因为它不稳定.解决方法是使用:this.Inner.type.

 def method(i:this.Inner.type) = { "inner object" }
Run Code Online (Sandbox Code Playgroud)

但这意味着您只能将您调用的实例的Inner对象作为参数传递method.


Sub*_*oid 7

一个简单的例子来说明这里发生了什么(在REPL中):

object A
def foo(a : A) = "Does not compile"
def bar(a : A.type) = "Does compile!"
bar(A) // returns "Does compile!"
Run Code Online (Sandbox Code Playgroud)

正如尼古拉斯所说,内在不是一种类型,所以你不能这样使用它.

试图了解你的动机,我提出了这样的事情:

class Outer(i : Int) {
  object Inner {
    def getI : Int = i
  }
  def foo(x : Inner.type) = x.getI
}
Run Code Online (Sandbox Code Playgroud)

这有点无意义,因为我们只是直接引用内部 - 毕竟,它只有一个:

class Outer(i : Int) {
  object Inner {
    def getI : Int = i
  }
  def foo = Inner.getI
}
Run Code Online (Sandbox Code Playgroud)

我猜你要做的就是接受来自任何Outer实例的Inner.我们可以检查一下这种事情的类型:

val o = new Outer(1)
:type o.Inner
o.Inner.type
Run Code Online (Sandbox Code Playgroud)

所以我们可能希望能够做到这样的事情:

class Outer(i : Int) {
  object Inner {
    def getI : Int = i
  }
  def foo(x : Outer#Inner.type) = x.getI
}
Run Code Online (Sandbox Code Playgroud)

但是,这无法编译.我不知道为什么.输入别名来救援!

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
Run Code Online (Sandbox Code Playgroud)

我猜这只是解析器的限制,它无法读取表单中的某些内容A#B.type.您可以提交错误请求.