Scala'da "#" operatörü ne anlama geliyor?


131

Bu kodu bu blogda görüyorum: Scala'da Tür Düzeyinde Programlama :

// 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]
}

Bir operatör vardır #kodda R#X[R#Next]ben görmedim. Arama yapmak zor olduğu için (arama motorları tarafından görmezden geliniyor), bunun ne anlama geldiğini kim söyleyebilir?


1
"pound işareti" bazen "octathrop" olarak adlandırılır (bu google araması beni bu sayfaya getirdi).
philwalk


# + Ve # gibi diğer operatörler hakkında - (bkz. Github.com/tpolecat/doobie/blob/series/0.4.x/yax/h2/src/main/… )? Kapsamlı bir liste var mı?
Markus Barthlen

Yanıtlar:


240

Bunu açıklamak için önce Scala'da yuvalanmış sınıfları açıklamalıyız. Şu basit örneği düşünün:

class A {
  class B

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

Şimdi onunla bir şeyler deneyelim:

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'da başka bir sınıfın içinde bir sınıf bildirdiğinizde , o sınıfın her örneğinin böyle bir alt sınıfa sahip olduğunu söylüyorsunuz . Başka bir deyişle, A.Bsınıf yoktur , ancak yukarıda hata mesajının bize söylediği gibi, a1.Bve a2.Bsınıflar vardır ve bunlar farklı sınıflardır.

Bunu anlamadıysanız, yola bağlı türleri arayın.

Şimdi, #belirli bir örnekle sınırlandırmadan bu tür iç içe geçmiş sınıflara başvurmanızı mümkün kılar. Başka bir deyişle, yok A.B, ama var A#B, bu da herhangi bir örneğinin Biç içe geçmiş bir sınıfı anlamına geliyor .A

Bunu, yukarıdaki kodu değiştirerek görebiliriz:

class A {
  class B

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

Ve denemek:

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.

Mükemmel örnek. Bu şekilde çalıştığını tamamen kabul ediyorum ama bunu anlamak zor: scala> classOf [A # B] res7: Class [A # B] = class A $ B scala> classOf [aB] res8: Class [aB] = class A B $. bu, aslında aynı türe sahip oldukları anlamına mı geliyor?
Chiron

2
Değerleri aynı dizgi temsiline sahiptir ve hatta eşit olabilirler. ClassJava sınıflarının çalışma zamanı temsilidir ve Java'da bile sınırlıdır. Örneğin List<String>ve List<Integer>aynı çalışma süresine sahip Class. Eğer Classtemsil etmek zengin yetmez Java türlerini temsil eden zaman, neredeyse yararsız Scala türleri. Yine, res7: Class[A#B] = class A$Beşittir işaretinin solunda , bir sınıfın Java çalışma zamanı temsili olan bir değer ise eşittir türünün sağındaki bir türdür .
Daniel C. Sobral

13

Tür projeksiyonu olarak bilinir ve tür üyelerine erişmek için kullanılır.

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

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

6
Bu bir cevap değil. Temelde soru ile aynı kodu gösterir, sadece biraz kısaltılmıştır. Örneğin, nokta gösterimi arasındaki fark nedir? Bu # numarayı gerçek kodda nerede kullanırım?
notan3xit

2
@ notan3xit belki sormak istediğin şeyin yanıtı değil. Ama sorduğun şey "... hiç görmediğim. Aramak zor olduğundan (arama motorları tarafından görmezden geliniyor), kim bana bunun ne anlama geldiğini söyleyebilir?"
nafg


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.