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.