Scala:隐式转换在任何情况下都有效吗?
我想将不同类型层次结构中的一些对象存储到Scala:隐式转换在任何情况下都有效吗?,scala,implicit,typeclass,Scala,Implicit,Typeclass,我想将不同类型层次结构中的一些对象存储到List[Any]或类似的容器中,但稍后会对它们执行隐式转换,以执行类似类型类的操作。 以下是一个例子: abstract class Price[A] { def price(a: A): Int } trait Car case class Prius(year: Int) extends Car trait Food case class FriedChicken() extends Food object Def { // implic
List[Any]
或类似的容器中,但稍后会对它们执行隐式转换,以执行类似类型类的操作。
以下是一个例子:
abstract class Price[A] {
def price(a: A): Int
}
trait Car
case class Prius(year: Int) extends Car
trait Food
case class FriedChicken() extends Food
object Def {
// implicit object AnyPrices extends Price[Any] {
// def price(any: Any) = 0
// }
// implicit object PriusPrices extends Price[Prius] {
// def price(car: Prius) = 100
// }
implicit object CarPrices extends Price[Car] {
def price(car: Car) = 100
}
implicit object FoodPrices extends Price[Food] {
def price(food: Food) = 5
}
}
def implicitPrice[A: Price](x: A) = implicitly[Price[A]].price(x)
import Def._
val stuff: List[Any] = List(Prius(2010), FriedChicken())
stuff map { implicitPrice(_) }
上述代码抛出一个错误,如下所示:
error: could not find implicit value for evidence parameter of type Price[Any]
stuff map { implicitPrice(_) }
^
如果取消注释AnyPrices
,您将得到列表(0,0)
,但这不是我所期望的。
我必须将清单存储到列表中才能工作吗
此外,
List(Prius(2010))map{implicitPrice()}
也不起作用,因为它想要Price[Prius]
而且Price[Car]
不够好。有没有办法使它更灵活?因此,一旦对象减少到Any
,我就无法获得类型类。我尝试使用Manifest
也失败了,因为即使我有Manifest[T]
对象,我似乎也无法将Any
强制转换为T
import reflect.Manifest._
def add [A, B >: A](stuff: A, list: List[(B, Manifest[_])])(implicit m: Manifest[A]) = (stuff, m) :: list
val stuff2 = add(Prius(2000), add(FriedChicken(), Nil))
stuff2 map { x =>
val casted = x._2.erasure.cast(x._1)
implicitPrice(casted)
}
给我
error: could not find implicit value for evidence parameter of type Price[Any]
因此,似乎我必须先将问题解析为Price
,然后才能将它们粘贴到列表中:
abstract class Price[A] {
def price(a: Any): Int
}
trait Car
case class Prius(year: Int) extends Car
trait Food
case class FriedChicken() extends Food
object Def {
implicit object PriusPrices extends Price[Prius] {
def price(car: Any) = 100
}
implicit object FriedChickenPrices extends Price[FriedChicken] {
def price(food: Any) = 5
}
}
import Def._
def add [A, B >: A](stuff: A, list: List[(B, Price[_])])(implicit p: Price[A]) = (stuff, p) :: list
val stuff = add(Prius(2000), add(FriedChicken(), Nil))
stuff map { x => x._2.price(x._1) }
隐式是静态选择的。考虑到您的列表包含不相关的类型,它的静态类型是list[Any]
,这说明了您看到的行为。您能建议一些解决方法吗Manifest[]#erasure.cast也返回Any
。有两件事:1)我对列表的推断类型有误。它实际上是List[Price]
,但您明确地将stuff
键入为List[Any]
;2) 底线是隐式是一个静态解析的构造,而您需要任何给定产品的价格确定方法的动态解析。我建议使用trait/mix-in方法。即使可以使用隐式转换,推断的类型似乎是List[Product]
res0:List[Product]=List(普锐斯(2010),FriedChicken())
。因为我可以存储比Product
更低的类型,比如String
,所以我强制执行Any
,但这似乎并不重要,因为它只适用于类型,而不适用于超类型。