为何先导入Doobie再导入Circe会引发Scala编译错误?
Doobie与Circe导入顺序引发编译错误的原因
问题背景
在同时使用Doobie和Circe时,发现导入顺序会影响编译结果:
- 先导入
doobie.util._再导入io.circe._,编译器提示“cannot resolve symbol circe” - 先导入
io.circe._再导入doobie.util._,编译正常 - 使用
import _root_.io.circe._也能解决问题
使用的库版本:
val scalaVersion = "2.13.12" val DoobieVersion = "1.0.0-RC1" val CirceVersion = "0.14.5"
核心原因:Scala的导入遮蔽(Shadowing)机制
问题的关键在于Doobie的doobie.util包下存在一个名为io的子模块,当你先执行import doobie.util._时,这个io模块会被导入到当前作用域中,此时io这个名称会被绑定到doobie.util.io,而非根路径下的io包(Circe所在的包)。
后续再写import io.circe._时,编译器会优先在当前作用域已有的io(也就是doobie.util.io)中查找circe,自然找不到,于是报错。
不同导入方式的解释
- 先导
io.circe._再导doobie.util._:此时io已经被绑定到根路径的io包,后续导入doobie.util._虽然也会引入内部的io,但Scala不会覆盖已有的同名导入绑定,所以依然使用根包的io,因此io.circe能正常找到。 - 使用
import _root_.io.circe._:_root_是Scala中表示根路径的关键字,明确告诉编译器从根目录开始查找io包,完全绕过了作用域中被遮蔽的doobie.util.io,所以能正确定位到Circe的包。
内容的提问来源于stack exchange,提问作者Bomen_Derick
相关产品推荐
相关产品推荐

