복붙노트

[SCALA] 어떻게 스칼라 컬렉션 맵 작업에서 올바른 모음 형식을 반환 할 수 있습니다?

SCALA

어떻게 스칼라 컬렉션 맵 작업에서 올바른 모음 형식을 반환 할 수 있습니다?

참고 : 이것은 질문입니다,이 문제가 상당히 자주 올 것 같은 내가, 그것을 자신을 대답 할 수 있도록 특별히 부탁하고 나는 그것이 (희망) 쉽게 검색을 통해 발견 할 수있는 위치에 넣고 싶어

여기 내 대답에 코멘트하라는 메시지로

예를 들면 :

"abcde" map {_.toUpperCase} //returns a String
"abcde" map {_.toInt} // returns an IndexedSeq[Int]
BitSet(1,2,3,4) map {2*} // returns a BitSet
BitSet(1,2,3,4) map {_.toString} // returns a Set[String]

이러한 사용 TraversableLike에서 상속지도 작업 모두의 scaladoc에서 찾고, 그래서 어떻게 가장 유효한 특정 집합을 반환 할 수 항상있어 온? 암시 적 변환을 통해지도를 제공하더라도 문자열.

해결법

  1. ==============================

    1.스칼라 컬렉션은 영리 것들 ...

    스칼라 컬렉션은 영리 것들 ...

    컬렉션 라이브러리의 내부는 스칼라의 땅에 더 많은 고급 주제 중 하나입니다. 그것은 높은 kinded 유형, 추론, 분산, implicits 및 CanBuildFrom 메커니즘을 포함한다 - 모든 사용자에 직면 관점에서이 놀라 울 정도로 쉽게 사용에, 일반, 강력하게 할 수 있습니다. 포인트 오브 뷰 API를 디자이너의에서 이해 초보자에 의해 촬영하는 가벼운 마음 일이 아니다.

    다른 한편으로는 당신이 이제까지 실제로 깊이에서 컬렉션을 함께 작동하도록해야한다는 매우 드물다.

    그래서 우리가 시작합시다 ...

    스칼라 2.8의 출시와 함께, 컬렉션 라이브러리가 완전히 중복을 제거하기 위해 다시 작성했다, 아주 많은 방법이 지속적인 유지 보수 및 새로운 수집 방법의 추가가 훨씬 쉬울 것, 그래서 한 장소로 이동뿐만 아니라 열심히 계층을하게되었다 이해하다.

    예를 들어 목록을 가지고에서이 상속 (차례)

    그건 아주 소수입니다! 왜이 깊은 계층? XxxLike 특성 간단히 무시하고, 그 계층 구조의 각 계층의 기능이 약간의 추가, 또는 유전 기능의 더욱 최적화 된 버전을 제공한다 (예를 들어, 횡단 (traverse)에 인덱스 요소를 페치하는 드롭 머리 동작의 조합을 필요로 크게 비효율적 인덱싱 된 시퀀스). 가능한 모든 기능을 사용할 수 있습니다 서브 클래스의 수를 극대화하고 중복을 제거, 멀리 가능성이 갈 수있는 계층까지로 푸시됩니다.

    지도는 단지 하나의 예이다. 널리 상속 - 방법은 (내가 곧 그 부분에 올거야 XxxLike 특성은 정말 라이브러리 디자이너 존재하지만 일반적으로 대부분의 의도와 목적에 이동의 방법으로 간주하므로) TraversableLike에서 구현됩니다. 그것은 몇 가지 서브 클래스에 최적화 된 버전을 정의하는 것이 가능하지만, 여전히 동일한 서명을 준수해야합니다. (또한 질문에서 언급 한 바와 같이) 맵의 다음 사용을 고려하십시오

    "abcde" map {_.toUpperCase} //returns a String
    "abcde" map {_.toInt} // returns an IndexedSeq[Int]
    BitSet(1,2,3,4) map {2*} // returns a BitSet
    BitSet(1,2,3,4) map {_.toString} // returns a Set[String]
    

    각각의 경우에, 출력이 목적지 입력과 같은 입력 가능하다. 그것이 불가능하면 하나의 유효한 반환 형식을 제공 않는 것으로 확인 될 때까지 입력 타입의 슈퍼 클래스를 검사합니다. 많은 일이 당신이 문자열도 수집 아니라고 생각 특히,이 권리를 가지고 갔다 오기, 그것은 하나의 단지 암시 적으로 변환합니다.

    그래서 어떻게 이루어집니다?

    퍼즐의 절반은 진정한 서브 클래스를 알 수 있도록 그 주요 기능에 repr 유형 PARAM을하는 것입니다 (짧은 "표현"에 대한), (내가 ... 내가 그들에게 얻을 것이라고 말 했는가)을 XxxLike 특성입니다 실제로으로 운영된다. 그래서 예를 들면, TraversableLike은에 이동과 동일하지만,에 repr 유형 PARAM을 통해 추출. 이 PARAM이어서 퍼즐의 후반부에서 사용되며 캡처 소스 컬렉션 타입, 목표 요소 유형 및 타겟 컬렉션 타입 콜렉션 바뀌는 동작에 의해 사용되는 것을 CanBuildFrom 형 클래스.

    이 예제를 통해 설명하는 것이 더 쉽습니다!

    비트 세트는 다음과 같이 CanBuildFrom의 암시 적 인스턴스를 정의합니다 :

    implicit def canBuildFrom: CanBuildFrom[BitSet, Int, BitSet] = bitsetCanBuildFrom
    

    비트 세트 (1,2,3,4)지도 {2} *를 컴파일 할 때, 컴파일러는 CanBuildFrom [비트 세트, INT, T]의 내재적 검색을 시도 할

    이것은 단지 처음 두 유형의 매개 변수와 일치하는 범위 내에서 암시 하나가있다 ... 영리한 부분입니다. XxxLike 특성에 의해 포착 첫번째 매개 변수에 repr이고, 두 번째는 (예를 들어, 횡단 (traverse))가 집전 특성의 촬상 소자 타입이다. 지도 동작은 다음과 같은 유형의 매개 변수화되고,이 T 형 내재적 있던 CanBuildFrom 인스턴스 제 타입 파라미터에 기초하여 추정된다. 이 경우 비트 세트.

    CanBuildFrom 처음 두 입력 파라미터가 입력되도록 암시 조회에 사용하고, 세번째 파라미터는 추론에 사용될 수있는 출력이다한다.

    조회가 성공할 수 있도록 비트 세트에 CanBuildFrom 그러므로, 두 가지 유형의 비트 세트 및 지능과 일치하고, 추론 반환 형식은 비트 세트됩니다.

    비트 세트 (1,2,3,4)지도 {_.toString}를 컴파일 할 때, 컴파일러는 CanBuildFrom [비트 세트, 문자열, T]의 암시 조회를 시도합니다. 설정 - - 컴파일러는 다음 슈퍼 클래스를 시도 할 것이다, 그래서 이것은, 비트 세트에서 암시 실패합니다 이것은 암시 포함

    implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Set[A]] = setCanBuildFrom[A]
    

    어느 일치, 콜은 비트 세트로 초기화있어 유형 별칭이기 때문에 경우 설정에서 비트 세트가 파생됩니다. canBuildFrom는 따라서 세트 [문자열]의 반환 형식을 산출 ... 문자열로 추정있어이 경우, A 형과 매개 변수화되는대로 A는 아무것도 일치합니다.

    제대로 컬렉션 형식을 구현에 따라서, 당신은 단지 형 CanBuildFrom의 정확한 암시를 제공 할 필요가 없습니다,하지만 당신은 그 수집의의 구체적인 유형 (예를 들어, 올바른 부모의 특성에에 repr의 PARAM로 공급되고 있는지 확인해야합니다 이것은)지도를 서브 클래스의 경우 MapLike 될 것이다.

    문자열은 암시 적 변환에 의해지도를 제공하기 때문에 조금 더 복잡하다. 문자열에 repr 형 PARAM 인 - 암시 적 변환은 궁극적 TraversableLike [샤아 문자열]이 도출 StringLike [문자열, 서브 클래스하는 StringOps이다.

    가 문자 문자열의 요소를 매핑 할 때 CanBuildFrom도있다 [문자열, 숯불, 문자열] 범위에 따라서 컴파일러가 알고, 다음 반환 형식은 문자열이어야한다는 것을. 이후이 시점에서, 동일한 메커니즘이 사용됩니다.

  2. ==============================

    2.스칼라 컬렉션의 아키텍처는 온라인 페이지는 2.8 컬렉션 디자인을 기반으로 새로운 컬렉션을 만드는 실용적인 측면에 맞도록 자세한 설명이 있습니다.

    스칼라 컬렉션의 아키텍처는 온라인 페이지는 2.8 컬렉션 디자인을 기반으로 새로운 컬렉션을 만드는 실용적인 측면에 맞도록 자세한 설명이 있습니다.

    인용문:

    그것은 패트리샤 트라이 RNA 서열에 대해 하나를 인코딩하는 예를 들어 컬렉션을 이용한다. 적절한 컬렉션 형식을 반환하기 위해 무엇을해야하는지에 대한 설명에 대한지도와 친구 섹션과 딜링을 찾아보십시오.

  3. from https://stackoverflow.com/questions/5200505/how-are-scala-collections-able-to-return-the-correct-collection-type-from-a-map by cc-by-sa and MIT license