Scala中的#操作符是什么意思?


131

我在以下博客中看到此代码:Scala中的Type-Level Programming

// 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]。由于很难搜索(搜索引擎忽略了它),谁能告诉我这是什么意思?


1
“英镑符号”有时也称为“八进制”(由Google搜索将我带到此页面)。
philwalk


像#+和#-这样的其他运算符呢(请参阅github.com/tpolecat/doobie/blob/series/0.4.x/yax/h2/src/main/…)?有完整的清单吗?
Markus Barthlen'2

Answers:


240

为了说明这一点,我们首先必须解释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,这意味着B任何实例的嵌套类A

通过更改上面的代码,我们可以在工作中看到这一点:

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。这意味着它们实际上具有相同的类型?
凯龙

2
它们的值具有相同的字符串表示形式-甚至可能相等。Class是Java类的运行时表示形式,即使在Java中也受到限制。例如,List<String>并且List<Integer>具有相同的runtime Class。如果Class不够丰富,无法表示Java类型,则在表示Scala类型时几乎没有用。同样,res7: Class[A#B] = class A$B等号的左边是类型,如果值是类的Java 运行时表示形式,则等号类型右边。
Daniel C. Sobral

13

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

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

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

6
这是无答案的。它基本上显示与问题相同的代码,只是略有缩短。什么是例如点标记法的区别?我将在实际代码中在哪里使用此#代码?
notan3xit 2012年

2
@ notan3xit可能不是您要问的问题的答案。但是您问的是“ ...我从未见过。由于很难搜索(搜索引擎忽略),谁能告诉我这是什么意思?”
2014年


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.