成らぬは人の為さぬなりけり

エンジニアライフをエンジョイする為のブログ

Scala2.10の新機能を勉強する その5 ValueClass(制約編)

前回、ValueClassの制約に関して、後回しにしてしまったので、
今回は、ValueClassの制約について勉強しました。

環境

ValueClassの制約

前回までの話でも多少でてきて居ましたが、
JVMに値クラス(ValueClass)という概念が存在しない為、
色々と制約があるそうです。

値クラスと汎用トレイト - Scala Documentation

  1. ただ1つの public で値クラス以外の型の val パラメータを持つプライマリコンストラクタのみを持つことができる。
  2. specialized な型パラメータを持つことができない。
  3. 入れ子のローカルクラス、トレイト、やオブジェクトを持つことがでない。
  4. equals や hashCode メソッドを定義することができない。
  5. トップレベルクラスか静的にアクセス可能なオブジェクトのメンバである必要がある。
  6. def のみをメンバとして持つことができる。特に、lazy val、var、val をメンバとして持つことができない。
  7. 他のクラスによって拡張されることができない。

なるほど。
一つ一つコードを書きながらやって行きたいと思います。

ただ1つの public で値クラス以外の型の val パラメータを持つプライマリコンストラクタのみを持つことができる。

はい、この話は、若干前回まで出てきていました。
まとめると、

という事かと思います。
では、コードを書いてみます。

追加で、パラメータを名前渡しにしてみました。
値クラスはlazy valを持てないので、名前渡しもダメなようです。

specialized な型パラメータを持つことができない。

s、、、specializeって何?!
すいません、初めて知りました。
Scala2.8からあるようです。
Scala @specializedメモ(Hishidama's Scala @specialized Memo)
つまり、型パラメータに「プリミティブ型だけ許す!」という制約を与えるアノテーションですかね。
一見、プリミティブ型なので、あれば、むしろ値クラス向いてるんではなかろうか、と思ったんですが、
何故specializeな型パラメータはダメなんでしょうか?
※すっごい気になったんですが、とりあえず先に進みます。

入れ子のローカルクラス、トレイト、やオブジェクトを持つことがでない。

これは以前もサンプルを書きましたが、
今回改めて書いてみます。

equals や hashCode メソッドを定義することができない。

equals、hashCodeは実装がほぼ空でもコンパイルエラー。
[gist: 5319662]

トップレベルクラスか静的にアクセス可能なオブジェクトのメンバである必要がある。

これは、クラスが入れ子になると、自分を内包するクラスへの参照を
コンストラクタの第2引数に受け取る必要があるからだそうです。

def のみをメンバとして持つことができる。特に、lazy val、var、val をメンバとして持つことができない。

これは以前も出てきたので、飛ばします。

他のクラスによって拡張されることができない。

値クラスは必ずfinalクラスになる為、拡張するこができません。

なるほど。

まとめ

値クラスに関してはん日本語ドキュメントが非常に読みやすく勉強になりました。
やはり、なんとなくシンタックス覚えて書くのと、
裏の動きを把握して書くのと、全然違うなと改めて思います。

関数型、に関してももっと勉強せねば、、、、