【问题标题】:What does the `#` operator mean in Scala?Scala 中的“#”运算符是什么意思?
【发布时间】:2012-03-15 15:02:08
【问题描述】:

我在这个博客中看到了这段代码:Type-Level Programming in 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]
}

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

【问题讨论】:

标签: scala type-systems


【解决方案1】:

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

class A {
  class B

  def f(b: B) = println("Got my B!")
}

现在让我们尝试一下:

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)
                   ^

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

如果您不理解,请查找路径相关类型。

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

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

class A {
  class B

  def f(b: B) = println("Got my B!")
  def g(b: A#B) = println("Got a B.")
}

并尝试一下:

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.

【讨论】:

  • 很好的例子。我完全接受它以这种方式工作,但很难理解这一点: scala> classOf[A#B] res7: Class[A#B] = class A$B scala> classOf[aB] res8: Class[aB] = class A $B 。这意味着它们实际上具有相同的类型?
  • 它们的值具有相同的字符串表示形式——甚至可能相等。 Class 是 Java 类的运行时表示,即使在 Java 中也是有限的。例如,List&lt;String&gt;List&lt;Integer&gt; 具有相同的运行时 Class。如果Class 不够丰富来表示Java 类型,那么它在表示Scala 类型时几乎没用。同样,res7: Class[A#B] = class A$B,等号左侧是类型,如果值是类的 Java runtime 表示形式,则等号右侧。
【解决方案2】:

称为类型投影,用于访问类型成员。

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

scala> val x = null.asInstanceOf[R#A]
x: Int = 0

【讨论】:

  • 这是一个非答案。它基本上显示了与问题相同的代码,只是稍微缩短了一点。例如,点符号的区别是什么?在实际代码中我会在哪里使用这个#?
  • @notan3xit 也许这不是您要问的问题的答案。但是你问的是“......我从来没有见过。因为它很难搜索(被搜索引擎忽略),谁能告诉我这是什么意思?”
【解决方案3】:

基本上,这是在其他类中引用类的一种方式。

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

【讨论】:

    【解决方案4】:

    这是用于搜索“符号运算符”(实际上是方法)的资源,但我还没有弄清楚如何转义“#”以在 scalex 中搜索)

    http://www.artima.com/pins1ed/book-index.html#indexanchor

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-07
      • 2012-07-15
      • 2015-09-18
      • 2017-03-29
      • 2011-03-16
      • 2011-07-09
      • 2016-07-23
      相关资源
      最近更新 更多