SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新開発言語「Scala」の実体

Javaの限界を超えて実用化を目指す
新開発言語「Scala」のメリットとは~前編

キーワードは手軽さと拡張性

関数

ブロック

 Scalaの関数には、無名関数やクロージャ、関数内での関数の定義など、関数型言語のエッセンスが取り込まれています。Javaユーザーにとっては新鮮であろうScalaのアプローチを理解するには、まず「ブロック」という処理単位(スクリプト言語「Ruby」のブロックのようなもの)を知る必要があります。

 ブロックとは、中括弧{……}で囲まれた領域であり、最後に表現された値が戻り値となるものです。次にブロックの例を挙げます。

scala> { val x=1 ;val y=2; x+y}
res0: Int = 3

 ブロック内で宣言された変数xと変数yを足した値が戻り値となっています(ここで、xyがIntと型推論されたうえで、x+yもIntと型推論されています)。ブロック内で宣言された変数は、ブロック内でのみ有効です(すなわち、ブロックは変数のスコープの区切りとなっています)。そのため、ブロック外から直接変数xを参照するとエラーとなります。

scala> x
<console>:5: error: not
found: value x

 ブロック内の最後の行が値を返さない場合には、Unit型という型を返します。

名前付きの関数を定義する

 関数は次のように定義します。

引数なし
def 関数名 : 戻り値の型 = { ブロック }
引数あり
def 関数名(引数名:引数の型, 引数名:引数の型, ……) : 戻り値の型 = { ブロック }

 ブロック内に関数の実体(処理内容)を記述します。戻り値の型は、変数の時と同じく省略可能です(自明なことは書かないというScalaの設計思想だと筆者は思っています)。

 一方、引数名の型は省略できません。引数を明示させることで、コンパイル時のコードの最適化および型推論を可能としています。LIST4に引数ありの関数の例を挙げます。

 なお、LIST4の縦棒(|)は、複数行にまたがる記述であることを示している記号で、実際に入力する必要はありません。

LIST4:引数ありの関数の例
scala> def funcArg(last : String, first : String) : String = { 
|          println("hello! " + last + " " + first)
|          last + first
|  }
funcArg: (String,String)String

 関数定義に「return」がないことが気になったかもしれません。returnを使う/使わないは自由ですが、{……}で区切られたブロックに、等号(=)で名前を付けることが関数定義という理解に立ち、returnのない記述にも慣れておくのがよいでしょう。

 ブロックが関数定義の最後の行の値を返すためですが、この点は読みやすさを重視して、last+firstという部分をreturnlast+first)と書くこともできます。また、関数定義時に関数名の後に等号(=)を忘れてしまうと、コンパイルは通りますが、こちらの意図したとおりに動作しないので注意が必要です。

 それでは、定義した関数funcArgを使ってみましょう。

scala> funcArg("yuuji","saito")
hello! yuuji saito
res3: String = yuujisaito

 これは第1引数と、第2引数が表示され、戻り値として、2つの引数を結合したものが返ってきています。

関数内での関数の定義

 Scalaでは、関数内に関数を定義できます(便宜上、これを親関数と子関数と言います)。その場合、親関数内で定義した子関数は、親関数の中からのみ呼び出すことができます(LIST5)。

LIST5:関数内での関数の定義
scala> def func1(arg1:int, arg2:int) = {
     | val func1valStart = "OK"
     |
     | def func2(arg3 : int) = {
     | println(func1valStart)//関数の前に宣言された変数にはアクセスできる
     | //println(func1valEnd)//関数の後に宣言された変数にはアクセスできない
     | (arg1 + arg2) * arg3
     | }
     | val func1valEnd = "NG"
     | func2(10)
     | }
warning: there were deprecation warnings; re-run with -deprecation for details
func1: (int,int)Int

scala> val ret = func1(1,2)
OK
ret: Int = 30

scala> ret
res3: Int = 30

 func1関数は、引数1と引数2を足して、さらに10倍して返す関数です。子関数は、親関数の引数や、子関数の定義前に宣言された変数へアクセスできるという特徴を持っています。今回は解説を省きますが、Scalaの関数は関数自体を引数にとれます。また、再帰的に処理する関数を容易に記述できます。これらについて興味のある方は、Scalaの解説書などを参考にしてください。

クラス

 クラスの宣言方法はLIST6のとおりです。extendsキーワードで、親クラスを継承できます。また、withキーワードとしてtraitを使用することで機能拡張(mix-in型の多重継承)が可能となります。メンバーの初期アクセス権限はpublicです。アクセス修飾詞にはpublicprotectedprivateが存在します。

LIST6:クラスの宣言方法(定義イメージ)
class クラス名(メンバ変数1, メンバ変数2, ……) extends 親クラス with トレイト {
    
    //メンバ変数(デフォルトでのスコープはpublicである)
    val publicMemberVal1
    protected val protectedMemberVal1
    private val privateMemberVal1
    
    //メンバ関数(デフォルトでのスコープはpublicである)
    def publicFunc = {}
    
    private def privateFunc = {}
}

オブジェクト(シングルトンオブジェクト)

 Scalaは、オブジェクト指向でよく利用されるシングルトンオブジェクト(注3)を、言語仕様としてサポートしています。宣言方法は、classキーワードを使用せずに、objectキーワードを用いた宣言を行うことで(パッケージ内で)唯一のシングルトンオブジェクトが生成されます。シングルトンオブジェクトは引数を持てない点を除いてクラスと同じです(LIST7)。

注3

 シングルトンパターンとは、複数のクライアントにサービスを提供するといった目的のために、インスタンスが1つしか生成されないことを保証するデザインパターンです。

LIST7:オブジェクトの宣言方法(定義イメージ)
object オブジェクト名 {
    
    //メンバ変数(デフォルトでのスコープはpublicである)
    val publicMemberVal = 1
    protected val protectedMemberVal1 = 2
    private val privateMemberVal1 = 3
    
    //メンバ関数(デフォルトでのスコープはpublicである)
    def publicFunc = {}
    
    private def privateFunc = {}
}

次のページ
制御構文

この記事は参考になりましたか?

新開発言語「Scala」の実体連載記事一覧

もっと読む

この記事の著者

株式会社パテントビューロ 三木隆史(ミキ タカフミ)

株式会社パテントビューロ所属。マネージャー業務と平行して、Webアプリケーション開発、自然言語系の研究開発を行なう。以前はC言語による組込開発。違和感なくScalaへ移行できたことや、ロジック部分に注力できる生産性の高さに驚いている。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

株式会社パテントビューロ 木村吉博(キムラ ヨシヒロ)

政府系研究機関での研究開発を経て、現在、株式会社パテントビューロにて、プログラミング(知財関連文書(SGML/XML)の変換バッチ処理のScalaでの記述など)を担当している。複雑でイレギュラーな記述も多々見られる大量の文書を相手にする際に、Scalaの書きやすさと高速性とに大いに助けられている。か...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4475 2009/11/06 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー