我一直在与天隐式转换的问题了,但不知何故,我无法找出我做错了通用的特质隐式转换。我读过所有其他关于隐含问题的问题,但我仍然不明白问题所在。斯卡拉上实现Java接口
举个例子,让我们考虑这样一个Java接口(T扩展对象为简洁起见):
public interface JPersistable<T extends Object> {
public T persist(T entity);
}
在Scala中,我做到以下几点:
case class A()
case class B() extends A
case class C()
case class D() extends C
trait Persistable[DTOType <: A, EntityType <: C] {
// this would be implemented somewhere else
private def doPersist(source: EntityType): EntityType = source
// this does not implement the method from the Java interface
private def realPersist(source: DTOType)(implicit view: DTOType => EntityType): EntityType = doPersist(source)
// this DOES implement the method from the Java interface, however it throws:
// error: No implicit view available from DTOType => EntityType.
def persist(source: DTOType): EntityType = realPersist(source)
}
case class Persister() extends Persistable[B, D] with JPersistable[B]
object Mappings {
implicit def BToD(source: B): D = D()
}
object Test {
def main(args: Array[String]) {
import Mappings._
val persisted = Persister().persist(B())
}
}
正如评论指出,我在编译时得到一个异常。我想我的问题是:
1)为什么我需要指定的doRealPersist
明确的隐式转换?即使我做了以下操作,我预计转换也会发生:
trait Persistable[DTOType <: A, EntityType <: C] {
// this would be implemented somewhere else
private def doPersist(source: EntityType): EntityType = source
def persist(source: DTOType): EntityType = doPersist(source)
}
但是,这也不能编译。
2)为什么在persist
编译失败,而不是实际的方法调用(val persisted = Persister().persist(B())
)?这应该是实际类型的实体类型和DTOType已知的第一个地方,对吗?
3)是否有更好的方式做什么,我想达到什么目的?再次,这不是我想要做的实际事情,但足够接近。
道歉提前,如果这个问题是无知和感谢很多提前对您有所帮助。
感谢您的快速解答Rex。仍然让我困惑的是,对于Predef implicits(如'byte2short'),如果您想使用转换,则不必指定抽象def。我预计转换将可用......好吧,含蓄地。特别是在我的问题1中,我希望scala一旦知道类型就能解决转换。至少我会期待如果我在你的例子中将'Mappings._'带入'Persister'的范围,我不必再次实现隐式def。 它对我来说仍然有点神秘我究竟是在做什么错... – LeChe
@LeChe - 我已经更新了我的答案,显示了一个使用“让外部隐式转换做它”的建议。 –
当然,我是一个白痴!为什么特质需要知道A树,转换应该完全透明!该死,我现在觉得很愚蠢。非常感谢你的解释。 – LeChe