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

标签 scala implicit-conversion implicit

假设我有一个隐式转换:

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

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

如果我有:

val listOfA: List[A] ...

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

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

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

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

最佳答案

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

<强>1。使用 View 绑定(bind)

如果可以更改采用 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 方法的任何类型,该怎么办?即,

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

这当然行不通,因为签名中没有任何内容表达 C 必须实现 map 的约束。据我所知,表达这个约束是相当复杂的,并且不能通过为任何实现 map 的类型提供开箱即用的支持的方式来完成。请参阅Type-safe Scala sequence comprehensions .

关于scala - 如何在集合中进行隐式转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12447968/

相关文章:

android - Android 中的自定义隐式 Intent 不起作用

scala - 使用一些 Scala Option 方法的示例

scala - 删除给定列表的给定数量的正项

c++ - 在 switch 语句的条件下同时具有模板和非模板转换运算符的类

scala - 隐含和召唤有什么区别?

Scala 隐式参数的类型查找失败

programming-languages - Scala "continuations"只是用于定义和使用回调函数的时髦语法吗?

scala - SBT:当文件在两个单独的子项目中更改时如何触发单独的操作

c# - 使用泛型类时如何修复 CA2225 (OperatorOverloadsHaveNamedAlternates)

c - 在 C 中赋值之前如何存储表达式值?