Неявное преобразование из массива в список - PullRequest
7 голосов
/ 13 февраля 2011

Как мне написать неявное преобразование из типа Array[_] в List[_]? Я попробовал следующее, но это не сработало.

scala> implicit def arrayToList[A : ClassManifest](a: Array[A]): List[A] = a.toList
<console>:5: error: type mismatch;
 found   : Array[A]
 required: ?{val toList: ?}
Note that implicit conversions are not applicable because they are ambiguous:
 both method arrayToList in object $iw of type [A](a: Array[A])(implicit evidence$1: ClassManifest[A])List[A]
 and method genericArrayOps in object Predef of type [T](xs: Array[T])scala.collection.mutable.ArrayOps[T]
 are possible conversion functions from Array[A] to ?{val toList: ?}
       implicit def arrayToList[A : ClassManifest](a: Array[A]): List[A] = a.toList
                                                                           ^

Ответы [ 2 ]

10 голосов
/ 13 февраля 2011
implicit def arrayToList[A](a: Array[A]) = a.toList

Кажется, работает как ожидалось. Я предполагаю, что уже есть genericArrayOps в Predef, который имеет сигнатуру для неявного преобразования из Array[T] -> ArrayOps[T], ArrayOps[T] имеет метод .toList(): List[T]. Ваш метод имеет подпись Array[T] -> List[T], что также делает метод .toList[T] доступным. Тело просит неявное преобразование с этой подписью. Компилятор не знает, что использование arrayToList приведет к тому, что этот метод войдет в бесконечный цикл, что приводит к ошибке неоднозначности. Тем не менее, вывод типа возвращаемого значения, похоже, способен обойти эту проблему. Похоже, разрешение последствий не очень хорошо сочетается с выводом типа.

Также стоит отметить, что, поскольку уже существует неявное преобразование, которое даст вам то, что вы хотите по умолчанию, нет необходимости в неявном преобразовании из Array в List.

7 голосов
/ 13 февраля 2011

Нет необходимости в Manifest или ClassManifest при преобразовании из массивов, поскольку Array - это один тип "коллекции", который получает специальную обработку в JVM и не подвергается типу стирание.

Это означает, что вы можете использовать очевидный / тривиальный подход, никакой хитрости не требуется:

implicit def arrayToList[A](arr: Array[A]) = arr.toList

Хотя один вопрос ... Учитывая, что .toList уже является такой тривиальной операцией, что вы получите, сделав ее неявной?

...