2012-02-25 59 views
94

我看到這個代碼在這個博客:Type-Level Programming in 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] 
} 

有中,我從來沒有見過的代碼R#X[R#Next]操作#。由於很難搜索它(被搜索引擎忽略),誰能告訴我這是什麼意思?

+0

「英鎊符號」有時被稱爲「八字符」(谷歌搜索帶我到這個頁面)。 – philwalk 2016-01-01 19:44:10

+2

使[octothorpe或octothorp](https://en.wikipedia.org/wiki/Number_sign) – smparkes 2016-03-13 23:09:53

+0

Whatabout其他運算符,如#+和# - (請參閱https://github.com/tpolecat/doobie/blob/series /0.4.x/yax/h2/src/main/scala/doobie/h2/H2Transactor.scala)?有全面的清單嗎? – 2017-02-05 06:53:21

回答

184

來解釋它,我們首先必須在斯卡拉解釋嵌套類。考慮一個簡單的例子:

class A { 
    class B 

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

現在,讓我們嘗試一些與它:

scala> val a1 = new A 
a1: A = [email protected] 

scala> val a2 = new A 
a2: A = [email protected] 

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 = [email protected] 

scala> val a2 = new A 
a2: A = [email protected] 

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. 
+0

極好的例子。我完全接受,它的工作原理是這樣,但很難理解這一點: 斯卡拉> classOf [A#B] res7:類[A#B] = A類$ B 斯卡拉> classOf [AB] res8 :Class [aB] = class A $ B 。這意味着,他們實際上具有相同的類型? – Chiron 2016-01-13 01:28:54

+2

它們的值具有相同的字符串表示 - 它們甚至可能相等。 'Class'是Java類的運行時表示,甚至在Java中也是有限的。例如,'List '和'List '具有相同的運行時類'Class'。如果'Class'不足以表示_Java_類型,則表示_Scala_類型時幾乎沒有用處。同樣,'res7:Class [A#B] = class A $ B',等號左邊的是一個類型,如果是類的Java _runtime_表示的值,則爲equals類型的右邊。 – 2016-01-21 00:16:57

8

它被稱爲類型投影,用於訪問類型成員。

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

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

這是一個無法回答的問題。它基本上顯示與問題相同的代碼,只是略微縮短。例如,什麼是點符號的區別?我在哪裏可以使用這個#在真正的代碼? – notan3xit 2012-02-25 12:33:53

+1

@ notan3xit也許這是一個無法回答你的意思要問。但是你所問的是「......我從未見過,因爲很難搜索它(被搜索引擎忽略),誰能告訴我這是什麼意思?」 – nafg 2014-09-15 02:25:17

相關問題