`#`运算符在Scala中意味着什么?

Fre*_*ind 125 type-systems scala

我在这个博客中看到了这个代码:Scala中的类型级编程:

// define the abstract types and bounds
trait Recurse {
  type Next <: Recurse
  // this is the recursive function definition
  type X[R <: Recurse] <: Int
}
// implementation
trait RecurseA extends Recurse {
  type Next = RecurseA
  // this is the implementation
  type X[R <: Recurse] = R#X[R#Next]
}
object Recurse {
  // infinite loop
  type C = RecurseA#X[RecurseA]
}
Run Code Online (Sandbox Code Playgroud)

#代码中有一个R#X[R#Next]我从未见过的运算符.由于难以搜索(被搜索引擎忽略),谁能告诉我它是什么意思?

Dan*_*ral 230

为了解释它,我们首先要解释Scala中的嵌套类.考虑这个简单的例子:

class A {
  class B

  def f(b: B) = println("Got my B!")
}
Run Code Online (Sandbox Code Playgroud)

现在让我们尝试一下:

scala> val a1 = new A
a1: A = A@2fa8ecf4

scala> val a2 = new A
a2: A = A@4bed4c8

scala> a2.f(new a1.B)
<console>:11: error: type mismatch;
 found   : a1.B
 required: a2.B
              a2.f(new a1.B)
                   ^
Run Code Online (Sandbox Code Playgroud)

当你在Scala中的另一个类中声明一个类时,你会说该类的每个实例都有这样一个子类.换句话说,没有A.B类,但有a1.Ba2.B类,它们是不同的类,因为错误消息告诉我们上面.

如果您不理解,请查找路径依赖类型.

现在,#您可以引用此类嵌套类,而不必将其限制为特定实例.换句话说,没有A.B,但有A#B,这意味着任何实例的B嵌套类.A

我们可以通过更改上面的代码来看到这一点:

class A {
  class B

  def f(b: B) = println("Got my B!")
  def g(b: A#B) = println("Got a B.")
}
Run Code Online (Sandbox Code Playgroud)

尝试一下:

scala> val a1 = new A
a1: A = A@1497b7b1

scala> val a2 = new A
a2: A = A@2607c28c

scala> a2.f(new a1.B)
<console>:11: error: type mismatch;
 found   : a1.B
 required: a2.B
              a2.f(new a1.B)
                   ^

scala> a2.g(new a1.B)
Got a B.
Run Code Online (Sandbox Code Playgroud)

  • 它们的值具有相同的字符串表示 - 它们甚至可能相等.`Class`是Java类的运行时表示,即使在Java中它也是有限的.例如,`List <String>`和`List <Integer>`具有相同的运行时`Class`.如果`Class`不够丰富以表示_Java_类型,那么在表示_Scala_类型时几乎没用.同样,`res7:类[A#B] =类A $ B`,等号的左边是一个类型,如果是一个类的Java _runtime_表示的值,则为equals类型的右边. (2认同)

mis*_*tor 11

它被称为类型投影,用于访问类型成员.

scala> trait R {
     |   type A = Int
     | }
defined trait R

scala> val x = null.asInstanceOf[R#A]
x: Int = 0
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非答案.它基本上显示了与问题相同的代码,只是略微缩短了.例如,点符号的区别是什么?我会在实际代码中使用这个#? (5认同)
  • @ notan3xit也许这不是你想要问的答案.但你问的是"......我从未见过.因为它很难搜索(被搜索引擎忽略),谁能告诉我它是什么意思?" (2认同)

mov*_*y00 7

基本上,它是一种引用其他类中的类的方法.

http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html(搜索"磅")