스칼라에서`#`연산자는 무엇을 의미합니까?


131

이 블로그 에서이 코드를 볼 수 있습니다 : Scala의 Type-Level Programming :

// 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]있습니다. 검색 엔진이 무시하기 때문에 검색하기가 어렵 기 때문에 누가 무슨 뜻인지 알 수 있습니까?


1
"파운드 사인"은 때때로 "옥타 프롭"(Google 검색으로이 페이지로 이동)이라고도합니다.
philwalk 2016 년


# + 및 #-와 같은 다른 연산자는 무엇입니까 ( github.com/tpolecat/doobie/blob/series/0.4.x/yax/h2/src/main/… 참조 )? 포괄적 인 목록이 있습니까?
Markus Barthlen

답변:


240

이를 설명하기 위해 먼저 스칼라에서 중첩 클래스를 설명해야합니다. 이 간단한 예를 고려하십시오.

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)
                   ^

스칼라의 다른 클래스 내부에서 클래스를 선언하면 해당 클래스의 각 인스턴스 에 이러한 하위 클래스가 있다고 말하는 것입니다 . 즉, A.B클래스 가 없지만 클래스가 a1.B있으며 a2.B클래스가 다르며 오류 메시지가 위에서 알려 주듯이 서로 다른 클래스입니다.

이해하지 못한 경우 경로 종속 유형을 찾으십시오.

이제 #이러한 중첩 클래스를 특정 인스턴스로 제한하지 않고 참조 할 수 있습니다. 다시 말해,는 없지만 A.B, 는 인스턴스의 중첩 클래스 A#B를 의미합니다 .BA

위의 코드를 변경하여 작동 상태를 확인할 수 있습니다.

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> classOf [A # B] res7 : Class [A # B] = class A $ B scala> classOf [aB] res8 : Class [aB] = class A $ B 즉, 실제로 같은 유형을 가지고 있습니까?
Chiron

2
이들의 값은 동일한 문자열 표현을 가지며 동일 할 수도 있습니다. ClassJava 클래스의 런타임 표현이며 Java에서도 제한됩니다. 예를 들어, List<String>List<Integer>같은 런타임이 Class. Java 유형 Class을 표현할만큼 풍부하지 않은 경우 Scala 유형을 나타낼 때 거의 쓸모가 없습니다 . 다시, 등호 왼쪽은 유형 이며, 클래스 의 Java 런타임 표현 인 값인 경우 등호 유형의 오른쪽은 유형 입니다. res7: Class[A#B] = class A$B
Daniel C. Sobral

13

형식 프로젝션이라고하며 형식 멤버에 액세스하는 데 사용됩니다.

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

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

6
이것은 대답이 아닙니다. 기본적으로 질문과 동일한 코드가 약간 단축되었습니다. 예를 들어 포인트 표기법의 차이점은 무엇입니까? 이 코드를 실제 코드에서 어디에 사용합니까?
notan3xit

2
@ notan3xit 아마 당신이 물어보고 싶은 것에 대한 대답이 아닐 수도 있습니다. 그러나 당신이 요구 한 것은 "... 내가 본 적이 없다. 검색 엔진에 의해 무시하기가 어렵 기 때문에 누가 무슨 뜻인지 말해 줄 수 있니?"
nafg


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.