Что означает оператор ` # ' в 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]
которых я никогда не видел. Поскольку его трудно найти(игнорируется поисковыми системами), кто может сказать мне, что это значит?
4 ответа:
чтобы объяснить это, мы сначала должны объяснить вложенные классы в 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.B
иa2.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> trait R { | type A = Int | } defined trait R scala> val x = null.asInstanceOf[R#A] x: Int = 0
в основном, это способ ссылаться на классы в других классах.
http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html (поиск "фунт")