Tenez compte de la session REPL suivante:CanBuildFrom introuvable lorsqu'il est invoqué implicitement
@ 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
La première définition de test
fonction et compile des œuvres, tandis que le second ne compile pas. La seule différence entre eux est la façon dont l'instance de CanBuildFrom
est obtenue. Dans le premier cas, il est déclaré comme paramètre implicite, ce qui oblige le compilateur à en trouver un. Dans le second cas, il est appelé via la fonction implicitly
, qui, en théorie, devrait se comporter de la même manière en termes de portée de recherche implicite. Quelles sont les causes de ce comportement?
Mais quelle est la différence entre les champs d'application implicites dans ces 2 situations? Comme je l'ai dit, je l'ai fait dans REPL, donc dans le premier cas un 'CanBuildFrom 'générique a été trouvé (dans Predef, je suppose) quand j'ai appelé la fonction. Cela signifie qu'il existe une instance implicite appropriée de CanBuildFrom dans la portée. Pourquoi le même ne peut-il pas être utilisé lors de la définition d'une fonction autonome dans REPL? – Haspemulator
Dans un cas, vous avez un type de béton, par ex. 'List', dans l'autre vous avez un paramètre de type abstrait' C [_] '.La résolution implicite portera, entre autres, sur l'objet compagnon de la classe type (CanBuildFrom) et de ses paramètres de type (par exemple ici List - où il trouve l'instance de classe de type!), Mais ne peut évidemment pas résoudre un type abstrait . –
Bon, maintenant c'est logique. – Haspemulator