我不会在这里使用隐式转换,而是在类中绑定一个视图:
case class Foo(x: Int)
case class Bar(y: Int)
implicit def foo2Bar(foo: Foo) = Bar(foo.x)
case class Items[A <% Bar](xs: List[A]) {
def apply(x: Int): Bar = xs(x)
}
您现在可以创建一个Items
带有列表的实例Foo
并在内部使用它们,就好像它们是Bar
s 一样。
scala> Items(List(Foo(1)))
res8: Items[Foo] = Items(List(Foo(1)))
scala> res8(0)
res9: Bar = Bar(1)
编辑:
一些澄清,为什么我不会使用隐式转换:
隐式转换可能很危险,当它们在范围内并意外转换了不应该转换的东西时。我总是会显式地或通过视图边界转换东西,因为这样我就可以控制它,隐式转换也可能会缩小代码的大小,但也会让其他人更难理解。我只会对“扩展我的库”模式使用隐式转换。
编辑2:
但是,如果这样的方法在范围内,您可以向集合类型添加一个方法来执行此转换:
trait Convertable[M[A], A] {
def convertTo[B](implicit f: A => B): M[B]
}
implicit def list2Convertable[A](xs: List[A]) = new Convertable[List, A] {
def convertTo[B](implicit f: A => B) = xs.map(f)
}
scala> implicit def int2String(x: Int) = x.toString
int2String: (x: Int)String
scala> List(1,2,3).convertTo[String]
res0: List[String] = List(1, 2, 3)
我可能不会在这里使用另一个隐式转换,而是使用类型类,但我想你明白了基本的想法。