2014年4月17日木曜日

Programming in Scala, First Edition: Chapter 11

11. Scala's Hierarchy
  scalaのクラス階層の全体像を見る。
  Any: top
    全てのクラスのスーパークラス。どんなクラスも受け入る。universal
  Null, Nothing: bottom
    全てのクラスのサブクラス。どんなクラスにも受け入れられる。

11.1 Scala's class hierarchy
   Any
     全てのクラスのスーパークラス。
     ==, !=, equals, haCode, toString のmethodがある。
       ==, != はfinalでoverride不可能。
         == のoverrideされている様に見えても、実際はequalsをoverrideしている。
   AnyVal extends Any
     built-in value classのスーパークラス
     Byte, Short, Char, Int, Long, Float, Double, Boolean, and Unit
     Unit以外はjavaのprimitive, value class
     このクラスのインスタンスはリテラルのみ。new出来ない。
       abstractとfinalを組み合わせることで実現。
     Unitはjavaのvoidとほぼ同じ。インスタンスは()のみ。Section 7.2参照。
     value classはAnyValの直系。互いに上下関係は無い。
       代わりにimplicit conversionsが定義されている。
         Longの型にIntの値を入れることが出来るようにしている。
       更に多くのメソッドが使えるが、これは例えばscala.runtime.RichInt定義されている。
         "booster classes"
         implicit conversionsでIntをRichIntのメソッドにも使えるようにする。
   AnyRef extends Any
     全ての参照クラスのスーパークラス
     java.lang.Objectとして実装されている。どちらでも同じ。どちらも使える。
       scalaではAnyRefと書くことを当然推奨。
     scalaのクラスはScalaObjectと言うtraitも継承している。
       ここはjavaのクラスと異なる。
       例外を効率よく扱うために定義されている。
       唯一のメソッドは$tag。内部向け。パターンマッチングの高速化用。

11.2 How primitives are implemented
  整数はjavaと同じように32bitで格納している。
    JVM上で実行する上で効率的
    javaのライブラリとの互換性
    +や*もjavaの組み込みを使っている。
  "backup" class として java.lang.Integer を使っている。
    javaのオブジェクトの様に扱わなければいけない時はいつでも。
    toStringを使うときやAnyの型に入れる時等。
      透過的に"boxed integers"である java.lang.Integer に変換される。
        これはjava 5のauto-boxingとほぼ同様。
        scalaの方がより隠蔽されていはいる。
  scalaではAnyRefの==はequalsを呼んでいて、サブクラスでoverrideされる。
    通常は参照の比較ではなくて内容の比較が実装されている。
    したがって違う参照でも値が同じならtrueになる。
  参照の比較にeq, neを使う。
  同一性についてはChapter 28で更に詳しく扱う。

11.3 Bottom types
  scala.Null, scala.Nothingはクラス階層の一番下に位置する。
    全てのクラスのサブクラスとして振舞う。
  オブジェクト指向的な型階層の"corner cases"に統一的な方法で対処するため。
  Nullはすべてのリファレンスクラスのサブクラス
    Valueクラスのサブクラスとしてはふるまえない。
  Nothingはすべてのクラスのサブクラス
    通常は値を返さないと言う場合に使う。
    (x: Int) => if (x == 0) 0 else throw new RuntimeException("hoge")
    Int => Int
    戻り値の型がIntなのはthrowの戻り値の型がNothingのため。
    if (...) Int  else Nothing extends Int
    が成り立つので、NothingがIntのup castされて全体がIntになる。

11.4 Conclusion
  topとbottomのクラスと全体の階層を見た。
  次は trait による mixin composition

0 件のコメント:

コメントを投稿