プログラムは動かさないと始まらない!最初は動かなくて嵌るかもしれない。
でも自分の手を動かして書いたソースが動き始めるともっと書きたくなってくるはず!
手を動かすことに喜びを感じたら、プログラミングの才能があるね!
最初はうまく書けなくても良いんだよ。
とにかくソースを書いて動かしてみようぜ!!
事前準備
まずは動作環境が必要だ。Windows7しか想定してない。すまん。
JavaとScalaのインストール・ダウンロード
以下のバージョンでダウンロードしインストールする。
-
Java SE 7u21
-
scala-2.10.1
環境変数の設定
-
JAVA_HOME
- JAVA_HOME=C:\Program Files\Java\jdk1.7.0_21
-
SCALA_HOME
- SCALA_HOME=C:\Program Files\scala
以上!
Hello Worldを出力してみる
新しい言語を始める際にまずやることは"Hello World"の出力。
もちろんここでも基本に忠実に"Hello World"をやるよ。
今回の全てのソースのInputとOutput。
-
Input
- なし
-
Output
- コンソールに"Hello World"と出力
ソース
object HelloWorld{
def main(args: Array[String]){
if(args.size == 0) {
val strs = Array("Hello", "World")
output(strs)
} else {
printf("Invalid args.")
}
}
def output(strs: Array[String]):Unit = {
for(str <- strs) {
printf("%s ", str)
}
}
}
上記を"HelloWorld.scala"というファイル名で保存だ。
そしてコンソールでscala HelloWorld.scala
とコマンドを叩こう。
"Hello World"が出力されるよ!
$ scala HelloWorld.scala
Hello World
ソースの説明
動いたらどうなっているか気になってこないかな?
ここから説明するよ!!
objectキーワード
シングルトンオブジェクトの定義。Javaとは違い静的(static)な扱いがない。
Scalaの世界では全てがオブジェクトとなる。
複数のインスタンスを必要としない場合に使用する。
シングルトンオブジェクトとは、インスタンスが1つしか存在しない
オブジェクトのことである。
例えば今回のソースのように、実行の起点となるmainメソッドには
複数のインスタンスは必要ない。そのためobject HelloWorld
と
宣言することにより、HelloWorldシングルトンオブジェクトの
mainメソッドという形にしている。
代表的なキーワード
- case
- class
- match
- return
- trait
mainメソッド
objectキーワードで記述したが、実行の起点となるメソッド。
scalaのソースを動かしたい場合に使用する。通常は以下の構文となる。
object オブジェクト{
def main(args: Array[String]): Unit = {
処理
}
}
: Unit =
は省略可能である。Unitとは戻り値がない場合の宣言。
Javaではvoidにあたる。
オブジェクトとクラス、インスタンス、フィールド、メソッド
オブジェクト指向の核となる概念。Javaの世界では以下のように考える。
- クラス = 型。class宣言する。
- インスタンス = 型を具現化したモノ。newする。newする毎にメモリが確保される。
- オブジェクト = クラスでありインスタンスでもある。ソース上ではObjectクラス以外、明示的なオブジェクトは現れない。
- フィールド = 状態を表す。インスタンス毎に値が変わることが多い。
- メソッド = 処理。何をするかを記述する。
言葉だけじゃわかりにくいから図を作ってみた。
車で考えてみるよ。
クラスは 車 だ。車には色んな属性があるけど、今回は 車種 だけとする。
これがフィールドだ。
では車種を決めてみよ。例えば バス、 スポーツカー にしてみるよ。
するとインスタンスができるんだ。
車ができること、例えば 走る だ。これがメソッド。
インスタンス化したバス・スポーツカーももちろん 走る ことができる。
違いはないかもしれないし、速さに違いがあるかもしれない。
どうわかったかな?
ところでオブジェクトはって?
オブジェクトは 車 であり、 バス であり スポーツカー であるんだよ。
if文
分岐を表す。条件はtrue, falseで評価する。
if(args.size == 0) {
val strs = Array("Hello", "World")
output(strs)
} else {
printf("Invalid args.")
}
上記では、条件args.size == 0
を評価し、trueの場合は直後の{}内の処理を実行する。
falseの場合はelse直後の{}内の処理を実施する。
ここでargs.size
は配列argsのサイズである。
defキーワード、for式、printf関数
def output(strs: Array[String]):Unit = {
for(str <- strs) {
printf("%s ", str)
}
}
defキーワード
メソッド宣言。下記の構文が通常の形となる。
def メソッド名(引数リスト): メソッドの戻り値の型 = {}
for式
繰り返しを表す。
このfor式は、文字列配列から1要素ずつ順番に抜き出し、
printf
の引数としている。<-
はジェネレータと呼ぶ。
printf関数
フォーマットを指定し文字列を出力する。第1引数の%s
の%s
を、
第2引数の値で置換して出力する。
valキーワード
イミュータブル(値を変えることができない)変数を定義する。
val strs = Array("Hello", "World")
上記のように変数strs
に一度値(配列)を設定すると、
strs
に別の値を入れ直すことはできない。Javaのfinal
と同等。
Scalaらしくリファクタリング
HelloWorld.scalaはJavaのソースとほとんど変わらないので、
output
メソッドをもう少しScalaらしくしてみたから確認してみよう!
これでもOutputは変わらないでしょ?
リファクタリング後のソース
object HelloWorld{
def main(args: Array[String]){
if(args.size == 0) {
val strs = Array("Hello", "World")
output(strs)
} else {
printf("Invalid args.")
}
}
def output(strs: Array[String]){
strs.foreach(printf("%s ", _))
}
}
変更点の説明
細かい変更は自分で確認してね!大きな変更点だけ書くよ。
foreachキーワード
これも繰り返しを表す。引数に関数を渡すことができる。
def output(strs: Array[String]){
strs.foreach(printf("%s ", _))
}
ここでは、printf("%s ", _)
という関数を引数として渡している。
プレイスホルダー_
が配列strsの要素を表す。
配列strsから1要素ずつ取り出すたびにプレイスホルダー_
に
要素の値を設定し、引数の関数を呼び出す。
まとめ
基本のHelloWorldだけど、キーワードを何個か入れ込んだから、
盛り沢山だったかな。このソースをいじって色々試してみようぜ!
今回のサンプルソースを通しScalaのソースを実際に動かすことで、
体で感じてくれたかな?