스칼라 컨텍스트와 뷰 범위는 무엇입니까?


267

간단한 방법으로 컨텍스트 및 뷰 바운드 란 무엇이며 차이점은 무엇입니까?

따라하기 쉬운 몇 가지 예도 좋습니다!

답변:


477

나는 이것이 이미 요청되었다고 생각했지만, 그렇다면 "관련된"바에서 그 질문은 명백하지 않다. 그래서 여기 있습니다 :

뷰 바운드 란 무엇입니까?

바인딩보기는 어떤 종류의 사용을 가능하게하는 스칼라에 도입 된 메커니즘이었다 A 것처럼 그것이 어떤 종류의했다 B. 일반적인 구문은 다음과 같습니다.

def f[A <% B](a: A) = a.bMethod

다시 말해, type의 객체에서 메소드를 호출 할 수 있도록 available A로 암시 적으로 변환해야 합니다 . 표준 라이브러리 (스칼라 2.8.0 이전)에서 가장 많이 사용되는 뷰 바운드는 다음 과 같습니다.BBAOrdered

def f[A <% Ordered[A]](a: A, b: A) = if (a < b) a else b

하나는 변환 할 수 있기 때문에 AOrdered[A]하고 있기 때문에 Ordered[A]방법을 정의 <(other: A): Boolean, 나는 표현을 사용할 수 있습니다 a < b.

양해하여 주시기 바랍니다 뷰 경계가되지 않습니다 당신이 그들을 피해야한다.

컨텍스트 바운드 란 무엇입니까?

컨텍스트 범위는 Scala 2.8.0에서 도입되었으며, 일반적으로 Haskell 유형 클래스가 제공하는 기능을보다 장황하게 표현하는 코드 패턴 인 소위 유형 클래스 패턴 과 함께 사용됩니다 .

뷰 바운드는 단순 유형 (예 :)과 함께 사용할 수 있지만 A <% String컨텍스트 바운드에는 위와 같은 매개 변수화 된 유형이 필요 Ordered[A]하지만와는 다릅니다 String.

컨텍스트 바운드 는 뷰 바운드의 암시 적 변환 대신 암시 적 값을 설명합니다 . 일부 유형 의 경우 사용 가능한 유형의 내재 된 값이 있음을 선언하는 데 사용됩니다 . 구문은 다음과 같습니다.AB[A]

def f[A : B](a: A) = g(a) // where g requires an implicit value of type B[A]

사용 방법이 명확하지 않기 때문에 뷰 바운드보다 혼란 스럽습니다. 스칼라 사용법의 일반적인 예는 다음과 같습니다.

def f[A : ClassManifest](n: Int) = new Array[A](n)

Array매개 변수화 된 유형에 대한 초기화는 ClassManifest유형 삭제 및 배열의 ​​비 삭제 특성과 관련된 특별한 이유로 사용할 수 있어야 합니다.

라이브러리에서 또 다른 매우 일반적인 예는 조금 더 복잡합니다.

def f[A : Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b)

여기서는 클래스가 메소드를 정의하는 implicitly유형 중 하나 인 원하는 암시 적 값을 검색하는 데 사용됩니다 .Ordering[A]compare(a: A, b: A): Int

우리는 이것을 아래에서 수행하는 다른 방법을 볼 것입니다.

뷰 바운드 및 컨텍스트 바운드는 어떻게 구현됩니까?

뷰 바운드와 컨텍스트 바운드가 모두 정의에 따라 암시 적 매개 변수로 구현된다는 것은 놀라운 일이 아닙니다. 실제로, 내가 보여준 구문은 실제로 일어나는 일에 대한 구문 설탕입니다. 그들이 어떻게 설탕을 제거하는지 아래를보십시오 :

def f[A <% B](a: A) = a.bMethod
def f[A](a: A)(implicit ev: A => B) = a.bMethod

def g[A : B](a: A) = h(a)
def g[A](a: A)(implicit ev: B[A]) = h(a)

따라서 자연스럽게 전체 구문으로 작성할 수 있으며 컨텍스트 범위에 특히 유용합니다.

def f[A](a: A, b: A)(implicit ord: Ordering[A]) = ord.compare(a, b)

뷰 바운드는 무엇에 사용됩니까?

뷰 바운드는 주로 라이브러리 형식 의 포주를 활용하는 데 주로 사용되며 ,이를 통해 원래 형식을 반환하려는 상황에서 기존 클래스에 메서드를 "추가"합니다. 어떤 식 으로든 해당 유형을 반환 할 필요가 없으면 뷰 바운드가 필요하지 않습니다.

