きっかけ
大学でプログラムならまずこれを勉強しろと言われ、文字通り1+1しか書けず挫折したScalaを改めて触ってみたいと思う。
少しばかりpythonで簡単な処理は書けるようになったので、今なら理解できるかどうか試してみたくなったのが動機。
ちなみに、Javaは全く触ったことがありません。
コップ本を片手に頑張ります!
理解がおかしかったらご指摘ください。
占い
Randomライブラリを使う。
import scala.util.Random
def fortune(): String = {
val fortuneNumber: Int = Random.nextInt(3)
if ( fortuneNumber == 0 ) "大吉"
else if ( fortuneNumber == 1 ) "吉"
else "凶"
}
println(fortune())
Randomモジュールを使うことで乱数を扱うことができる。
nextIntメソッドは0から"引数で指定した値 -1"の整数をランダムに出力する。
今回は3パターン出してみたので、nextInt(3)で0, 1, 2が生成される。
あとは、0=大吉、1=吉、2=凶に振り分けて条件分岐。
scalaはelif使えないんですね。
もう少し簡潔に書く
このままだと、出力候補が増えれば増えるほどelse if文が増えるのでイケてない。
じゃんけんみたいな処理だと、数値->文字列の置き換え処理が必要で、非常にイケてないプログラムになることが想像できる。
Randomライブラリにsuffleメソッドがあった。これで返したい値をリスト化し、さらに要素をシャッフルすることが可能。
import scala.util.Random
val fortune = List("大吉", "吉", "凶")
val result = Random.shuffle(fortune).apply(0)
println(result)
ちなみに、shuffle関数を今回用に自分で作るとこんな感じ。
import scala.util.Random
def shuffle(list: List[String]): String = {
list(Random.nextInt(list.length + 1))
}
val fortune = List("大吉", "吉", "凶")
val result = shuffle(fortune)
println(result)
頭の整理:配列とリスト
配列とリスト
Pythonだとメソッドを呼び出すときは次のように[]を使った。
配列のデータに直接触りに行って参照しているイメージ。
>>> test = ["one", "two", "three"]
>>> test[0]
'one'
>>>
Scalaはapplyという関数で呼び出しているらしい。
関数なので、指定すべき要素は引数扱いになる。だから()で呼び出す。
scala> test(0)
val res1: String = one
scala> test.apply(0) //同じこと
val res2: String = one
配列とリストの違い
- 配列:要素は全て同じ型
- リスト:要素の型はそれぞれ違っていて良い
架空の勇者の情報として、「名前、レベル、魔王討伐状況」を配列、リストにそれぞれ入れることを試す。
※辞書で書けばいい話だけど、今回は練習として。
scala> val testArray = new Array[String](3) //これは配列。そもそもこう書かないと通らない。
val testArray: Array[String] = Array(null, null, null)
scala> testArray(0) = "勇者"
scala> testArray(1) = 20
^
error: type mismatch; //当然型エラー
found : Int(20)
required: String
scala> testArray(2) = false
^
error: type mismatch; //当然型エラー
found : Boolean(false)
required: String
scala> val testList = ("勇者", 20, false) //これはリスト
val testList: (String, Int, Boolean) = (勇者,20,false)
リストの定義
先ほどのListの定義を下記のように書くと、エラーが出る。
scala> val test = new List("test")
^
error: class List is abstract; cannot be instantiated ^
scala> val test = new List("test": String)
^
error: class List is abstract; cannot be instantiated
コップ本にはこう書いてある。
List.apply()はscala.Listコンパニオンファクトリーメソッドとして定義されているので、new Listと書く必要はない。
"ファクトリーメソッド"とあるから、
List.apply()の処理で作られるモノが具体的なオブジェクトだから、作り方なListクラスはインスタンスにはできないということ?
飲み込むのに時間がかかりそうなので、これは次の機会に。