Scala의 암시적 구성이 더 높은 종류의 유형을 변환하도록 구성될 수 있나요?

StackOverflow https://stackoverflow.com/questions/5485672

문제

LongArrayWritable이라는 유형이 있는데, 이는 Long 배열의 박스형 표현입니다.다음 유형 간에 변환하는 암시적 정의가 있습니다.

implicit def boxLongArray(array: Array[Long]) : LongArrayWritable { /*elided*/}
implicit def unboxLongArray(array: LongArrayWritable) : Array[Long] { /*elided*/}

이제 java.lang.Iterable과 scala.collection.List[X] 사이를 일반 형식으로 변환하는 암시적 함수도 있습니다.

implicit def iterator2list[X](it : java.lang.Iterable[X]) : List[X] { /* elided */ }
implicit def list2iterator[X](list : List[X]) : java.lang.Iterable[X] { /* elided */ }

이러한 정의를 사용하여 스칼라 컴파일러는 java.lang.Iterable[LongArrayWritable]과 List[Array[Long]] 사이의 암시적 변환을 추론할 수 있습니까? iterator2list(iterator).map(unboxLongArray(_))), 아니면 암시적 기능을 넘어서는 것이므로 자체적인(명시적?) 암시적 정의가 필요합니까?

감사해요,

도움이 되었습니까?

해결책

이 질문을 다루는 게시물이 있습니다. Scala에서 암시적 연결을 어떻게 할 수 있나요? .기본적으로 다음으로 변환하려면 뷰 경계가 있어야 합니다. LongArrayWritable.즉, 암시적인 def 이는 다음으로 변환됩니다. LongArrayWritable 암시적 인수(뷰 바운드라고 함)를 수신하므로 이에 대한 인수는 def 직접적으로는 아니다 Array 하지만 다음으로 변환될 수 있는 일부 유형은 Array:

object LongArrayWritable {
  implicit def fromArraySource[A <% Array[Long]](a: A): LongArrayWritable = apply(a)
}
case class LongArrayWritable(a: Array[Long])

def test(a: LongArrayWritable): Unit = println("OK")

이제 이것은 배열에서 작동합니다.

test(Array( 1L, 2L, 3L))

그러나 이후 Array 는 아니다 Iterable 기본 변환은 없습니다. Iterable 에게 Array 범위에 다음 중 하나를 추가해야 합니다.

implicit def iterable2Array[A: ClassManifest](i: Iterable[A]): Array[A] = i.toArray

그러면 작동합니다 :

test(List(1L, 2L, 3L))

뷰 바운드 A <% Array[Long] 유형의 암시적 인수에 대한 지름길입니다. A => Array[Long], 그래서 당신도 쓸 수 있었을 것입니다

implicit def fromArraySource[A](a: A)(implicit view: A => Array[Long]) ...
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top