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

Scala的理解效率如何?

发布时间:2020-12-16 09:08:48 所属栏目:安全 来源:网络整理
导读:在第23章“ Scala编程”一书中,作者给出了一个例子: case class Book(title: String,authors: String*)val books: List[Book] = // list of books,omitted here// ?nd all authors who have published at least two booksfor (b1 - books; b2 - books if b1
在第23章“ Scala编程”一书中,作者给出了一个例子:

case class Book(title: String,authors: String*)
val books: List[Book] = // list of books,omitted here
// ?nd all authors who have published at least two books

for (b1 <- books; b2 <- books if b1 != b2;
    a1 <- b1.authors; a2 <- b2.authors if a1 == a2)
yield a1

作者说,这将转化为:

books flatMap (b1 =>
   books filter (b2 => b1 != b2) flatMap (b2 =>
      b1.authors flatMap (a1 =>
        b2.authors filter (a2 => a1 == a2) map (a2 =>
           a1))))

但是如果你查看map和flatmap方法定义(TraversableLike.scala),你可能会发现,它们被定义为for循环:

def map[B,That](f: A => B)(implicit bf: CanBuildFrom[Repr,B,That]): That = {
    val b = bf(repr)
    b.sizeHint(this) 
    for (x <- this) b += f(x)
    b.result
  }

  def flatMap[B,That](f: A => Traversable[B])(implicit bf: CanBuildFrom[Repr,That]): That = {
    val b = bf(repr)
    for (x <- this) b ++= f(x)
    b.result
  }

好吧,我想这将继续被翻译为foreach,然后翻译成while语句,这是一个构造而不是表达式,scala没有for构造,因为它希望for总是产生一些东西.

所以,我想和你讨论的是,为什么Scala这样做“翻译”?
作者的例子使用了4个生成器,最终将被翻译成4级嵌套for循环,我认为当书籍很大时它会有非常糟糕的表现.

Scala鼓励人们使用这种“语法糖”,你总能看到大量使用过滤器,地图和平面图的代码,似乎程序员忘记了他们真正做的是将一个循环嵌套在另一个循环中,而实现的只是使代码看起来更短.你有什么想法?

解决方法

因为理解是monadic变换的语法糖,因此,在各种各样的地方都很有用.在那里,它们在Scala中比同等的Haskell结构更加冗长(当然,Haskell默认是非严格的,所以不能像Scala那样谈论构造的性能).

同样重要的是,这种结构可以保持清晰的工作,避免快速升级的缩进或不必要的私有方法嵌套.

至于最后的考虑,无论是否隐藏复杂性,我都会认为:

for {
  b1 <- books
  b2 <- books
  if b1 != b2
  a1 <- b1.authors
  a2 <- b2.authors 
  if a1 == a2
} yield a1

很容易看出正在做什么,复杂性很明显:b ^ 2 * a ^ 2(过滤器不会改变复杂性),书籍数量和作者数量.现在,使用深度缩进或私有方法在Java中编写相同的代码,并尝试快速确定代码的复杂性.

因此,imho,这并不掩盖复杂性,相反,它表明了这一点.

至于你提到的map / flatMap / filter定义,它们不属于List或任何其他类,因此不会应用它们.基本上,

for(x <- List(1,2,3)) yield x * 2

被翻译成

List(1,3) map (x => x * 2)

这不是一回事

map(List(1,3),((x: Int) => x * 2)))

这就是你传递的定义将被调用的方式.为了记录,List上map的实际实现是:

def map[B,That]): That = {
  val b = bf(repr)
  b.sizeHint(this) 
  for (x <- this) b += f(x)
  b.result
}

(编辑:李大同)

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

    推荐文章
      热点阅读