뷰 바운드 사용의 고전적인 예는 처리 Ordered입니다. 참고 Int아니다은 Ordered, 예를 들어, 비록 암시 적 변환이 있습니다. 이전에 제공된 예제는 변환되지 않은 유형을 반환하므로 뷰 바운드가 필요합니다.

def f[A <% Ordered[A]](a: A, b: A): A = if (a < b) a else b

이 예제는 뷰 바운드없이 작동하지 않습니다. 그러나 다른 유형을 반환하려는 경우 더 이상 뷰 바인딩이 필요하지 않습니다.

def f[A](a: Ordered[A], b: A): Boolean = a < b

매개 변수를에 전달하기 전에 여기에서 필요한 경우 변환이 발생 f하므로 f알 필요가 없습니다.

게다가 Ordered, 라이브러리의 가장 일반적인 사용은 취급 String하고 Array그들이 스칼라 컬렉션 것처럼, 자바 클래스있는. 예를 들면 다음과 같습니다.

def f[CC <% Traversable[_]](a: CC, b: CC): CC = if (a.size < b.size) a else b

하나의 뷰 경계없이이 작업을 수행하려고 경우의 반환 형식은 StringWrappedString, 유사에 대한 (스칼라 2.8) Array.

형식이 반환 형식의 형식 매개 변수로만 사용되는 경우에도 마찬가지입니다.

def f[A <% Ordered[A]](xs: A*): Seq[A] = xs.toSeq.sorted

컨텍스트 바운드는 무엇에 사용됩니까?

컨텍스트 바운드는 주로 Haskell의 유형 클래스에 대한 참조 로 typeclass pattern으로 알려진 것에 사용됩니다 . 기본적으로이 패턴은 일종의 암시 적 어댑터 패턴을 통해 기능을 사용 가능하게하여 상속에 대한 대안을 구현합니다.

전형적인 예는 Scala 2.8 's Ordering이며 OrderedScala의 라이브러리 전체 를 대체 합니다. 사용법은 다음과 같습니다.

def f[A : Ordering](a: A, b: A) = if (implicitly[Ordering[A]].lt(a, b)) a else b

일반적으로 다음과 같이 작성된 것을 볼 수 있습니다.

def f[A](a: A, b: A)(implicit ord: Ordering[A]) = {
    import ord.mkOrderingOps
    if (a < b) a else b
}

Ordering기존 연산자 스타일을 가능하게하는 내부의 일부 암시 적 변환을 활용 합니다. 스칼라 2.8의 또 다른 예는 다음과 Numeric같습니다.

def f[A : Numeric](a: A, b: A) = implicitly[Numeric[A]].plus(a, b)

더 복잡한 예는의 새로운 컬렉션 사용법 CanBuildFrom이지만 이미 그것에 대해 매우 긴 답변이 있으므로 여기서는 피할 것입니다. 그리고 앞에서 언급했듯이 ClassManifest구체적인 유형없이 새 배열을 초기화하는 데 필요한 사용법이 있습니다.

타입 클래스 패턴으로 묶인 컨텍스트는 문제를 분리 할 수 ​​있기 때문에 자신의 클래스에서 훨씬 더 많이 사용될 수 있습니다. 반면 좋은 디자인으로 코드에서 뷰 바운드를 피할 수 있습니다. ).

오랜 시간 동안 가능했지만 컨텍스트 범위 사용은 실제로 2010 년에 시작되었으며 이제는 스칼라의 가장 중요한 라이브러리 및 프레임 워크에서 어느 정도 발견되었습니다. 그러나 그 사용법의 가장 극단적 인 예는 스칼라 즈 라이브러리로, Haskell의 강력한 기능을 스칼라에 제공합니다. 타입 클래스 패턴을 읽어서 사용할 수있는 모든 방법을 익히는 것이 좋습니다.

편집하다

관심있는 관련 질문 :


9
정말 고마워. 나는 이것이 이전에 답을 받았음을 알고 있으며, 아마도 충분히 읽지 않았을 수도 있지만, 여기에서 당신의 설명은 내가 본 가장 분명한 것입니다. 다시 한 번 감사드립니다.
chrsan

3
@chrsan 나는 두 개의 섹션을 더 추가하여 각각의 사용 위치에 대해 자세히 설명했다.
Daniel C. Sobral

2
나는 이것이 훌륭한 설명이라고 생각합니다. 괜찮다면 제 독일어 블로그 (dgronau.wordpress.com)로 번역하고 싶습니다.
Landei

3
이것은 지금까지 내가 찾은이 주제에 대한 가장 훌륭하고 포괄적 인 설명입니다. 참으로 대단히 감사합니다!
fotNelton

2
당신의 스칼라 책이 나오는 경우 SOOO, 나는 :) 어디서 살 수있다
wfbarksdale
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.