为什么Scala推断路径依赖类型的路径 – 甚至从显式的自引用?
发布时间:2020-12-16 09:18:35 所属栏目:安全 来源:网络整理
导读:我想将一个对象传递给一个接受一个投影类型的参数的函数,并且得到 Scala来推断对象的类型来自包围对象的对象.这里有一些简单的代码来说明难点: trait Cult { cult_ = case class CultLeader(personality: Personality) { val cult = cult_ val follower = p
我想将一个对象传递给一个接受一个投影类型的参数的函数,并且得到
Scala来推断对象的类型来自包围对象的对象.这里有一些简单的代码来说明难点:
trait Cult { cult_ => case class CultLeader(personality: Personality) { val cult = cult_ val follower = personality.attractFollower(this) } case class Follower(leader: CultLeader,name: String) } trait Personality { def attractFollower(leader: Cult#CultLeader) = leader.cult.Follower(leader,"Fred") <-- THIS LINE FAILS TO COMPILE } 换句话说,Cultleader的个性应该吸引与追随者相同的崇拜者. Scala 2.11.2编译器说: TypeProjection.scala:11: error: type mismatch; found : Cult#CultLeader required: leader.cult.CultLeader leader.cult.Follower(leader,"Fred") ^ 如果我添加一个演员,它会编译并正确运行,如下所示: leader.cult.Follower(leader.asInstanceOf[leader.cult.CultLeader],"Fred") 这似乎很笨拙,它引入了在编译时应该可以推出的东西的运行时检查.至少我有一个解决方法.如何让Scala编译器推断领导者的类型其实是leader.cult.CultLeader? 我不希望通过邪教作为另一个参数来吸引浪漫者.在我的实际代码中,这可能会导致很多丑恶的传播邪教参数 – 当它真的不需要通过. 解决方法
简单的方法是:
trait Cult { cult_ => case class CultLeader(personality: Personality) { val cult = cult_ val follower = personality.attractFollower(this) } case class Follower(leader: Cult#CultLeader,name: String) // <-- Cult#CultLeader here } trait Personality { def attractFollower(leader: Cult#CultLeader) = leader.cult.Follower(leader,"Fred") } // Exiting paste mode,now interpreting. defined trait Cult defined trait Personality 在这里,您明确指定了跟随者可以采取任何投影,您实际上正在尝试强制使用asInstanceOf. 还有另一种方法: trait Cult { case class CultLeader(personality: Personality) { def fl(name: String) = Follower(this,name) val follower = personality.attractFollower(this) } case class Follower(leader: CultLeader,name: String) } trait Personality { def attractFollower(leader: Cult#CultLeader) = leader.fl("Fred") } 要么 trait Cult { case class CultLeader(personality: Personality) { ld => val follower = personality.attractFollower(this) case class Follower(name: String) { val leader = ld } } } trait Personality { def attractFollower(leader: Cult#CultLeader) = leader.Follower("Fred") } 更新:这个例子可以使它更清楚为什么Scala正在做她正在做的事情: trait Cult { cult_ => case class CultLeader(personality: Personality) { val cult: Cult = cult_ //could be new Cult{} as well val l = this.asInstanceOf[cult.CultLeader] //We have to do asInstanceOf here because Scala have no glue (from type signature) that this cult is same as cult_ val follower = personality.attractFollower(this) } case class Follower(leader: CultLeader,name: String) } trait Personality { def attractFollower(leader: Cult#CultLeader) = leader.cult.Follower(leader.l,"Fred") } // Exiting paste mode,now interpreting. defined trait Cult defined trait Personality 这里是最终的解决方案,以正确的方式做你想要的: trait Cult { cult_ => case class CultLeader(personality: Personality) { val cult: cult_.type = cult_ val l: cult.CultLeader = this val follower = personality.attractFollower(this) } case class Follower(leader: CultLeader,name: String) } trait Personality { def attractFollower(leader: Cult#CultLeader) = leader.cult.Follower(leader.l,"Fred") } // Exiting paste mode,now interpreting. defined trait Cult defined trait Personality 这里的意思是,cult_.type是路径依赖(投影). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |