微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

scala列表映射vs mapConserve

我试图理解mapConserve,据说是“喜欢xs map f,但如果函数f将所有元素映射到自己,则返回xs不变”,从 List开始.但是,它给出了错误.

def map [B] (f: (A) ⇒ B): List[B]
def mapConserve (f: (A) ⇒ A): List[A]
def mapConserve [B >: A <: AnyRef] (f: (A) ⇒ B): List[B]


scala> list map (x=>x)
rES105: List[Int] = List(1,2,3,4,5,6,7,8,9,10)

scala> list mapConserve (x=>x)
<console>:12: error: inferred type arguments [Int] do not conform to method mapConserve's type parameter bounds [B >: Int <: AnyRef]
              list mapConserve (x=>x)
                   ^

mapConserve代码应该满足(A)=>一个功能.如果不是,它仍应满足(A)=> B函数,因为类型A可以是子类型和自身的超类型.请赐教mapConserve的目的和错误.

解决方法

实际上,mapConserve定义为

def mapConserve[A <: AnyRef](xs: List[A])(f: A => A): List[A]
def mapConserve[B >: A <: AnyRef](f: A => B): List[B]

所以A应该是AnyRef的子类型. Int is a subtype of AnyVal,这会带来错误.

scala> val l = List("foo","bar","baz")
l: List[java.lang.String] = List(foo,bar,baz)

scala> l.mapConserve(_.toupperCase)
res4: List[java.lang.String] = List(FOO,BAR,BAZ)

scala> l.mapConserve(identity)
res5: List[java.lang.String] = List(foo,baz)

更新:

map和mapConserve之间的唯一区别,如scaladoc中所述:

Builds a new list by applying a function to all elements of this list.
Like xs map f,but returns xs unchanged if function f maps all elements to themselves (as determined by eq).

scala> val xs = List.fill(1000000)("foo")
xs: List[java.lang.String] = List(foo,foo,...)

scala> xs.map(identity) eq xs
res48: Boolean = false

scala> xs.mapConserve(identity) eq xs
res49: Boolean = true

在我的简单基准测试中,xs mapConserve标识的速度提高了约五倍.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