Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Essential Scala 第2章 式、型、値 / Essential Scala Chapter 2 Expressions, Types, and Values

Essential Scala 第2章 式、型、値 / Essential Scala Chapter 2 Expressions, Types, and Values

Takuya Tsuchida

June 27, 2018
Tweet

More Decks by Takuya Tsuchida

Other Decks in Programming

Transcript

  1. 2.1 最初のプログラム Scala コンソールでは評価結果の型と値が表示されます。 "Hello world!" // res: String =

    Hello world! Scala のコードは左から右へ評価されます。 "Hello world!".toUpperCase // res: String = HELLO WORLD! 4
  2. 5

  3. 2.1.1 コンパイル時と実行時 コンパイル時には文法と型が検証されます。 toUpperCase."Hello world!" // error: identifier expected but

    string literal found. // toUpperCase."Hello world!" // 2.toUpperCase // error: value toUpperCase is not a member of Int // 2.toUpperCase // 6
  4. 8

  5. 10

  6. 2.2.2 メソッド呼び出し メソッドを呼び出すことでオブジェクトを作用させます。* "Hello world!".toUpperCase // res: String = HELLO

    WORLD! パラメーター(引数)を受け取れるメソッドもあります。 "abcdef".take(3) // res: String = abc 14 * オブジェクトを作用させる別の方法としてパターンマッチングがあります。
  7. 15

  8. 17 2.2.3 演算子 Scala のすべての値はオブジェクトなので、プリミティブ型*に対してもメソッドが呼び出せ ます。 123.toShort // this is

    how we define a `Short` in Scala // res: Short = 123 Scala では演算子もメソッドです。Scala のメソッドはシンボルによる名前を使用できま す。 43 - 3 + 2 // res: Int = 42 43.-(3).+(2) // res: Int = 42 * Java のプリミティブ型にマッピングされる Int や Boolean などです。
  9. 19 2.2.3 演算子 すべての1引数メソッドは中置記法にできます。 "the quick brown fox" split "

    " // res: Array[String] = Array(the, quick, brown, fox) 前置記法、後置記法、右結合、代入演算子という記法もありますが中置記法に比べると 一般的ではありません。 Scala における演算子の優先順位*はメソッドの名前から推論されます。 * https://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#infix-operations
  10. 20

  11. 2.3 リテラルオブジェクト 22 すでにいくつかの Scala の基本型を説明しました。本節では Scala の全リテラル式を網 羅することでその知識を完全なものにします。リテラル式はそれ自身が表す固定値を表 現します。

    42 // res: Int = 42 リテラルと評価された値を混同しないでください。リテラル式はプログラムを実行する前 のプログラムテキストにおける表現で、値はプログラムを実行した後のメモリ上における 表現です。
  12. 24

  13. 2.3.2 真偽値 真偽値は Java と同じで true か false です。 true

    // res: Boolean = true false // res: Boolean = false 25
  14. 26

  15. 28

  16. 2.3.4 文字列 文字列は Java と同じで、ダブルクォートで囲まれた文字列で表現します。 "this is a string" //

    res: String = this is a string "the\nusual\tescape characters apply" // res: String = // the // usual escape characters apply 29
  17. 30

  18. 32

  19. 2.3.6 Unit Unit は Java の void と同じで、() で表現します。Unit は、標準出力に使用される

    println など、興味深い値に評価されない式の結果で使用されます。 多くの Scala の文法的構成要素は式で型と値を持ちます。有用な値を生成しない式の ためのプレースホルダーとして Unit は必要になります。 33
  20. 34

  21. 37

  22. 2.4.1 メソッド オブジェクトはメソッドを通して作用されます。 object Test2 { def name: String =

    "Probably the best object ever" } Test2.name // res: String = Probably the best object ever 39
  23. 41

  24. ノート:メソッド宣言記法 def name(parameter: type, ...): resultType = bodyExpression or def

    name: resultType = bodyExpression • name はメソッドの名前 • parameter は1つ以上の引数の名前(省略可能) • type はメソッドの引数の型 • resultType はメソッドの結果の型(省略可能) • bodyExpression はメソッドが呼び出されたときに評価される式 42
  25. 2.4.2 フィールド オブジェクトはフィールドにほかのオブジェクトを持てます。 object Test4 { val name = "Noel"

    def hello(other: String): String = name + " says hi to " + other } Test4.hello("Dave") // res: String = Noel says hi to Dave 44
  26. 2.4.2 フィールド val で不変フィールドを定義できます。不変フィールドは名前に束縛された値を変更する ことができません。var で可変フィールドを定義できます。可変フィールドは名前に束縛さ れた値を変更できます。 常に var より

    val を選びましょう。Scala プログラマーは不変フィールドを使用することを 好みます。本書の大部分では var を避けているので、Scala プログラミングをするときは 真似してみてください。 45
  27. 46

  28. ノート:フィールド宣言記法 val name: type = valueExpression or var name: type

    = valueExpression • name はフィールドの名前 • type はフィールドの型(省略可能) • valueExpression はオブジェクトに評価されて名前に束縛される 47
  29. 2.4.3 メソッド対フィールド オブジェクトは遅延ローディングされるため、参照されるまで評価されません。 Test7 // Evaluating simpleField // res: Test7.type

    = Test7$@b22e8c9 フィールドの式はただ1回だけ実行され、その結果がフィールドに保存されます。 Test7.simpleField // res: Int = 42 Test7.simpleField // res: Int = 42 49
  30. 51

  31. 2.5 メソッドの書き方 53 本書では文法を越えて Scala プログラムを構築する体系的な方法を与えることが主目 的のひとつです。 本節ではメソッドを構築するための体系的な方法を見ていきます。Scala についての経 験がある場合、方法のいくつかのステップを省略できるかもしれませんが、本書を読ん

    でいる間はこの方法を踏襲することを強く推奨します。 このアドバイスを具体的にするために前節の課題を例題として使用します。 例題:calc オブジェクトを square メソッドを持たせて定義してください。square メソッド は Double を引数とし、その入力を2乗します。
  32. 56

  33. 57 2.5.3 宣言を書く 型とテストケースがあるのでメソッド宣言を書くことができます。未実装であるメソッドの 本体には Scala の機能である ??? を使用できます。 def

    square(in: Double): Double = ??? この宣言はこれまでのステップで集めた情報によって機械的にもたらされるべきです。
  34. 58

  35. 60

  36. 2.5.5 本体を書く メソッドの本体を書く技法は2つあります。 1つ目は結果の型について考える技法です。例題の結果の型は Double です。どうやっ たら Double を生成できるでしょうか?リテラルを書くこともできますが、当然ながらこの ケースでは正しくありません。

    2つ目は引数の型について考える技法です。例題の引数の型は Double です。Double を生成する必要性も確認済みです。入力から Double を生成するメソッドにどんなもの があるでしょうか?そのようなメソッドはたくさんあるので、ドメイン知識を活用し、呼ぶべ き正しい * メソッドを選択します。 def square(in: Double): Double = in * in 61
  37. 63

  38. ノート:メソッドの書き方についての手順 1. メソッドにおける入力と出力の型を確認する。 2. 与えられた入力例から期待されるメソッドの出力についてテストケースを記述する。 それらのケースを書くために assert 関数を利用する。 3. 下記のように本体に

    ??? を使用してメソッド宣言を記述する。 def name(parameter: type, ...): resultType = ??? 4. テストケースが失敗することをチェックするためにコードを実行する。 5. メソッドの本体を記述する。そのために下記のような2つの技法がある。 • 結果の型について、それのインスタンスをどう作成できるか検討する。 • 入力の型について、それをどう結果の型に変換できるか検討する。 6. コードを再実行し、テストケースをパスすることをチェックする。 64
  39. 2.6.1 条件式 条件式はいくつかの条件にもとづいて式を選択することを可能にします。 if (1 < 2) "Yes" else "No"

    // res: String = Yes 選択されなかった式は評価されません。 if (1 < 2) println("Yes") else println("No") // Yes 66
  40. 67

  41. ノート:条件式記法 if(condition) trueExpression else falseExpression • condition は Boolean 型の式

    • trueExpression は条件が true に評価されるときに評価される式 • falseExpression は条件が false に評価されるときに評価される式 69
  42. 73

  43. 2.7 まとめ 76 下記のような Scala の基本について簡潔に紹介しました。 • 値に評価される式 • 値に名前を与える宣言

    様々なオブジェクトのためにリテラルを書く方法、メソッド呼び出しや複合式で既存のも のから新しいオブジェクトを作る方法を見てきました。 また、メソッドとフィールドで構成される独自のオブジェクトを宣言することもできるように なりました。 次章ではオブジェクトを作成するためのテンプレートとしてクラスの宣言を見ていきます。 クラスはコードの再利用と類似するオブジェクトの共通型としての統一を可能にします。