連載
» 2012年03月02日 00時00分 UPDATE

スケーラブルで関数型でオブジェクト指向なScala入門(2):Scalaプログラミングで知っておきたい基本構文まとめ (1/2)

Scalaの特徴を紹介し、基本構文や関数、クラスなど、Scalaの基本的な機能について解説する入門連載

[中村修太,クラスメソッド株式会社]

REPLを使ってScalaの文法を覚えよう

 前回の連載第1回記事「EclipseでScalaプログラミングを始めるための基礎」では、Scalaの特徴についての解説から始まり、Scalaのインストール、そしてScalaプログラムを記述してREPLScala IDE for Eclipse(以下、Scala IDE)での動作を確認してみました。Scalaプログラミングを始めるための準備ができたので、いよいよ今回からScalaの文法について紹介します。

 第1回記事では、Scala標準のREPLとScala IDEで動作を確認してみました。今後本記事のサンプルコードは、どちらで確認しても問題はありませんが、対話的に実行でき、1文ごとにコードの結果が分かって便利なので、基本的にはREPLを用いて説明していきます。

 Scala IDEを使用する場合、第1回記事の『Scala IDE for Eclipseで「Hello Scala!」』を参照してプロジェクトを作成して実行してください。REPLを使用する場合は、コンソール上でscalaコマンドを実行し、REPLを起動してください。

Scalaの変数と定数

 Scalaには、何度でも代入が可能な変数(var)と初期化した後に代入ができない定数(val)があります。変数(var)はJavaでいう通常の「変数」と変わりません。定数(val)はJavaでいう「final変数/フィールド」と同じです。

Scalaの変数

 まずは、変数(var)を使ってみましょう。宣言する形式は、以下2つのいずれかにします。

var 変数名:型 = 初期値
var 変数名 = 初期値

 また、以下のようにすれば、複数の変数を一度に定義できます。

var 変数名1,変数名2 = 初期値
scala> var num:Int = 10
num: Int = 10
 
scala> num = 20
num: Int = 20
 
scala> var n1,n2,n3 = 1
n1: Int = 1
n2: Int = 1
n3: Int = 1

Scalaの定数は関数型プログラミングに重要

 次に定数(val)を使用してみましょう。宣言する形式は、先ほどのvarがvalになっただけです。ここでも、初期化後に再度、代入してみます。

scala> val message = "Hello"
message: java.lang.String = Hello
 
scala> message = "Scala"
<console>:8: error: reassignment to val
       message = "Scala"

 valで宣言されているので、再代入ができずにエラーが発生します。今後の連載で紹介しますが、関数型プログラミングをしていくうえで一度値を決めたら変更できないvalというものは重要です。現状では、変数はまずvalで宣言し、valではうまくいかなかったり冗長になってしまう場合のみ、varを使用するようにしてみてください。

Scalaの「型推論」

 また、messageを宣言している部分ではを指定していません。それにもかかわらず、「"Hello"」で初期化した段階でmessageの型が「java.lang.String」であると判断されています。

 これがScalaの持つ機能「型推論」です。このように、Scalaが型を推論できるときはScalaに任せた方が簡潔なコードが書けますが、明示的に型の宣言をした方がよい場合もあります。

 型宣言をすることでコードが予期しない型推論を防げますし、後でコードを読んだときに分かりやすいというメリットもあります。状況に応じて使い分けてください。

補足 セミコロンについて

前回のサンプルコードを見ても分かりますが、Scalaで書いたコードにはセミコロンがありません。Javaなどと同じようにセミコロンを使用することも可能ですが、通常は1行に複数の文を記述したいとき以外、あまりセミコロンを使用することはありません。


Scalaの基本データ型

 Scalaの基本データ型は、Javaのそれと同じ意味を持ちます。表1がScalaの基本データ型です。Stringを除けば、Javaのプリミティブ型(具体的な値を格納するための型)の先頭文字を大文字にしたものになっています。

型名 説明 デフォルト値
Byte 8ビット符号付き整数 0
Short 8ビット符号付き整数 0
Int 32ビット符号付き整数 0
Long 64ビット符号付き整数 0
Char 16ビット符号なしUnicode文字 '\0'
String Charシーケンス null
Float 32ビットIEEE754単精度浮動小数点数 0.0
Double 64ビットIEEE754単精度浮動小数点数 0.0
Boolean trueかfalse false
表1 Scalaの基本データ型

 「デフォルト値」というのは、varで変数を宣言したときに「_」(アンダースコア)を指定した場合の値です。宣言した時点で値が定まっていない場合、「_」で取りあえず変数を宣言しておき、後で代入できます。

scala> var longNumber:Long = _
longNumber: Long = 0

 ScalaとJavaの基本データ型における違いとしては、「Scalaにはプリミティブ型がなく、すべてオブジェクト型である」という点が挙げられます。オブジェクトなので、基本データ型の変数や数値に対してもメソッドを呼べます。

