如何在集合中进行隐式转换?

2024-04-13

假设我有一个隐式转换:

implicit def aToB(a: A):B={
...
}

如何让这种隐式转换适用于列表的元素?

如果我有:

val listOfA: List[A] ...

我有一个接受 B 列表的函数,是否可以让 Scala 将所有元素从 A 隐式转换为 B ?

如果没有隐式转换,转换可能如下所示:

lisftOfA.map(a => new B(a.someValue, a.anotherValue))

但我希望这能像“魔法”一样发生……这个要求是否太过分了?


以下是您可能希望考虑的一些替代方案:

1. 使用视图绑定

如果可以更改采用 B 列表的函数,这将是最简单的解决方案。修改它以接受可以转换为 B 的事物列表。那是,

def yourFn(l: List[B]) = ...

会成为

def yourFn[X <% B](l: List[X]) = ...

然后,您可以使用 listOfA 调用该函数:

yourFn(listOfA)

2.介绍转换方法

这与 Rogach 的第一个解决方案类似,只是外部转换是非隐式的:

def convert[B, A <% B](l: List[A]): List[B] = l map { a => a: B }

然后在你的函数的调用站点,你会写

yourFn(convert(listOfA))

与 Rogach 的第二个解决方案一样,这比引入隐式转换要安全一些。

3.引入隐式转换

这相当于 Rogach 的第一个解决方案,但符号更好一点(IMO)。

implicit def convert[B, A <% B](l: List[A]): List[B] = l map { a => a: B }

如果此转换在您的调用站点的范围内,您只需使用 listOfA 调用您的函数:

yourFn(listOfA)

离别的思念

考虑如何以一般方式解决这个问题是很有趣的。如果我想定义我的转换方法,以便它可以处理实现该转换的任何类型,该怎么办?map方法? IE。,

def convert[B, A <% B, C[_]](c: C[A]): C[B] = c map { a => a: B }

当然,这是行不通的,因为签名中没有任何内容表达这样的约束:C必须执行map。据我所知,表达这个约束是相当复杂的,并且不能以一种为任何实现的类型提供开箱即用支持的方式来完成map. See 类型安全的 Scala 序列理解 http://tonymorris.github.io/blog/posts/type-safe-scala-sequence-comprehensions/.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在集合中进行隐式转换? 的相关文章

随机推荐