专业编程基础技术教程

网站首页 > 基础教程 正文

在Scala的for表达式面前,Java简直是弟弟

ccvgpt 2024-10-12 13:42:12 基础教程 9 ℃

“旋风式”对比

在正式介绍前,先通过几个例子对Scala和Java的写法进行一个快速的比对。

1. 打印1到9

在Scala的for表达式面前,Java简直是弟弟

/* Java */
for (int i = 1; i <= 9; i++) {
  ...
}

/* Scala */
for (i <- 1 to 9) {
  ...
}

2. 打印1到9中的奇数

/* Java */
for (int i = 1; i <= 9; i++) {
  if (i % 2 == 0) {
    continue
  }
  ...
}

/* Scala */
for (i <- 1 to 9
    if i % 2 != 0) {
  ...
}

这种把if放在for中的写法称为“守卫”(guard)。

3. 多层嵌套(打印9*9乘法表)

/* Java */
for (int i = 1; i <= 9; i++) {
  for (int j = 1; j <= 9; j++) {
    ...
  }
}

/* Scala */
for (i <- 1 to 9;
    j <- 1 to 9) {
  ...
}

4. 多层嵌套组合多个守卫条件(打印9*9乘法表中奇数*奇数的部分)

/* Java */
for (int i = 1; i <= 9; i++) {
 	if (i % 2 == 0) {
    continue
  }
  for (int j = 1; j <= 9; j++) {
    if (j % 2 == 0) {
      continue
    }
    ...
  }
}

/* Scala */
for (i <- 1 to 9 if i % 2 != 0;
    j <- 1 to 9 if j % 2 != 0) {
  ...
}

for的本质

在Scala中,for其实不仅仅是循环,它的本质,是一个非常“甜”的语法糖。在之前的一篇文章《Optional的正确用法,只知道isPresent()你可就out了》里,我们讲到Optional或者Monad的高级玩法是flatMap。

再来回忆下:

val bmi = weight
        .flatMap(w -> height.map(h -> w / (h * h)))

其中weight和height都是Option,实际上,我们可以用更易读一点的语法:

val bmi = for (h <- height; w <- weight) yield { h -> w / (h * h) }

嘿嘿,是不是很赞?

实际上Scala的for会被转化为等价的map、filter等操作。

比如:

for (x <- c1; y <- c2; z <-c3) {...}

会被转化为

c1.foreach(x => c2.foreach(y => c3.foreach(z => {...})))

比如:

for (x <- c1; y <- c2; z <- c3) yield {...}

会被转化为

c1.flatMap(x => c2.flatMap(y => c3.map(z => {...})))

比如:

for (x <- c; if cond) yield {...}
                             
会被转化为
                             
c.filter(x => cond).map(x => {...})

那么,你学废了么?

Tags:

最近发表
标签列表