gpt4 book ai didi

Scala 将隐式函数应用于集合

转载 作者:行者123 更新时间:2023-12-01 02:27:39 24 4
gpt4 key购买 nike

编辑:我使用的是 Scala 2.9.2

在 Scala 中,我定义了一个包含 Double 的自定义类:

class DoubleWrap( d : Double ) {
def double( ) = d * 2
}

以及从 Double 到 DoubleWrap 的隐式转换:
implicit def wrapDouble( d : Double ) = new DoubleWrap( d )

这使我可以执行以下操作:
scala> 2.5.double
res0: Double = 5.0

但是,由于 Scala 中存在从 Int 到 Double 的隐式转换,我还可以执行以下操作:
scala> 2.double
res1: Double = 4.0

此运算符也可以使用 map 应用于 double 类型集合的所有元素。
scala> List( 1.0, 2.0, 3.0 ).map( _.double )
res2: List[Double] = List(2.0, 4.0, 6.0)

但是,如果我尝试将该函数应用于整数集合的所有元素,则它不起作用:
scala> List( 1, 2, 3 ).map( _.double )
<console>:10: error: value double is not a member of Int
List( 1, 2, 3 ).map( _.double )

有谁知道为什么会这样?

最佳答案

在 Scala 中,隐式转换是 不是 自动链接。换句话说,编译器会寻找 单例使代码有意义的隐式转换,它永远不会尝试应用两个(或更多)连续的隐式转换。

在您的示例中,您可以执行 2.double 的事实与来自 Double 的隐式转换这一事实无关。至 IntPredef .
作为证明,在 REPL 中试试这个:

scala> val i: Int = 2
i: Int = 2

scala> i.double
<console>:13: error: value double is not a member of Int
i.double

它不编译。
那么为什么 2.double编译?好问题。
我以为我直观地理解了这一点: 2可以解释为 Int值 2 或作为 Double首先值 2.0,所以我的直觉是 2不知何故已经是 Double在这种情况下。
但是,我认为这是错误的,因为即使是以下内容也会令人惊讶地编译: (2:Int).double (或者更奇怪的是: ((1+1):Int).double )。老实说,我大吃一惊,不知道为什么会在 val i: Int = 2; i.double 时编译。才不是。

所以总结一下,scala 不会尝试同时应用两个隐式转换是很正常的,但是由于某种原因,这个规则似乎不适用于 常量表达式 .

现在寻找一种解决问题的方法:只需修改您的隐式转换,使其接受任何本身可隐式转换为 Double 的类型。 .实际上,这允许链接隐式转换:
implicit def wrapDouble[T <% Double]( d : T ) = new DoubleWrap( d )

关于Scala 将隐式函数应用于集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15136056/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com