反覆一個
容器(Container)內容, 在 Java 我們大多數的時間使用者 for 迴圈來處理, 事實上 Scala 在這方面更優於 Java,
- Scala 善用本身的類型推論(Type Inference)本能來簡化您的思維
- Scala 除了讓您可以使用傳統的 for 迴圈, 更可以使用俱 FP(函數編程) 的技巧來迭代容器內容.
for (arg <- args)
for循環並不是語法,而是被定義為稱作 for-comprehension 的語法蜜糖,最後被轉換成 map 和 filter 等方法的組合。
fish 在此被視為創建一個 val 而不是 var, 在 <- 右邊是一個連績值 產出器表達式(Generator Expression), 每次都連績性產出一個 val 來進行初始化,
for (fish <- 1 to 5) println(fish)
for (fish <- 1 to 5)
println(fish)
Examples
Iterate with foreach
and for
Although you may not have realized it, when you wrote the while loops in the previous step, you were programming in an imperative style.
In the imperative style, which is the style you would ordinarily use with languages like Java, C++, and C, you
give one imperative command at a time, iterate with loops, and often mutate state shared between different functions
or methods.
Scala enables you to program imperatively, but as you get to know Scala better, you'll likely often find yourself
programming in a more functional style.
In fact, one of the main aims of the Scalazine will be to help you become as competent at functional programming as you are
at imperative programming, using Scala as a vehicle.
One of the main characteristics of a functional language is that functions are first class constructs, and that's
very true in Scala. For example, another (far more concise) way to print each command line argument is:
args.foreach(arg => println(arg))
In this code, you call the foreach
method on args
, and pass in a function. In this case, you're
passing in an anonymous function (one with no name), which takes one parameter named arg
.
The code of the anonymous function is println(arg)
.
If you type the above code into a new file named pa.scala
, and execute with the command:
scala pa.scala Concise is nice
You should see:
Concise
is
nice
In the previous example, the Scala
interpreter infers type of arg
to be String
, since String
s are what the array on which you're calling
foreach
is holding. If you'd prefer to be more explicit, you can mention the type name, but when you do you'll
need to wrap the argument portion in parentheses (which is the normal form of the syntax anyway). Try typing this into
a file named epa.scala
.
args.foreach((arg: String) => println(arg))
Running this script has the same behavior as the previous one. With the command:
scala epa.scala Explicit can be nice too
You'll get:
Explicit
can
be
nice
too
If instead of an explicit mood, you're in the mood for even more conciseness, you can take advantage
of a special case in Scala. If an anonymous function consists of one method application that takes a single argument,
you need not explicitly name and specify the argument. Thus, the following code also works:
args.foreach(println)
To summarize, the syntax for an anonymous function is a list of named
parameters, in parentheses, a right arrow, and then the body of the
function. This syntax is illustrated in Figure 1.

Figure 1. The syntax of a Scala anonymous function.
Now, by this point you may be wondering what happened to those trusty
for loops you have been accustomed to using in imperative languages
such as Java. In an effort to guide you in a functional direction, only
a functional relative of the imperative
for
(called a for comprehension) is available in Scala. While you won't see their full power and expressiveness
in this article, we will give you a glimpse. In a new file named forprintargs.scala
, type the following:
for (arg <- args)
println(arg)
The parentheses after the for
in this for comprehension contain arg <- args
. To the left of the <-
symbol, which
you can say as 「in」, is a declaration of a new \@val@ (not a \@var@) named arg
. To the right of <-
is the familiar args
array. When
this code executes, arg
will be assigned to each element of the args
array and the body of the for, println(arg)
,
will be executed. Scala's for comprehensions can do much more than this, but this simple form is similar in functionality to
Java 5's:
// ...
for (String arg : args) { // Remember, this is Java, not Scala
System.out.println(arg);
}
// ...
or Ruby's
for arg in ARGV # Remember, this is Ruby, not Scala
puts arg
end
When you run the forprintargs.scala
script with the command:
scala forprintargs.scala for is functional
You should see:
for
is
functional