Рассмотрим следующую REPL сессию:CanBuildFrom не найден, когда вызывается неявно
@ def test[C[X] <: TraversableOnce[X]](implicit cbf: CanBuildFrom[C[Int], Int, C[Int]]) = cbf()
defined function test
@ test[List]
res32: collection.mutable.Builder[Int, List[Int]] = ListBuffer()
@ def test[C[X] <: TraversableOnce[X]] = implicitly[CanBuildFrom[C[Int], Int, C[Int]]]
cmd33.sc:1: Cannot construct a collection of type C[Int] with elements of type Int based on a collection of type C[Int].
def test[C[X] <: TraversableOnce[X]] = implicitly[CanBuildFrom[C[Int], Int, C[Int]]]
^
Compilation Failed
Первое определение test
функции компилирует и работает, а второй один не компилируется. Единственная разница между ними - это способ получения экземпляра CanBuildFrom
. В первом случае он объявлен как неявный параметр, требующий от компилятора его найти. Во втором случае он вызывается функцией implicitly
, которая теоретически должна вести себя одинаково с точки зрения неявного поиска. Что вызывает такое поведение?
Но в чем разница между неявными областями в этих двух ситуациях? Как я уже сказал, я сделал это в REPL, поэтому в первом случае был найден общий «CanBuildFrom» (в Predef, я полагаю), когда я вызвал функцию. Это означает, что в области видимости имеется подходящий неявный экземпляр «CanBuildFrom». Почему один и тот же нельзя использовать при определении автономной функции в REPL? – Haspemulator
В одном случае у вас есть конкретный тип, например. 'List', в другом вы имеете абстрактный тип параметра' C [_] '.Неявное разрешение будет выглядеть, среди прочих, у сопутствующего объекта класса типа («CanBuildFrom') и его параметров типа (например, здесь« List »- где он находит экземпляр типа!), Но, очевидно, не может разрешить абстрактный тип , –
Правильно, теперь это имеет смысл. – Haspemulator