Widzę ten kod na tym blogu: Programowanie na poziomie typu w Scali :
// 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]
}
W #
kodzie jest operator, R#X[R#Next]
którego nigdy nie widziałem. Ponieważ wyszukiwanie jest trudne (ignorowane przez wyszukiwarki), kto może mi powiedzieć, co to oznacza?
scala
type-systems
Freewind
źródło
źródło
Odpowiedzi:
Aby to wyjaśnić, najpierw musimy wyjaśnić zagnieżdżone klasy w Scali. Rozważmy ten prosty przykład:
class A { class B def f(b: B) = println("Got my B!") }
Teraz spróbujmy czegoś z tym:
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) ^
Kiedy deklarujesz klasę wewnątrz innej klasy w Scali, mówisz, że każda instancja tej klasy ma taką podklasę. Innymi słowy, nie ma
A.B
klasy, ale istniejąa1.B
ia2.B
klasy i są to różne klasy, o czym informuje nas powyżej komunikat o błędzie.Jeśli tego nie rozumiesz, poszukaj typów zależnych od ścieżki.
Teraz
#
umożliwia odwoływanie się do takich zagnieżdżonych klas bez ograniczania ich do konkretnej instancji. Innymi słowy, nie maA.B
, ale istniejeA#B
, co oznaczaB
zagnieżdżoną klasę dowolnej instancjiA
.Możemy to zobaczyć w działaniu, zmieniając powyższy kod:
class A { class B def f(b: B) = println("Got my B!") def g(b: A#B) = println("Got a B.") }
I wypróbować:
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.
źródło
Class
jest reprezentacją klas Java w czasie wykonywania i jest ograniczona nawet w Javie. Na przykładList<String>
iList<Integer>
mają to samo środowisko wykonawczeClass
. JeśliClass
nie jest wystarczająco bogaty, aby reprezentować typy Java , jest prawie bezużyteczny podczas reprezentowania typów Scala . Ponownie, pores7: Class[A#B] = class A$B
lewej stronie znaku równości znajduje się typ, a na prawo od typu równości, jeśli wartość jest reprezentacją klasy w środowisku wykonawczym Java .Jest znany jako projekcja typu i służy do uzyskiwania dostępu do elementów członkowskich typu.
scala> trait R { | type A = Int | } defined trait R scala> val x = null.asInstanceOf[R#A] x: Int = 0
źródło
Zasadniczo jest to sposób odwoływania się do zajęć z innych klas.
http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html (wyszukaj „funt”)
źródło
Oto zasób do wyszukiwania „operatorów symbolicznych” (które są tak naprawdę metodami), ale nie wymyśliłem, jak uciec od znaku „#” do wyszukiwania w scalex)
http://www.artima.com/pins1ed/book-index.html#indexanchor
źródło