이를 일반화 된 유형 제한 조건 이라고 합니다 . 타입 매개 변수화 된 클래스 나 특성 내에서 타입 매개 변수 중 하나 를 추가로 제한 할 수 있습니다. 예를 들면 다음과 같습니다.
case class Foo[A](a:A) { // 'A' can be substituted with any type
// getStringLength can only be used if this is a Foo[String]
def getStringLength(implicit evidence: A =:= String) = a.length
}
암시 적 인수 evidence
는 컴파일러에서 제공합니다 (iff A
is) String
. 당신은 그것을 생각할 수있는 증거A
입니다 String
고마웠다 인수 자체 만이 존재하는 것을 알고, 중요하지 않습니다. [편집 : 글쎄요, 기술적으로 실제로는 중요합니다.에서 (으) A
로의 암시 적 변환을 나타내므로 컴파일러가 String
호출 a.length
하지 않아도됩니다.]
이제 다음과 같이 사용할 수 있습니다.
scala> Foo("blah").getStringLength
res6: Int = 4
그러나 내가 Foo
다른 것을 포함하는 것으로 사용하려고 하면 String
:
scala> Foo(123).getStringLength
<console>:9: error: could not find implicit value for parameter evidence: =:=[Int,String]
"Int == String이라는 증거를 찾을 수 없습니다"라는 오류를 읽을 수 있습니다. 일반적으로 요구 되는 것보다 유형에 getStringLength
대한 추가 제한 을 부과하고 있습니다 . 즉, 당신은 단지 호출 할 수 켜짐 . 이 제약 조건은 컴파일 타임에 적용되며 멋지다!A
Foo
getStringLength
Foo[String]
<:<
와 <%<
비슷하게 작동하지만, 약간의 변형과 :
A =:= B
A가 정확히 B 여야 함을 의미
A <:< B
는 A가 B의 하위 유형이어야 함을 의미합니다 ( 단순 유형 제약 조건 과 유사 <:
)
A <%< B
의미 A는 암시 적 변환을 통해 B 로 볼 수 있어야 함을 의미합니다 (단순한 유형 제약 조건과 유사 <%
)
@retronym 의이 스 니펫 은 이러한 종류의 작업을 수행하는 방법과 일반화 된 유형 제약 조건이 이제 더 쉬워지는 방법에 대한 좋은 설명입니다.
추가
당신의 후속 질문에 대답하기 위해, 내가 준 예는 꽤 고안되었으며 분명히 유용하지 않습니다. 그러나 그것을 사용하여 List.sumInts
정수 목록을 추가 하는 메소드 와 같은 것을 정의한다고 상상해보십시오 . 이 메소드를 이전의 List
a, 단지 a 에서 호출하는 것을 허용하지 않으려 고 합니다 List[Int]
. 그러나 List
형식 생성자는 그렇게 제한 될 수 없습니다. 여전히 문자열, foos, bar 및 notnots 목록을 가질 수 있기를 원합니다. 따라서 일반화 된 형식 제약 조건을 설정 sumInts
하면 해당 메서드 에만에 사용할 수있는 추가 제약 조건이 있는지 확인할 수 있습니다 List[Int]
. 기본적으로 특정 종류의 목록에 대한 특수 사례 코드를 작성하고 있습니다.