Scala的理解效率如何?
在第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这样做“翻译”? 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 } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |