String - みる会図書館


検索対象: ななか+Inside PRESS 2012 夏
11件見つかりました。

1. ななか+Inside PRESS 2012 夏

6.4 トレイトは実装コードを書けるインタフェース トで実装したサンプルです。 Greeting トレイトは Java のインタフェースのように実装を持ち ません。抽象クラスである AbstractGreet ⅲ g クラスが継承しています、 13 。次はトレイトを使っ た「ミックスイン」の例です。複数のトレイトを合成することをミックスインと呼びます。リ スト 32 を見てください。今度はトレイトに処理が実装されています。トレイトにはコンスト ラクタが記述できない以外は、クラスと同様に実装コードも記述できます。 こでは、従業員 (Employee) をメモリー上で読み書きできるリポジトリを例に挙げます。リポジトリの抽象クラ スである EmployeeRepositoryBase は内部に Map を持ち、 List や Map への変換メソッドを提 供します。そして、リポジトリとして書き込みや読み込みの機能を提供する WritableEmploy- eeRepository トレイトと ReadableEmpIoyeeRepository トレイトがあります。先ほどの例と違 い実装コードを含みます。また、これらのトレイトでは this 型で EmployeeRepositoryBase クラ スを指定しており、 ミックスイン対象の EmployeeRepositoryBase の機能にアクセスできます。 EmployeeReadOnlyRepository クラスは読み込み専用で、 EmployeeRepository クラスは読み書 きができ、 toReadabIe メソッドで EmployeeReadOnIyRepository クラスに変換することができ ます。トレイトでミックスインを使うとクラスに実装する処理を小さな断片として定義し、必要な ときに組み合わせてクラスを実装することが可能です。 Java にはない Scala の魅力の一つです。 リスト 31 トレイトの利用例。 Scala には Java の interface に相当する機能はなく、トレイトを使用する / / あいさつのトレイト trait Greeting { def getMessage : String / / あいさつの抽象クラス abstract class AbstractGreeting (target : String) extends Greeting { def getMessageFormat : String override def getMessage = getMessageFormat . format (target) / / 日本語のあいさつ class GreetingJapanese (target : String) extends AbstractGreeting(target) { " %s さん、こんにちは " override def getMessageFormat / / 英語のあいさつ class GreetingEng1ish(target : String) extends AbstractGreeting(target) { "%s, He110 " override def getMessageFormat / / あいさっするアプリケーション object GreetingApp1ication { / / ポリモーフィズムを使ってあいさつを表示 private def say(greeting: Greeting) { 、 13 二つ以上のトレイトを継承する場合は「… extends Greetingwith A with B 」などと with でつなげて指名しま ななか十 inside press ◆ 27

2. ななか+Inside PRESS 2012 夏

変数 : 再代入の有無がポイント scala> var name name: java. lang. String "Sca1a" scala> name name : 」 ava. lang. String 3.1 Java Sca1a このように ScaIa では、一度作成したら再度の代入はできない「不変な val 」と、再代入可能な 「可変な var 」の 2 種類の変数宣言が可能です。関数型のプログラミングスタイルでは変数を再代 String name クラスです * 3 。 Java では次のように変数の型を指定する必要があります。 Scala の代表的な型を表 3 に示します。 Java のプリミテイプ型に相当する型はなく、すべてが 3.1.3 ScaIa の代表的な型と変数の型推論 入できない val を原則的に利用します。なぜかについては後述します。 name が Str ⅲ g であるとコンパイラが型を自動的に判定します。このような機能を「型推論」と Scala では、変数の型を省略して記述できます。これは、代入される値が文字列型であるため、 val name いいます。 は Java と同様に強い型付けを持っ言語だということがわかります。 Scala は Java と同様に強い 値を代入してみましよう ( リスト 6 ) 。結果は期待通り、型の不一致 (type mismatch) です。 scala なる型の値を代入したらどうなるでしようか。試しに文字列型の name に数値型である lnt 型の アノテーションを利用するとよいでしよう ( リスト 5 ) 。逆に型推論で型が決定している変数に異 数値型の場合も同様に型推論が適用できます。 Number 型などの抽象型を指定したい場合は型 name: java. lang. String = Java scala> val name:String 述することで、明示的に型を指定できます。この指定方法を「型アノテーション」と呼びます。 あえて型を指定して宣言した例を次に示します。変数名の後ろに、コロン ( : ) に続けて型名を記 型アノテーションの例 静的型付けを持ちながらも、スクリプト言語のように簡潔なコードを書くことができます。これ は大きな魅力ではないでしようか。 scala> val num1 numl : lnt scala> val num2 1 リスト 5 1 . 5 1 、 3Java ではすべてのクラスが java. lang. Object を継承しているように scala では Any クラスから派生しています。 Any クラスの直下には AnyVal と AnyRef があります。 AnyVal は、 Java のプリミテイプ型に相当し、 lnt や Long など値を表すクラスの親クラスです。 AnyRef は、 Java の参照型に相当し、それ以外のクラスの親クラスと なります。 ◆ ななか十 inside press

3. ななか+Inside PRESS 2012 夏

3.2 クラスが簡潔に書ける num2 : Doub1e scala> val num : Number num : j ava. lang. Number 1 1 リスト 6 文字列型の変数に lnt 型の値を代人するとエラーになる found : lnt(l) く console > : 6 : error: type mismatch; scala> name = 1 name : コ ava. lang. String = Sca1a scala> var name "Sca1a" required : name java. lang. String 1 3.2 クラスが簡潔に書ける Java と同様、 ScaIa の場合もプログラミングはクラスからです。 う。 InteIIiJ IDEA でコードを動かしながら読み進めてください。 3.2 ュクラスとフィールドを宣言する その使い方から見ていきましよ 早速クラスを使ってみましよう。今回はお金を表す M 。 ney クラスを例に取り、クラスの使い方 を学びます。まず、リスト 7 のように Money クラスを宣言します。前述したように、クラス宣言 のデフォルト ( 既定 ) のアクセス修飾子は public です。 Java だと同一バッケージ内からしかアク 表 3 ScaIa の代表的な型 型名 Unit Boolean Char Byte Short lnt Long Float Double String ◆ ななか十 inside press 12 値の範囲 なし 真偽値 ュニコード文字 1 バイト整数 16 ビット整数 32 ビット整数 64 ビット整数 32 ビット浮動小数 64 ビット浮動小数 文字列 記述例 true, false 10. toByte 10. toShort 123 123L 123. OF 123. OD ” abc ” Java での例 VOid boolean Ch ar byt e short int long Ⅱ 0 at double String

4. ななか+Inside PRESS 2012 夏

1.5 クラスを作ってビルド・実行する object He110WorId { def main(args : Array [String] ) :Unit print1n("HeIIo, Wor1d! " ) 1.5 クラスを作ってビルド・実行する それでは、ビルドとプログラムの実行を試しましよう。簡単なプログラム例として Hello, WorId! を表示するプログラムを作成します。前述の手順で作成したプロジェクトで src フォル ダに He Ⅱ oWorld オプジェクトを作成します。後述するように、オプジェクトは特別なクラスで す。 src ディレクトリを右クリックして、「 New 」→「 ScaIa CIass 」を選択し、開いたウインド ウで HelloWorld の Object を作成します ( 図 2 ) 。 HelloWorld オプジェクトのコードがリスト 4 こでは「 HelloWorId. scala 」と表示されたエデイタ領域にこのまま入力してください。 です。 HeIIoWorId オプジェクトを含むプロジェクト全体をビルドするには、メニューから「 Build 」→ 「 Make Project 」を指定します。 HeIIoWorId オプジェクトだけをコンパイルするには「 Build 」→ 「 CompiIe 'HeIIoWorId. scala' 」をクリックします。それでは、 InteIIiJ IDEA 上で実行してみま しよう。 HeIIoWorId オプジェクトにカーソルがある状態で、メニューの「 Run 」→「 Run 」をク リックして、プログラムを実行します。 Hello, World! という表示が IntelliJIDEA のコンソール に表示されるはずです ( 図 3 ) 。デバッグをしたい場合には、「 Run 」→「 Debug 」を指定します。 Eclipse ユーザーのために、 Eclipse のショートカットを併記した lnte Ⅱ iJIDEA の代表的なショー トカット一覧を表 2 に示します。 図 3 メニューで「 Run 」→「 Run 」を指定してプログラムを実行 」」 , H 団 0W0 日 d. 5 ( a な - [ un 厄 - リ n 厄 d - トハ d 所可ん itled 】 ~ 応朝 , 亡」 ( 」新い H 0W0 d 、 5 ( は の寺帯 , ド第叫 HeIIoWorId. 5()は置 ; 0 マ Guntitled ( ~ ハ deap 「 0 」 e ロ引 un 歌に d ) j ・ ( t ー朝 WO 「 ( def main(args: Array(Stringl):Unit = { ( の H 0W0 月 d p れ ttn ( 他ーい ~ Wortd!") ) ー untitled. iml 一ト ; 曲 Ex 「は海「 a 「に 5 ー Run 「 HeUoWor\d / し山「 a 「 y / 」ヨ va / 」ヨ vaVi 代聞 a ( hines / 1.7 論 . jdk/Contents/Home/bin/java —Didea.lau 距 ~ を 0 , World! P 「 0 ( e55 f inished with exit ( 0d0 0 第 M 2 っ P 「 0 ^ 、当お 6 「 & を ) CO ョョ物 nd の 1 5 き T ( 0n50 厄生 Run ー 0 を TO [ 4 : 9 21 Event L09 M 0 を 790M ◆ 6 ななか十 inside press

5. ななか+Inside PRESS 2012 夏

3 基礎編 : 変数とクラスを学ぶ , こで学ぶこと ・変数 (val と var の違い、型と型推論 ) ・クラス ( フィールドとメソッド、コンストラクタ ) ・オプジェクト ( コンパニオンオプジェクト ) ・プログラミングスタイルの使い分け いよいよ、 Scala の基本文法を学んでいきましよう。基礎編では主に 「変数」と「クラス」につい て学びます。 3.1 変数 : 再代入の有無がポイント 学習のためにはインタブリタで一文ずっ確認した方が理解しやすいでしよう。そこで、 は REPL を利用します。 * 2 「 v 引」で再代入できない変数を定義する 典型的な変数として、文字列型の変数を次のように定義してみます。 scala> val name "Sca1a" name: java. lang. String = Sca1a 変数を宣言するには「 val 」あるいは「 var 」を最初に配置し、その後に変数名を記述します。 の例では val で宣言し、初期値は代入演算子の後に続けて指定しています。また、変数宣言の文を 記述し Enter キーを押すと、次の行に「 name: java. lang. String = Scala 」と表示されます。これ は name という変数の中に Str ⅲ g 型で ' ' Scala ”という値を保持していることを表します。ちなみ に Scala の文字列型には Java の文字列型 (java. lang. String) が使われます。 val の変数は、 Java でいう final 変数と同じ扱いです。つまり、初期値が必要で、再代入は禁止されます試しに代入 すると次のようにラーが発生します。そういう意味では " 変数 " ではなく、 " 定数 : という表現 が適切かもしれません。 S cala> name error : reassignment tO val く CO Ⅱ sole > : 6 : name 3.1 ユ 3.1.2 再代入できる変数は「 var 」で定義する 続いて、もうーっの宣言方法である var の場合です。 こちらは再代入が可能な“普通の”変数 です。 * 2REPL ではクラスに紐付かない変数やメソッドを定義できます。 ななか十 inside press ◆ 10

6. ななか+Inside PRESS 2012 夏

2.3 コンパイル済みのプログラムを実行する 図 4 Java と比較した場合の ScaIa の文法の特徴 object He110WorId { def main(args : Array [String] ) : Unit print1n("HeIIo, Wor1d! " ) class He110WorId { public static VOid main(String ロ args) { System. out . print1n("He110, Wor1d! " ) ・ 1. object はシングルトンを定義するための予約新 、ロロ 0 2. Scala では、アクセス修飾子を省略した場合は public となる。 3. ScaIa のメソッド宣言は、 def から始める。 4. ScaIa ではクラスメソッドはなく、すべてインスタンスメソッドとなる。 5. メソッドの引数の型は引数名の後ろに記述する。 6. 配列は Array クラスを利用する。 7. メソッドの戻り値の型は引数プロックの後ろにコロン ( : ) に続けて記述する。 Unit は 値を返さないという意味 6 。 8. メソッド本体のプロックは、戻り値の型の後ろにイコール ( = ) に続けて記述する。 ななか十 inside press = { / * * / } は defhoge() { / * * / } に省略して記述できます。 わ def hoge():Unit インスタンスを 1 つだけ作ることを保証するデザインパターン。

7. ななか+Inside PRESS 2012 夏

6.4 トレイトは実装コードを書けるインタフェ ース println(greeting. getMessage) def main(args : Array [String] ) { args match { case Array(1ang, user) = > lang mat ch { case = > pri Ⅱ tl Ⅱ ( " 指定されたあいさつは実行できません。 " ) case "EN" = > say (new GreetingEng1ish(user) ) case "JP't = > say (new GreetingJapanese (user) ) リスト 32 複数のトレイトを使ったミックスインの例 = > println ( " 引数の数が不正です。 " ) } ななか十 inside press ◆ 28 / / 読み込み専用リポジトリの宣言 entities + = (employee . id ー > employee) def save (employee : Emp10yee) : Unit this: Emp10yeeRepositoryBase = > / / this 型の指定 trait Writab1eEmp10yeeRepository { / / 書き込み専用のリポジトリ機能 def load(key : lnt) : Emp10yee entities(key) this: Emp10yeeRepositoryBase = > / / this 型の指定 trait Readab1eEmp10yeeRepository { / / 読み込み専用のリポジトリ機能 def toList entities . toList def toMap = entities Map. empty [lnt , Emp10yee] private [repository] var entities abstract class Emp10yeeRepositoryBase { 〃従業員情報を保持するリポジトリの骨格実装 case class Emp10yee(id: lnt, name: String) / / 従業員 package repository

8. ななか+Inside PRESS 2012 夏

6.3 ケースクラスでバリューオプジェクトを簡単実装 case List(3,3,3) = > "three" / / コレクションの場合 = > throw new IIIega1ArgumentException case print1n(convertNumberToString(I) ) / / 0 れ e print1n(convertNumberTOString("2") ) / / t 田 0 print1n(convertNumberToString(List(3,3,3)) / / three t'Katot') val personName = PersonName ( "Junichi" println(pl = (2) / / . eq 乙 s 朝 2 ) が呼ばれる "KATO" ) val p2 = PersonName ( " JUNICHI" "Kato") va1 pl = PersonName ( " Junichitt リスト 30 ケースクラスで定義したバリューオプジェクトの利用 print1n(convertNumberToString(0.5)) / / 例外発生 ・ケースクラスに対応するコンパニオンオプジェクトとファクトリメソッドを追加する このケースクラスを宣言するとコンパイラが以下を自動的に追加します。 case class PersonName(firstName: String, 1astName: String) うに記述できます。 機能を提供するクラスです。例えば、人の名前を表す人名というバリューオプジェクトは次のよ ケースクラスは、バリューオプジェクト ( 値を表現するオプジェクト ) を実装するために必要な 6.3 ケースクラスでバリューオプジェクトを簡単実装 print1n("IastName %s" . format(12)) / / LastName = Ka カ 0 val PersonName ( ー 12 ) = personName / / LastName だけを抽出 LastName = イ 0t0 / / ↑ firstName = れ c れを , print1n("firstName = %s, 1astName = . format(f , 1 ) ) val PersonName (f , 1 ) personName 〃フィールドを抽出 ScaIa には Java のインタフェースと同じ機能はありません。 6.4 トレイトは実装コードを書けるインタフェース です。 このため、たった 1 行の記述で、リスト 30 のようにバリューオプジェクトを扱うことが可能 ・ toString 、 hashCode 、 equals メソッドの実装を行う ケースクラスのコンストラクタの引数宣言を val で行う Scala ではインタフェースの代 ななか十 inside press ◆ 26 フェースのようなものです。リスト 31 は英語と日本でのあいさつを使い分けるアプリをトレイ わりにトレイト (trait) を使います。このトレイトを一言でいうと、実装コードを書けるインタ

9. ななか+Inside PRESS 2012 夏

トレイトは実装コードを書けるインタフェ def toReadab1e with Readab1eEmp10yeeRepository { with WritabIeEmpIoyeeRepository extends Emp10yeeRepositoryBase class Emp10yeeRepository / / 読み書き可能なリポジトリの宣言 with Readab1eEmp10yeeRepository extends Emp10yeeRepositoryBase class Emp10yeeReadOn1yRepository ース 6.4 print1n(emp2) / / EmpLoyee(), T の ) val emp2 = readOn1yRepos . load ( 1 ) val readOn1yRepos = repos . t0Readab1e println(emp) / / E 乙 ee ( 1 , T の val emp = repos . load ( 1 ) repos . save(Emp10yee(1, "KATO")) val repos = new Emp10yeeRepository def main(args : Array [String] ) { object RepositoryApp1ication { 〃アプリケーション本体 result result . entities 十十 = entities val result = new Emp10yeeReadOn1yRepository ◆ 29 ななか十 inside press 勧めします。 きっかけにして、 Scala 関連書籍やネット上のコンテンツを合わせて自分なりに学習することをお に体感することができます。こでは ScaIa の魅力のほんの一部しか紹介できませんが、これを 関数型が難しければ、従来からなじみのある命令型でプログラミングしても Scala の魅力を十分 しても敬遠しがちですが、まずは自分が理解した範囲から ScaIa を使い始めてもよいと思います。 ScaIa には次世代言語として様々な機能が実装されています。言語としての機能が多いとどう

10. ななか+Inside PRESS 2012 夏

val resultl val resu1t2 val resu1t3 リスト 22 値としての関数を呼び出す square(2) / / es 乙 t プ = イ squareDebug(2) 〃 resuLt2 = イ標準出力にイを表示 square("aaa") / / 第一引数の型がコンパイルエラー val resu1t4:String = square(2) / / 戻り値の型がコンパイルエラー リスト 23 関数をメソッドの引数や戻り値に利用する / / 関数を引数に取る関数 def debugprint(): lnt, func: (lnt) = > lnt) { func (x) va1 result println(result) debugPrint(10, square) / / プ 00 が表示される / / デバッグ版の s 。メソッドを返す関数 def newSquareDebugFunc = { val squareDebugFunc = (x : lnt) = > { square (x) println(result) va1 result result squareDebugFunc val squareDebug = newSquareDebugFunc squareDebug(5) / / 25 が表示される va1 result 5 Scala と」 ava のコレクションの違い こで、関数と深い関係にあるコレクションについて説明します。 Java との違いが際立っ List と Array について見ていきましよう。 5.1 List の生成と追加、順次処理を学ぶ ななか十 inside press ◆ 22 スタイルに基づきます。既存のインスタンスに要素を追加するのではなく、要素が追加された新 素の追加や削除はできません。これは関数型言語の特徴である、「副作用」がないプログラミング なるのは、 List は「不変オプジェクト」であるという点です。例えば、一度作成した List への要 scala の List は、 Java の List と同様、順序を持つコレクションです。 Java の List と大きく異