Scala2.8探秘之for表达式

  虽然Scala2.8还在持续跳票中,但目前[url=http://www.scala-lang.org/node/212/distributions]Nightly Build[/url]版本的可用性已经很高了,其中Scala2.8中主要特性都已经实现。毫无疑问,Scala2.8的发布将会是Scala发展中的一个重大里程碑。在这个版本中,不仅包括了许多Scala社区期待已久的特性,如命名参数、类型特殊化等等,详细的信息可以参看[url]http://eastsun.iteye.com/blog/373710[/url];而且包含了一些对之前Scala中设计不合理的地方的改进,例如Scala中对String以及数组的处理,在之前的版本中Scala编译器在编译的时候对这两种类型进行了一些比较特殊(魔法)的处理,这样做虽然某些程度上使得这两种类型在Scala中更加易用,但同时也破坏了Scala中的一致性,并随之产生了一些离奇的问题。举个例子,在Scala2.7.7 final中我们可以看到如下结果:
[code]
//Scala2.7.7 final
scala> val array = Array("String Array")
array: Array[java.lang.String] = Array(String Array)

scala> println(array.toString())
Array(String Array)

scala> println(array)
[Ljava.lang.String;@139491b

scala> "WOW" == "WOW".reverse
res4: Boolean = false

scala> "abcdefg" map { _.toUpperCase }
res5: Seq[Char] = ArrayBufferRO(A, B, C, D, E, F, G) //注意,得到的是个Seq[Char]而不是String
[/code]
  显然这样的运行结果有违我们的直觉,即使是对Scala有一定了解的人也未必能马上明白其中的奥妙。
  在Scala2.8中,这些问题都得到了一定的解决——可能有些解决方式会让你觉得退步了,但是保持了Scala的一致性,并且消除了编译器在背后做的那些魔法,使事情变得简单——虽然这样破坏了Scala的向后兼容性,但我认为这样做事非常值得的:这为Scala成为一门成功的语言垫下了基础。下面我们看看在Scala 2.8.0.r20117-b20091213020323中上面代码的运行结果:
[code]
scala> val array = Array("String Array")
array: Array[java.lang.String] = Array(String Array)

scala> println(array.toString())
[Ljava.lang.String;@335053

scala> println(array)
[Ljava.lang.String;@335053

scala> "WOW" == "WOW".reverse
res2: Boolean = true

scala> "abcdefg" map { _.toUpperCase }
res3: String = ABCDEFG
[/code]
  可以看到,运行结果就如我们所预想的那样——固然其中数组的toString结果变得丑陋了,和Java中一样丑陋,但保持一致了。
  OK,String与数组的讨论就此为止,以后如果有时间我再来详细解释一下其背后的故事;现在我们转向本文要讨论的东东:Scala中的for表达式。注意:在本文中使用了两种不同的Scala版本:Scala2.7.7final与2.8.0.r20117-b20091213020323进行对比。
[b]
[size=large]1.Scala2.8之前的for表达式[/size][/b]
  在Scala中,通常有以下几种使用方式:
[code]
for (p <- e) e'
for (p <- e if g) e'
for (p <- e; p' <- e' ...) e''
[/code]
以及相应的
[code]
for (p <- e) yield e'
for (p <- e if g) yield e'
for (p <- e; p' <- e' ...) yield e''
[/code]
其中p,p'为Scala中的Pattern;e,e',e''为表达式;g为Boolean表达式。
  根据《The Scala Language Specification Version 2.7》,上面的for表达式将在编译阶段展开为下面的形式(没有考虑p为比较复杂的Pattern时的情形):
[code]
for (p <- e) e' => e.foreach { case p => e' }
for (p <- e if g) e' => for (p <- e.filter{ (x1,...,xn) => g }) e' => ..
for (p <- e; p' <- e' ...) e'' => e.foreach{ case p => for (p' <- e' ...) e'' }
[/code]
以及相应的
[code]
for (p <- e) yield e' => e.map { case p => e' }
for (p <- e if g) yield e' => for (p <- e.filter{ (x1,...,xn) => g }) yield e'
for (p <- e; p' <- e' ...) yield e'' => e.flatmap { case p => for (p' <- e' ...) yield e'' }
[/code]
  注意的是,这个转换发生在类型检查之前。也就是说,对map,filter,flatMap以及foreach这四个方法的方法签名没有任何其它限制,只需要满足展开后for语句的类型检查。通常情况下,对于一个具有类型参数A的类C——一般表示某种数据结构(集合)——下面的定义方式是比较自然的:
[code]
class C[A] {
def map[B](f: A => B): C[B]
def flatMap[B](f: A => C[B]): C[B]
def filter(p: A => Boolean): C[A]
def foreach(b: A => Unit): Unit
}[/code]
  相对Java1.5中的for语句,Scala的实现更加灵活,并且以一种轻量级的方式实现了[url=http://en.wikipedia.org/wiki/List_comprehension]List comprehension[/url]。举个例子,下面几行代码实现了求一个List的全排列:
[code]
scala> def perm[T](ls: List[T]): List[List[T]] = ls match {
| case Nil => List(Nil)
| case xs => for(x <- xs;ys <- perm(xs-x)) yield x::ys
| }
perm: [T](List[T])List[List[T]]

scala> perm(1::2::3::Nil)
res2: List[List[Int]] = List(List(1, 2, 3), List(1, 3, 2), List(2, 1, 3),
List(2, 3, 1), List(3, 1, 2), List(3, 2, 1))
[/code]
  但是这个转换规则还不甚完美。当转换后的表达式含有filter方法的时候,会产生几个问题。
[b][color=red](a)性能问题[/color][/b]
  以一个简单的问题为例:[color=blue]求1~999中所有偶数之和。[/color]
  下面是两段类似的解决代码:
[code]
val set = 1 until 1000
var sum = 0
for(num <- set;if(num%2 == 0)) sum += num
[/code]
或者把if语句移到括号外面:
[code]
val set = 1 until 1000
var sum = 0
for(num <- set) if(num%2 == 0) sum += num
[/code]
  这两段代码功能上应该是等价的,但是运行效率如何呢?下面首先写一个粗略的测试函数:
[code]
/**
计算count次调用call所需的时间,单位:毫秒
*/
def time(call : => Unit,count: Int): Long = {
var cnt = count
val start = System.currentTimeMillis
while(cnt > 0) {
call
cnt -= 1
}
System.currentTimeMillis - start
}
[/code]
  先在Scala2.7.7final中将每段代码各运行十万次:
[code]
scala> val set = 1 until 1000
set: Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...

scala> time({
| var sum = 0
| for(num <- set;if(num%2 == 0)) sum += num
| },100000)
res3: Long = 47390

scala>

scala> time({
| var sum = 0
| for(num <- set) if(num%2 == 0) sum += num
| },100000)
res4: Long = 3344

scala>
[/code]
  测试结果很出乎意料:两段类似的代码,性能竟相差一个数量级!
  之所以会有这么大的差异,根据上述的转换规则,第一段代码将会转换为下面的实际执行代码:
[code]
val set = 1 until 1000
var sum = 0
set.filter{ num => num%2 == 0) }.foreach{ case num => sum += num }
[/code]
  而第二段代码实际执行的是:
[code]
val set = 1 until 1000
var sum = 0
set.foreach{ case num => if(num%2 == 0) sum += num }
[/code]
  相对而言,第一段代码会调用filter方法,创建一个新的集合类,而这个集合类包含了1~999中所有的偶数。显然这个过程是比较昂贵的,也是不必要的。

[b][color=red](b)运行顺序[/color][/b]
  以
[code]for (p <- e if g) e'[/code]
为例,实际运行的代码为:
[code]
e.filter{ (x1,...,xn) => g }.foreach{ case p => e'}
[/code]
  可以看到,虽然直观上if g与e'在遍历的时候应该是依次循环执行;但事实上转换后if g整体先于e'执行。当g与e'中同时包含一个变量v,并且在g中对变量v进行改动时,实际运行结果可能和我们所预想的不一致。可能问题描述的不是很清楚,下面引用fineqtbull同学在[url=http://scalagroup.group.iteye.com/group/blog/481804]for语句中内嵌if语句的副作用[/url]一文中的代码作为例子来说明:实现compress方法,其功能是将一个list中连续相同的元素删减至一个。比如compress(List(1,1,2,3,3,1,1,4)) == List(1,2,3,1,4),下面是两段类似的实现代码,咋一看都没问题,但运行结果却不一样。
[code]
Welcome to Scala version 2.7.7.final (Java HotSpot(TM) Client VM, Java 1.6.0_17).

scala> def compress1[T](ls: List[T]): List[T] = {
| var res = List(ls.first)
| for(x <- ls) if(x != res.last) res = res:::List(x)
| res
| }
compress1: [T](List[T])List[T]

scala> def compress2[T](ls: List[T]): List[T] = {
| var res = List(ls.first)
| for(x <- ls;if(x != res.last)) res = res:::List(x)
| res
| }
compress2: [T](List[T])List[T]

scala> compress1(List(1,1,2,3,3,1,1,4))
res0: List[Int] = List(1, 2, 3, 1, 4)

scala> compress2(List(1,1,2,3,3,1,1,4))
res1: List[Int] = List(1, 2, 3, 3, 4)

scala>
[/code]
  有了之前的说明,我们不难发现其原因所在。但这样的结果显然违反了C/Java中习惯用法,很容易让一个刚接触Scala的人产生困惑。
[size=large]
[b]2.Scala2.8中的for表达式[/size][/b]
  刚才已经提到了Scala2.8之前for表达式所存在的两个问题,那么在Scala2.8中这两个问题有没有得到解决呢?下面将之前的代码在2.8.0.r20117-b20091213020323重新运行一次试试:
[code]
Welcome to Scala version 2.8.0.r20117-b20091213020323 (Java HotSpot(TM) Client VM, Java 1.6.0_17).

scala> def time(call : => Unit,count: Int): Long = {
| var cnt = count
| val start = System.currentTimeMillis
| while(cnt > 0) {
| call
| cnt -= 1
| }
| System.currentTimeMillis - start
| }
time: (call: => Unit,count: Int)Long

scala> val set = 1 until 1000
set: scala.collection.immutable.Range ...

scala> time({
| var sum = 0
| for(num <- set;if(num%2 == 0)) sum += num
| },100000)
res0: Long = 6906

scala> time({
| var sum = 0
| for(num <- set) if(num%2 == 0) sum += num
| },100000)
res1: Long = 4312

scala> def compress1[T](ls: List[T]): List[T] = {
| var res = List(ls.first)
| for(x <- ls) if(x != res.last) res = res:::List(x)
| res
| }
compress1: [T](ls: List[T])List[T]

scala> def compress2[T](ls: List[T]): List[T] = {
| var res = List(ls.first)
| for(x <- ls;if(x != res.last)) res = res:::List(x)
| res
| }
compress2: [T](ls: List[T])List[T]

scala> compress1(List(1,1,2,3,3,1,1,4))
res2: List[Int] = List(1, 2, 3, 1, 4)

scala> compress2(List(1,1,2,3,3,1,1,4))
res3: List[Int] = List(1, 2, 3, 1, 4)

scala>
[/code]
  可以看到Scala2.8中已经很好的解决了这两个问题。对于一门语言,要想对已经存在的问题进行改进是很困难的,因为首先这些改进要尽可能少的影响已经存在的旧有代码,另一方面不能带来新的问题。幸运的是,Martin想到了一个简单而优雅的方法成功做到了这些。下面简单的叙述一下Martin的解决方法,感兴趣的同学可以去看Martin的原文[url=http://old.nabble.com/Rethinking-filter-to25906315.html#a25923142]Rethinking filter[/url]。
  首先,Martin引入了一个新的方法withFilter,这个方法与filter方法一样以一个条件函数A => Boolean作为参数。与filter方法不同的是,withFilter方法是lazy的。它并不会创建一个新的包含符合条件的元素所组成的集合类,而是返回一个代理类WithFilter,这个类具有foreach、map、flatMap以及withFilter等方法,并且所有这些方法的调用是与原来条件组合的结果。下面是TraversableLike中WithFilter的实现,Scala2.8中所有的集合类都继承了TraversableLike:
[code]
class WithFilter(p: A => Boolean) {

/** Builds a new collection by applying a function to all elements of the
* outer $coll containing this `WithFilter` instance that satisfy predicate `p`.
*
* @param f the function to apply to each element.
* @tparam B the element type of the returned collection.
* @tparam That $thatinfo
* @param bf $bfinfo
* @return a new collection of type `That` resulting from applying the given function
* `f` to each element of the outer $coll that satisfies predicate `p`
* and collecting the results.
*
* @usecase def map[B](f: A => B): $Coll[B]
*
* @return a new $coll resulting from applying the given function
* `f` to each element of the outer $coll that satisfies predicate `p`
* and collecting the results.
*/
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
for (x <- self)
if (p(x)) b += f(x)
b.result
}

/** Builds a new collection by applying a function to all elements of the
* outer $coll containing this `WithFilter` instance that satisfy predicate `p` and concatenating the results.
*
* @param f the function to apply to each element.
* @tparam B the element type of the returned collection.
* @tparam That $thatinfo
* @param bf $bfinfo
* @return a new collection of type `That` resulting from applying the given collection-valued function
* `f` to each element of the outer $coll that satisfies predicate `p` and concatenating the results.
*
* @usecase def flatMap[B](f: A => Traversable[B]): $Coll[B]
*
* @return a new $coll resulting from applying the given collection-valued function
* `f` to each element of the outer $coll that satisfies predicate `p` and concatenating the results.
*/
def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
for (x <- self)
if (p(x)) b ++= f(x)
b.result
}

/** Applies a function `f` to all elements of the outer $coll containing this `WithFilter` instance
* that satisfy predicate `p`.
*
* @param f the function that is applied for its side-effect to every element.
* The result of function `f` is discarded.
*
* @tparam U the type parameter describing the result of function `f`.
* This result will always be ignored. Typically `U` is `Unit`,
* but this is not necessary.
*
* @usecase def foreach(f: A => Unit): Unit
*/
def foreach[U](f: A => U): Unit =
for (x <- self)
if (p(x)) f(x)

/** Further refines the filter for this $coll.
*
* @param q the predicate used to test elements.
* @return an object of class `WithFilter`, which supports
* `map`, `flatMap`, `foreach`, and `withFilter` operations.
* All these operations apply to those elements of this $coll which
* satify the predicate `q` in addition to the predicate `p`.
*/
def withFilter(q: A => Boolean): WithFilter =
new WithFilter(x => p(x) && q(x))
}
}[/code]
  在Scala2.8中,for表达式的转换方式大体保持不变,只是将以前使用filter的地方全部替换为withFilter方法。

[b][size=large]结语[/size][/b]:可以看到Scala2.8成功解决了之前Scala中存在的一些问题,使得Scala语言变得更加优雅、强大。你还在等待Java7的闭包吗?赶紧去尝试Scala2.8吧^_^
【实战项目开发技术分享】ROS1.0、ROS 2.0和CyberRT开源通信框架对比 随着机器人和自动驾驶技术的飞速发展,开源通信框架在机器人、自动驾驶行业扮演着重要的角色。ROS1.0是一个广泛应用于机器人领域的开源框架,ROS 2.0是其改进版本,而CyberRT是Baidu Apollo自动驾驶平台的通信框架。ROS和ROS 2.0都注重灵活性和共享性,适用于各种机器人应用。CyberRT则专注于实时性和高性能,适用于自动驾驶等对实时性要求较高的场景。选择适合的框架取决于具体应用需求和开发者的偏好。 阅读详情

相关推荐

TMS320F280049C 学习笔记21 交叉开关 Crossbar (X-BAR)

简单介绍了X-BAR。

whyorwhnt的专栏 2万+

scala函数 for循环

scala中使用def定义一个函数: 无返回值的函数 def add(a:Int , b:Int){        println(a + b)      } 有返回值的函数 def add(a:Int , b:Int) :Int = { //需要有具体返回值时要添加“=”        a + b;  //scala默认返回最后一行的值      } for循环

qa38113202的博客 467

Robosuite与Robomimic:机器人学习的黄金搭档

本文深入探讨了Robosuite与Robomimic这对机器人学习的黄金组合,详细介绍了如何利用Robosuite进行物理仿真和任务环境构建,以及Robomimic在演示数据处理和离线学习算法实现中的应用。通过实际案例和代码示例,展示了从仿真环境搭建到模型训练的全流程,帮助研究人员高效开展机器人学习实验。

weixin_29178069的博客 416

scala 从2.7 到 2.8的一些方法变化

Scala2.8的Beta终于发布了,变化可是真大啊,除了[url=http://www.scala-lang.org/node/4587]官方提到[/url]的外,在一些Object的方法也有不少的小改动,在此将碰到的简单罗列一下: [list] [*]Source.getLines,增加了缺省换行的参数,因此调用需要加上括号,.getLines() [*]Array更像Java的Ar...

lovec的专栏 178

别再只调电位器了!用单片机PWM控制LM317输出电压,精度和玩法都多了

本文探讨了如何利用单片机PWM控制LM317输出电压,替代传统的电位器调节方案。通过PWM信号的有源滤波和运放处理,实现了更高精度(±5mV)、更好温度稳定性(0.01%/°C)的数控稳压电源设计,支持远程控制和可编程曲线输出,为经典电路注入数字化智能。

weixin_29164497的博客 360

分析以太网帧结构_100G以太网接口调试初体验

是的,标题没有多敲一个“0”,明人不说暗话,就是在FPGA上实现100G以太网接口设计。正好参与了实验室某项目中的100G接口的调试,早想写个专栏文章了,由于调试过程中发现了一些硬件问题,导致迟迟没有往前推进,现在问题解决了之后可以简单分享一下100G以太网接口的调试初体验了~(好像DDR4读写测试系列文章还没搞完 )这篇初体验暂时不分多个章节了,基本设计流程与之前发布的“10G以太网接口”系列文...

weixin_39574050的博客 1603

【Scala入门】Scala中的For循环

import scala.collection.immutable /** * For循环 */ object ForDemo { def main(args: Array[String]): Unit = { //定义一个数组变量,to后的第一个参数为末位置(包含该值),第二个参数为步长(负数为递减) val arr1 = 1 to (10, 2) val ...

fuyun6363的博客 658

手把手教你学Simulink--基于电能质量与无功补偿的场景实例:统一电能质量调节器(UPQC)的联合控制仿真

在现代电力系统中,电能质量问题有源电力滤波器(APF)→ 治理谐波与无功动态电压恢复器(DVR)→ 补偿电压暂降/暂升静止无功发生器(SVG)→ 无功补偿与电压支撑而统一电能质量调节器(Unified Power Quality Conditioner, UPQC)是一种集串联补偿与并联补偿于一体的全能型电能质量治理装置✅ 电压类问题:暂降、暂升、不平衡、闪变✅ 电流类问题:谐波、无功、三相不平衡✅ 实现双向有功交换(储能型)串联单元(DVR功能):串联于线路,控制电源侧电压质量并联单元。

MHD0815的博客 240

3D数字化研发管理方案选型:核心维度与实战框架

在产品研发数字化过程中,PDM/PLM作为核心基础设施,将三维模型、BOM和变更流程统一纳入受控体系,使协同评审与版本追溯成为可能。选型工作的首要任务并非比较厂商,而是从业务痛点出发,对需求、预算、集成等约束条件进行诊断。随后围绕业务匹配度、CAD集成深度、实施服务等维度加权评估,并通过RFP与POC验证真实场景。这套方法论能帮助研发管理者降低选型风险,平稳落地实施。

weixin_34239169的博客 349

基于YOLOv10深度学习的花生种子霉变检测系统

YOLO(You Only Look Once)是当前最先进的目标检测算法之一,具有快速、精准的特性。YOLOv10是YOLO系列的最新版本,相较于之前的版本,YOLOv10在特征提取、模型精度和速度上都有了显著的提升。YOLOv10采用了更深的卷积神经网络、更多的跨层特征融合方法,使得其在不同尺寸物体的检测和复杂场景的处理上都表现出了优异的性能。YOLOv10特别适合应用在需要快速处理并检测大量图像的任务中,如花生种子霉变检测等,能够实现精准、高效的检测。

2201_76125393的博客 649

华为 MetaERP 财务模块的核心业务对象,按子模块与架构维度分类,以表格呈现,适配架构设计与实施落地

华为MetaERP财务模块基于4A架构(业务/应用/数据/技术)与TOGAF框架,实现业财一体化与全球合规。业务架构涵盖组织模型与核心流程,应用架构支撑财务操作,数据架构确保数据一致性,技术架构提供高性能技术底座。模块覆盖总账、应收应付、资产等子模块,支持多组织、多币种、多准则核算,通过实时会计引擎实现"交易即核算"。4A架构与TOGAF框架对应,实现业务能力、应用组件、数据模型与技术栈的深度融合,为华为全球化财务核算提供核心支撑。

金牌架构师 444

scala表达式

Scala中的yield的主要作用是记住每次迭代中的有关值,并逐一存入到一个数组中。- 表达式一般是一个语句块,可包含一条或者多条语句,多条语句使用“{}”包含,语句间以“;1.表达式有返回值,语句被执行。表达式一般是一个语句块,执行后,返回一个值。if-else表达式有值,这个值就是跟在if或者else之后的表达式的值。在Scala中有for循环和while循环,用for循环比较多。说明:当条件表达式为ture 时,就会执行 { } 的代码。说明:当条件表达式成立,即执行代码块1,否则执行代码块2.

HYSliuliuliu的博客 9821

高通平台 Android T 蓝牙技术全解析:架构、代码与实现原理

协议栈、配置文件和服务都运行在一个独立的用户空间进程。

专业开发者的博客,一个从事Android WiFi和蓝牙的工程师 101

Scala教程(二十)For循环模式匹配与表达式

For循环模式匹配与表达式; 1.1 模式匹配下的For循环; 1.2 模式匹配下的赋值语句; 1.3 模式匹配下的提取器; 1.4 Scala中For表达式; 1.5 For表达式查询过滤;

yuan_xw的专栏 2356

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Scala语法(scala条件表达式__for循环__while循环)

条件表达式 条件表达式就是if表达式。scala条件表达式的语法和Java一样。 有返回值的if 参考代码: scala> val sex = "male" sex: String = male ​ scala> val result = if(sex == "male") 1 else 0 result: Int = 1 与Java不一样的是 在scala中,条件表达式也是有返回...

写的不好之处,请指教 5504

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

在Scala和Java 8中Lambda表达式这么用,你知道么

最近几年Lambda表达式风靡于编程界. 很多现代编程语言都把它作为函数式编程的基本组成部分. 基于JVM的编程语言如Scala,Groovy还有Clojure把它们作为关键部分集成在语言中.现在Java8也加入了它们的行列. 有趣的是,对于JVM来说,Lambda表达式是完全不可见的,并没有匿名函数和Lamada表达式的概念,它只知道字节码是严格面向对象规范的.它取决于语言的作者和它的编译器在规范限制内创造出更新,更高级的语言元素. 我们第一次接触它是在我们要给Takipi添加Scala支持的时...

weixin_46577306的博客 1088

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Scala语法介绍(五):scala条件表达式-for循环-while循环

条件表达式 条件表达式就是if表达式。scala条件表达式的语法和Java一样。 有返回值的if 参考代码: scala> val sex = "male" sex: String = male ​ scala> val result = if(sex == "male") 1 else 0 result: Int = 1 与Java不一样的是 在scala中,条件表达式也是有返回...

4759

Scala 2.12将只支持Java 8

根据近期Scala路线图所公布的信息来看,Scala从版本2.12开始,只能运行在Java 8及之后的版本上。InfoQ找到了Adriaan Moors(Typesafe的Scala技术主管)和Json Zaugg(Typesafe工程师),了解到更多关于这个改动的内容,以及Scala将如何利用Java 8的lambda表达式的细节。\u0026#xD;\u0026#xD;InfoQ:做出这个改动...

cpongo011702 1083

黑猴子的家:Scala for 表达式

Scala 也为for 循环这一常见的控制结构提供了非常多的特性,这些for 循环的特性被称为for 推导式(for comprehension)或for 表达式(for expression)。 1、遍历array1 里面所有的元素 val array1 = Array(1,"2","3",true) for (x <- array1){ //println(x + " -&gt...

黑猴子的博客 437

scala java8_λ表达式之争:Scala vs Java8

最近几年Lambda表达式风靡于编程界。很多现代编程语言都把它作为函数式编程的基本组成部分。基于JVM的编程语言如Scala、Groovy及Clojure把它作为关键部分集成在语言中。而如今,(最终)Java 8也加入了这个有趣的行列。Lambda表达式最有意思的地方在于,在JVM的角度来看它是完全不可见的。在JVM中没有匿名函数或Lambda表达式的概念。JVM唯一知道是字节码。字节码是一个严格...

weixin_34581086的博客 232

scala java8_Java 8 vs. Scala(一): Lambda表达式

【编者按】虽然 Java 深得大量开发者喜爱,但是对比其他现代编程语言,其语法确实略显冗长。但是通过 Java8,直接利用 lambda 表达式就能编写出既可读又简洁的代码。作者 Hussachai Puripunpinyo 的软件工程师,作者通过对比 Java 8和 Scala,对性能和表达方面的差异进行了分析,并且深入讨论关于 Stream API 的区别,本文由 OneAPM 工程师编译整理...

weixin_35601445的博客 323

Lambda表达式用法大比较: Scala和Java 8

最近几年Lambda表达式风靡于编程界. 很多现代编程语言都把它作为函数式编程的基本组成部分. 基于JVM的编程语言如Scala,Groovy还有Clojure把它们作为关键部分集成在语言中.现在Java8也加入了它们的行列. 有趣的是,对于JVM来说,Lambda表达式是完全不可见的,并没有匿名函数和Lamada表达式的概念,它只知道字节码是严格面向对象规范的.它取决于语言的作者和它的编译器在规范限制内创造出更新,更高级的语言元素. 我们第一次接触它是在我们要给Takipi添加Scala支持的时候..

Java架构师联盟 1129

scala支持java8_Java8和Scala中的Lambda表达式

Java8 终于要支持Lambda表达式!自2009年以来Lambda表达式已经在Lambda项目中被支持。在那时候,Lambda表达式仍被称为Java闭包。在我们进入一些代码示例以前,先来解释下为什么Lambda表达式在Java程序员中广受欢迎。1、为什么使用Lambda表达式Lambda表达式通常使用在图形用户界面(GUI)的开发中。一般来说,GUI编程将程序行为和事件做连接。比如,当用户按下...

weixin_34585343的博客 171

scala 模式匹配支持正则吗_16.scala的For 表达式

Scala 提供一个轻量级的标记方式用来表示 序列推导。推导使用形式为 for (enumerators) yield e 的 for 表达式,此处 enumerators 指一组以分号分隔的枚举器。一个 enumerator 要么是一个产生新变量的生成器,要么是一个过滤器。for 表达式在枚举器产生的每一次绑定中都会计算 e 值,并在循环结束后返回这些值组成的序列。看下例:case c...

weixin_30030437的博客 85

scala lambda_编译Lambda表达式:Scala与Java 8

scala lambda 在过去的几年中,Lambda表达式席卷了编程世界。 大多数现代语言都将它们用作函数式编程的基本部分。 基于JVM的语言(例如Scala,Groovy和Clojure)已将它们集成为该语言的关键部分。 现在,Java 8(终于)加入了这个乐趣。 Lambda表达式的有趣之处在于,从JVM的角度来看,它们是完全不可见的。 它不知道什么是匿名函数或Lambda表达式。...

254

编译Lambda表达式:Scala与Java 8

在过去的几年中,Lambda表达式席卷了编程世界。 大多数现代语言都将它们用作函数式编程的基本部分。 基于JVM的语言(例如Scala,Groovy和Clojure)已将它们集成为该语言的关键部分。 现在,Java 8(最终)加入了这个乐趣。 Lambda表达式的有趣之处在于,从JVM的角度来看,它们是完全不可见的。 它不知道什么是匿名函数或Lambda表达式。 它只知道严格的OO规范...

277
上一篇: Sun在Devoxx2009上宣布Java7中将加入FCM(闭包)
下一篇: Projecteuler 169
JavaSxy
博客等级 码龄21年 1粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值