気になる開発プロダクツ

第7回 Scala 2.6.0-final

この記事を読むのに必要な時間:およそ 6 分

Scalaプログラミングを少しだけ

では,Scalaのプログラミングを少しだけ試してみましょう。Java VM上で動作するとはいっても,Java言語とは異なる部分が多いため,はじめは戸惑ってしまうかもしれませんが,まずはトライしてみることで新しい世界が見えてくるでしょう。

objectとclass

図1を見て,Javaプログラマは不思議に思ったかもしれません。staticを宣言したわけでもないのに,ScalaProgrammingはnewでインスタンスを生成しないままに実行されてしまったからです。

では,ScalaProgrammingインスタンスをnewで生成できるのかといえば,それはできません( 図8)。objectで宣言された場合は,インスタンスを複製しないことを表しているためです。

図8 object宣言ではnewできない

scala> object ScalaProgramming {                  ← ソースコード入力開始
     |   def main( args: Array[ String ] ) {
     |     println( "Scalaによるプログラミング" )
     |   }
     | }
defined module ScalaProgramming                   ← ソースコード入力完了

scala> ScalaProgramming.main( null )              ← プログラム実行
Scalaによるプログラミング                        ← 実行結果

scala> var o = new ScalaProgramming()             ← インスタンスを変数oに代入?
<console>:4: error: not found: type ScalaProgramming   ← エラーが表示された!
var o = new ScalaProgramming()
            ^

scala>

classで宣言している場合は,newによりインスタンスを生成できます(図9)。objectとは異なり,インスタンスを生成しないと実行できません。両者の違いはJavaプログラマにはちょっと馴染まないところかもしれません。

図9 classならnewできる(Javaと同じ)

scala> class ScalaProgramming {                  ← classとして宣言してみる
     |   def main( args: Array[ String ] ) {
     |     println( "Scalaによるプログラミング" )
     |   }
     | }
defined class ScalaProgramming

scala> var o1 = new ScalaProgramming()           ← newでインスタンス生成
o1: ScalaProgramming = ScalaProgramming@168f248

scala> var o2 = new ScalaProgramming()           ← 別のインスタンスも生成
o2: ScalaProgramming = ScalaProgramming@805298

scala> println( o1 == o2 )
false                                            ← 2つは別のインスタンス

scala> o1.main( null )                           ← インスタンスでメソッド実行
Scalaによるプログラミング

scala> o2.main( null )
Scalaによるプログラミング

scala>

defはメソッド

defはメソッドを表しますが,メソッドの特殊形として代入文を記述することもできます(ただし代入文用にはvalやvarという予約語があります)。クラスを用いずメソッドだけを実行することが可能です。もちろん再帰処理も記述できます。図10に例を示します。

引数の型は引数の後に,戻り値の型はメソッドの後に,:に続けて記述しますが,戻り値の型は省略可能です。また,returnを記述しない場合は,最後に実行された文の結果がメソッドの戻り値となります。

図10 defによるメソッドや代入文の例

scala> def sum( n : Int ) = n * ( n + 1 ) / 2   ← 1からnまでの整数の総和を求めるメソッド
sum: (Int)Int         ← 戻り値の型は自動的にIntと判定された

scala> sum( 10 )
res0: Int = 55        ← 1から10までの整数の総和は55

scala> def a = 5      ← 代入文も記述できる(メソッドの特殊形)
a: Int                ← 値がInt型であることを自動的に判定

scala> def b = 1000L  ← 値の末尾にL(小文字でも良い)をつけてLong型に
b: Long

scala> def c = 3.2D   ← 値の末尾にD(小文字でも良い)をつけてDouble型に
c: Double

scala> def d = 5.5f   ← 値の末尾にf(大文字でも良い)をつけてFloat型に
d: Float

scala> def fact( n : BigInt ) : BigInt = if ( n == 0 ) 1 else ( n * fact( n - 1 ) )                  ← 再帰処理も記述可能
fact: (BigInt)BigInt

scala> fact( 100 )    ← 1から100までの階乗!
res1: BigInt = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

scala> def resultFalse() = {  true;  false;  }  ← 戻り値がfalseになるメソッド
resultFalse: ()Boolean

scala> resultFalse()
res2: Boolean = false    ← 戻り値はfalse

scala> def resultTrue()  = {  false;  true;  }  ← 戻り値がtrueになるメソッド
resultTrue: ()Boolean

scala> resultTrue()
res3: Boolean = true     ← 戻り値はtrue

scala>

toとuntil

範囲を表すtoとuntilでは,最後の値が異なります。図11で示すとおり,1 to 5では1から5までの値を表すのに対し,1 until 5では,1から4までの値しか表しません。これらはRubyでいう1..5と1...5にあたります。

図11 toとuntilでは最後の値が異なる

scala> println( 1 to 5 )
Range(1, 2, 3, 4, 5)

scala> println( 1 until 5 )
Range(1, 2, 3, 4)

scala> println( 5 to 1 )
Range()

scala> println( 5 until 1 )
Range()

scala>

著者プロフィール

沖林正紀(おきばやしまさのり)

SE/プログラマを経て,WebアプリケーションやXMLなどについて雑誌記事や書籍の執筆活動を始める。大手メーカで製品資料の作成や,セミナーの講師を担当したこともある。現在は,取材記事や製品レビューなどに執筆活動の幅を広げる一方,プログラミング教材の開発も手がけている。

著書

コメント

コメントの記入