Scala プログラミング

[Home]

コンパイルと実行

ソースを直接実行する

scala ソースを直接、実行することができる。"Hello, World!" と表示するだけのプログラム(下記)の実行例を示す。

println("Hello, World!")

次のように scala コマンドを使って直接ソースを実行する。

$ scala Hello.scala
Hello, World!

ソースをコンパイルして実行する

scala コンパイラ scalac を使いソースをコンパイルすると .class ファイルができる。これを scala コマンドを使って実行する。

$ scalac Hello.scala
$ scala Hello
Hello, World!

 

main とコマンドライン引数

main を含むクラスには3つの形式がある。その際、クラス名とファイル名は同じである必要はなくファイルに複数のクラスを定義することもできる。3つの形式とは

  1. いきなりメインプログラムのコードを書いたもの
  2. Application Trait を使う形式
  3. Java の main と同じような形式

いきなりメインプログラムのコードを書いたものの例

Python のような他のスクリプト言語のようにいきなりコードを書くことができる。

println("Hello, scala !")

上のプログラム(ファイルは Hello2.scala) の実行例

$ scala Hello2.scala
Hello, scala !

コマンドライン引数を参照するには args を使用する。

println("Hello, scala !")
if (args.length > 0) {
  println("Parameter = " + args(0))
}

Application Trait を使う形式の例

App Trait を Mixin する。

object Main extends App {
  Console.println("Hello scala")
}

上のプログラム(ファイルは Main.scala) の実行例。この場合、一度コンパイルして .class を実行する必要がある。

$ scalac Main.scala
$ scala Main
Hello scala

コマンドライン引数を使う場合は、args 配列を参照する。

object Args extends App {
  if (args.length > 0) {
     println("Hello scala! " + args(0));
  }
  else {
     println("Hello scala! No parameters.");
  }
}

Java の main と同じような形式の例

object (静的なクラスと同等) に main を定義する。

object Hello {
  def main(args: Array[String]) {
    println("Hello, World!");
  }
}

実行例。Hello.scala はソースファイル名。

$ scala Hello.scala
Hello, World!

 

基本構文

IF ELSE

IF ELSE 構文は Java とだいたい同じである。ただ、switch 構文はない。代わりにパターンマッチを使用する。

if (args.length == 0) {
  println("No parameters.")
}
else if (Integer.parseInt(args(0)) > 0) {
  println("Plus")
}
else if (Integer.parseInt(args(0)) < 0) {
  println("Minus")
}
else {
  println("Zero")
}

LOOP

繰り返し構文には while, do while, for がある。for は for each のみである。

while

var i = 10

while (i > 0) {
  println(i)
  i -= 1
}

do while

ar i = 10

do {
  i -= 1
  println(i)
} while (i > 0)

for

for (i <- 0 to 9) {
  println(i)
}

関数

関数は def を使って定義する。

def add(a:Int, b:Int):Int = { a + b }

println(add(1, 2))

クロージャ

クロージャは => 演算子を使って定義する。

var defclo1 = (x:Double) => { x * x }

println(defclo1(3))

基本型

scala は ruby などと異なり明確にデータ型を指定できる。

意味
Byte長さ 8 ビットの符号付整数
Short長さ 16 ビットの符号付整数
Int長さ 32 ビットの符号付整数
Long長さ 64 ビットの符号付整数
Float長さ 32 ビットの IEEE 754 浮動小数点数
Double長さ 64 ビットの IEEE 754 浮動小数点数
Char16 ビットの Unicode 文字
String文字列 (Char の並び)
Booleantrue または false
Unit値がないことを意味する。Java の void 相当。
Null参照先がないことを意味する。Java の null 相当。
NothingNull を含む任意の型になれる値。
AnyNull を含まない任意の型。Java の Object 型相当。
AnyRefAny の参照バージョン。すべて(任意)の参照型。

配列

配列は Array クラスのインスタンスである。要素は [] でなく () で指定する。

object Main extends App {
  Console.println("Scala's Array")
  val a1 = new Array[Int](5)
  a1(0) = 0
  a1(1) = 10
  a1(2) = 20
  a1(3) = 30
  a1(4) = 40

  for (i <- 0 to 4) {
    Console.println(a1(i))
  }
}

クラスとオブジェクト

クラスの定義には予約語 class を使用する。

// クラスの定義
class Point {
  var x: Double = 0.0
  var y: Double = 0.0

  def norm(): Double = {
    Math.sqrt(x * x + y * y)
  }
}

// インスタンス化
val p = new Point()
p.x = 1.0
p.y = 2.0

// フィールドとメソッドの使用
println(p.x)
println(p.y)
println(p.norm())

メンバーを特定の値で初期化するには、クラス名の後に () でその値を指定する。複数コンストラクタを使う場合は、this を使用する。

// クラスの定義
class Point(x0: Double, y0: Double) {
  var x: Double = x0;
  var y: Double = y0;

  // 初期値を省略したときのコンストラクタ
  def this() {
    this(0.0, 0.0)
  }

  // メソッド
  def norm(): Double = {
    Math.sqrt(x * x + y * y)
  }
}

// インスタンス化
val p = new Point(2.0, -1.0)
val q = new Point()

// メソッドの呼び出し
println(p.norm())
println(q.norm())

メインプログラムを定義するとき、object を使用するが、これは static クラスに相当する。

object Origin {
  val x0: Double = 0.0
  val y0: Double = 0.0
}

println(Origin.x0)
println(Origin.y0)

パッケージ

パッケージは package で定義する。次の例は、com.name1 と com.name2 パッケージに同じ名前のクラス Class1 を定義して使用するものである。

Name1.scala

package com.name1 {
  class Class1 {
    val name: String = "com.name1.Class1"

    override def toString(): String = {
      return name
    }
  }
}

Name2.scala

package com.name2 {
  class Class1 {
    val name: String = "com.name2.Class1"

    override def toString(): String = {
      return name
    }
  }
}

test.scala

import com.name1
import com.name2

object Test {
  def main(args:Array[String]) {
    val a = new com.name1.Class1
    val b = new com.name2.Class1

    println(a)
    println(b)
  }
}

ビルドは次のようにして行う。

scalac Name1.scala scalac Name2.scala scalac -classpath com.name1:com.name2:. test.scala

実行は次のようにする。

scala Test

Trait

Trait は Java の抽象クラスに近い。

trait1.scala

package my.traits {
  trait T1 {
    def append(s: String): String
  }
}

Class1.scala

import my.traits

class Class1 extends my.traits.T1 {
    protected var str: String = ""

    def append(s: String): String = {
      str += s
      return str
    }

    def get(): String = { return str }
}

Test.scala

object Test extends App {
  val o = new Class1
  o.append("my.")
  o.append("traits.")
  o.append("Class1")
  println(o.get())
}

上のソースのビルド方法を示す。

scalac trait1.scala
scalac -cp .:com.traits.T1 Class1.scala
scalac -cp .:Class1 Test.scala

例外処理

Java と異なり catch 句内で例外の判別を行う。

import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException

try {
  val f = new FileReader("somefile")
}
catch {
  case ex: FileNotFoundException => {
    println("FileNotFoundException")
  }

  case ex: IOException => {
    println("IOException")
  }
}

 

[TOP]