Scala隐式转换不适用于某些类型
我有一个容器类型,它保存与值关联的元数据Scala隐式转换不适用于某些类型,scala,implicit-conversion,Scala,Implicit Conversion,我有一个容器类型,它保存与值关联的元数据 class Container[A](val value: Option[A], val meta: Metadata) 有时访问meta很有用,但大多数情况下,像使用选项[a]一样使用值更方便。这是一个隐式转换 object Container { implicit def containerToValue[A](c: Container[A]): Option[A] = c.value } 所有这些都很好。问题是,通常会出现从A=>B到Con
class Container[A](val value: Option[A], val meta: Metadata)
有时访问meta很有用,但大多数情况下,像使用选项[a]
一样使用值更方便。这是一个隐式转换
object Container {
implicit def containerToValue[A](c: Container[A]): Option[A] = c.value
}
所有这些都很好。问题是,通常会出现从A=>B
到Container[A]
的隐式转换。我想做的是提供一种基本上从Container[a]=>Option[B]
进行隐式转换的方法。我的第一次尝试是:
object Container {
implicit def containerToValue[A](c: Container[A]): Option[A] = c.value
implicit def containerToB[A,B](c: Container[A])(implicit conv: (A) => B): Option[B] = c.value.map(conv)
}
Scala一点也不喜欢这样,因此作为一种退步,因为在90%的情况下B
实际上是一个字符串,我尝试了用更多的类型来填充:
object Container {
implicit def containerToValue[A](c: Container[A]): Option[A] = c.value
implicit def containerToB[A](c: Container[A])(implicit conv: (A) => String): Option[String] = c.value.map(conv)
}
这做得好一点,但我得到了一些关于歧义的错误。我想知道的是,是否有办法指定a
不是String
。也许是这样的:
implicit def containerToB[A >!> String]
这样我就可以告诉编译器,这个隐式转换只适用于非字符串的情况
有更好的方法来处理这个问题吗?为什么不在混合中添加一个类型类,这样您就可以按照您希望的方式来处理它们,而不是执行隐式转换(因为它们很难调试,在您最不希望的情况下会导致运行时错误,并使代码变得不那么清晰)
trait Extractor[A,B]{
def opt(that: Container[A]): B
}
然后显式创建您可能需要的所有不同实例:
def myGloriousFunction[B](that: Container[A])(implicit ex: Extractor[A,B]) ={
val value = ex.opt(that)
//more stuff
}
它将处理为您的内部选项找到“提取器”的问题,而且它的签名仍然相当明确。我知道这可能不是您想要听到的,但是请重新考虑像这样的隐式转换是可怕的东西,而且几乎可以肯定有更好的方法来获得您想要的便利。