加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala将隐式函数应用于集合

发布时间:2020-12-16 08:48:27 所属栏目:安全 来源:网络整理
导读:编辑:我正在使用 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.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应用于双类型集合的所有元素

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,3 ).map( _.double )

有谁知道为什么会这样?

解决方法

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

在您的示例中,您可以执行2.double这一事实与Predef中从Double到Int的隐式转换无关.
作为证明,请在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 )

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读