Edited at

第1章:Hello Worldから始めるScala

More than 5 years have passed since last update.

プログラムは動かさないと始まらない!最初は動かなくて嵌るかもしれない。

でも自分の手を動かして書いたソースが動き始めるともっと書きたくなってくるはず!

手を動かすことに喜びを感じたら、プログラミングの才能があるね!

最初はうまく書けなくても良いんだよ。

とにかくソースを書いて動かしてみようぜ!!


事前準備

まずは動作環境が必要だ。Windows7しか想定してない。すまん。


JavaとScalaのインストール・ダウンロード

以下のバージョンでダウンロードしインストールする。


環境変数の設定



  • 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"と出力




ソース


HelloWorld.scala

    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クラス以外、明示的なオブジェクトは現れない。

  • フィールド = 状態を表す。インスタンス毎に値が変わることが多い。

  • メソッド = 処理。何をするかを記述する。

object_illust.png

言葉だけじゃわかりにくいから図を作ってみた。

車で考えてみるよ。

クラスは だ。車には色んな属性があるけど、今回は 車種 だけとする。

これがフィールドだ。

では車種を決めてみよ。例えば バススポーツカー にしてみるよ。

するとインスタンスができるんだ。

車ができること、例えば 走る だ。これがメソッド。

インスタンス化したバス・スポーツカーももちろん 走る ことができる。

違いはないかもしれないし、速さに違いがあるかもしれない。

どうわかったかな?

ところでオブジェクトはって?

オブジェクトは であり、 バス であり スポーツカー であるんだよ。


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は変わらないでしょ?


リファクタリング後のソース


HelloWorld1.scala

    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のソースを実際に動かすことで、

体で感じてくれたかな?