scala> var num:Int = 10
num: Int = 10
 
scala> num.toString
res0: java.lang.String = 10
 
scala> 10.toString
res1: java.lang.String = 10

補足 基本データ型の「パッケージ」

基本データ型の中で、Stringだけは「java.lang」パッケージに属しており、それ以外は「scala」パッケージに属しています。

Scalaでは、scalaパッケージとjava.langパッケージが自動的にimportされるので、そのまま使えます(※Scalaのパッケージやimportについては次回以降で紹介する予定です)。


Scalaのリテラル

 先に述べた基本データ型は、リテラル(コードに値を直接記述する書き方)として書けます。基本的なリテラルを順番に紹介していきましょう。

整数リテラル

 整数リテラルは10進数、8進数、16進数で表現できます。

種類 フォーマット
10進数 0か0以外の数字に0個以上の数字が続く 0、1、765
8進数 0の後に1個以上の数字(0〜7)が続く 011、046
16進数 0xの後に1個以上の16進数数値(0〜9、A〜F、a〜f)が続く 0xFF、0x3B
表2 整数リテラル

 有効な値は、代入する値の型によって決まります。表3が整数リテラルの範囲です。なお、Longリテラルには値の末尾に「L」か「l」を付ける必要があります。

型名 最小値 最大値
Byte -2^7 2^7-1
Short -2^15 2^15-1
Int -2^31 2^31-1
Long -2^63 2^63-1
Char 0 2^16-1
表3 整数リテラルの最小値と最大値

浮動小数点リテラル

 0の後に「.」(ピリオド)が付き、その後に0個以上の数値が続くと、「浮動小数点リテラル」です。「Floatリテラル」の場合は末尾に「F」か「f」がつきます。そうでなければ、「Doubleリテラル」と見なされます。

 Doubleの場合は、末尾に「D」か「d」を付けられます。また、指数表現を付加できます。指数の形式は、「e」または「E」の後に「+」か「-」と1個以上の数値が続きます。

scala> val float = 0.1
float: Double = 0.1
 
scala> val float = 0.1F
float: Float = 0.1
 
scala> val double = 0.1e+3f
double: Float = 100.0

ブールリテラル

 次は、ブールリテラルです。これはBoolean型に代入できる値です。trueかfalseを代入できます。

scala> val t = true
t: Boolean = true
 
scala> val f = false
f: Boolean = false

文字リテラル

 文字リテラルは、基本的には「'」(シングルクオート)で囲まれたUnicode文字エスケープシーケンスです。明示的な文字か、「\u」に続いて4個の16進数値を並べたUnicode文字の一般表現、または、「\」に続いて文字のコードポイントを8進数か16進数で表明した値を書けます。

scala> val a = 'A'
a: Char = A
 
scala> val b = '\u0041'
b: Char = A
 
scala> val c = '\101'
c: Char = A

 そして、有効なエスケープシーケンス文字があります。

リテラル 意味
\n 改行
\r 復帰
\t タブ
\b バックスペース
\" ダブルクオート
\' シングルクオート
\\ バックスラッシュ
\f 改ページ
表4 特別なエスケープシーケンスの文字リテラル

文字列リテラル

 「"」(ダブルクオート)で文字を囲むと、文字列リテラルになります。内容は文字リテラルと同じで、有効なエスケープシーケンスもあります。なお、生成される文字列はJavaのString型です。

scala> val s = "hello"
s: java.lang.String = hello
 
scala> val es = "\"\'\\"
es: java.lang.String = "'\

 また、「"""」(ダブルクオート3つ)を使用して文字列を囲むと、「生の文字列(raw string)」を使えます。これは文字列内のエスケープシーケンスを無視し、改行などもそのまま記述できます。

scala> val es = """\"\'\\"""
es: java.lang.String = \"\'\\

 文字列に多くのエスケープシーケンスが含まれる場合、raw stringを使用すると分かりやすく記述できます。

シンボルリテラル

 シンボルリテラルは「'」(シングルクオート)を名前の前に付けることで、その名前を表すSymbolリテラルとなります。これは「scala.Symbol」のインスタンスで、「'symbol」というリテラルは、「scala.Symbol("symbol")」という式と同じ意味です。

 なお、同じ名前を持った2つのシンボルは、同じオブジェクトを示します。そのため、マップキーとして文字列の代わりにSymbolを使うことがあります。

scala> val s = 'sSymbol
s: Symbol = 'sSymbol
 
scala> s.name
res4: String = sSymbol

 以上が一般的なリテラルです。ここまでは、基本データ型と一般的なリテラルについてご紹介しました。次ページでは、Scalaの配列型について見てみましょう。

       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

Touch Barという新UIを得た「MacBook Pro」、プレゼント!

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。