前回の記事「Scalaのトレイトでプログラマをミックスインしてやんよ」では、Scalaの重要な機能であるトレイトの基本的な使い方から始まり、複数のトレイトを積み重ねた場合にどのような順番で線形化されるかについても紹介しました。今回は型のパラメータ化について紹介します。IDEで動作を確認してみました。今後本記事のサンプルコードは、どちらで確認しても問題はありませんが、対話的に実行でき、1文ごとにコードの結果が分かって便利なので、基本的にはREPLを用いて説明していきます。Scala!」』を参照してプロジェクトを作成して実行してください。REPLを使用する場合は、コンソール上でscalaコマンドを実行し、REPLを起動してください。Scalaにおける「型のパラメータ化」とは一般的にはコンストラクタやメソッドを使用するとき、引数を使用してパラメータ化します。型のパラメータ化とは、それと同じようにクラスやメソッドなどで使用する型そのものをパラメータ化して再利用性を高める機能です。JavaでのGenericsについて知りたい方は、記事「キュー構造をJavaで実装してジェネリック型を理解する」などをご覧ください。型パラメータを使ってみましょう。コレクションでよく使用するListは型パラメータを指定し、String型や自分で定義した型など、いろいろな型を指定できます。REPLでString型を格納するList型変数を定義します。c)「List[型名](初期値)」として、Listの型パラメータを指定しています。ここでは型パラメータのStringを明示的に指定していますが、指定しない場合でも型推論によりList[String]として判断されます。c)Listの先頭を取り出すと、ちゃんとString型として取得できます。a[Any]型と「型安全」しかし、型パラメータ名を指定しないと、誤ってString以外の要素を渡そうとした場合にList[Any]型として定義されてしまいます。1)String型以外の型を想定していなければ、おそらくsListを使用する個所のメソッド呼び出しでコンパイルエラーが発生して間違いに気付くことになるでしょう。定義時に型パラメータをString型として指定した場合、String型以外の要素を渡そうとすると、コンパイル時にエラーになります。List[String]("a","b",1)このように、型パラメータを適切に使えば、ScalaのListは「型安全(誤った型の状態を引き起こす処理や変換を許さない状態)」に操作できます。Scalaでの型の調べ方とキャスト下記のように、Listを型パラメータを指定せず、初期値でString型とInt型を格納した場合、List[Any]で定義されます。1)この場合、要素を任意の型で取り出したいときは、どうすればいいのでしょうか。Javaの場合、instanceof演算子でその変数の実際の型を調べたり、(型)変数とすることでキャストできます。{System.out.println((String)o);}Scalaの場合、Anyが持つisInstanceOfメソッドを使用することで、変数の実際の型を調べられます。true「isInstanceOf[型名]」として、その型名が合っていればtrue、そうでなければfalseが返ります。キャストはasInstanceOfメソッドで可能です。aしかし、これらのメソッドは実際あまり使いません。型の確認やキャストをしたい場合、連載第4回で解説した「パターンマッチ」を使った方がシンプルに記述できるからです。パターンマッチを検討してみてください。型パラメータの使い方は分かったので、次は型パラメータを使用したクラスを定義してみましょう。1つの型パラメータ「A」を取る、「MySample」というクラスを定義してみます。param}型パラメータは、クラス名とコンストラクタ引数の間に型パラメータ名の指定を追加します。上記の例でいうと、MySampleクラスは「A」という何らかの型を取るという意味です。型パラメータはカンマ区切りで、いくつでも記述可能です。Scalaにおいて型パラメータは、Aから順番に名前を付けることが慣習となっているようです。型パラメータを使ったクラスのインスタンス化ではMySampleクラスをインスタンス化して使用してみましょう。インスタンス化時に、[]を使用して型パラメータに実際の型を指定します。下記サンプルではMySampleの型パラメータAに対してStringを指定しています。helloこれでMySampleのparamフィールドはString型として使えるようになります。setメソッドはString型を受け取るようになり、getメソッドはString型を返すようになります。型パラメータを2つ指定するクラスを「new」でインスタンスする場合、少し変わった書き方ができます。型パラメータを2つ取る「OR」というクラスがあった場合には、クラス名を中央に書いてその前後に型パラメータを書けます。OR@4ee00c09ORという“演算子”を使っているようにも見えますが、実際には「OR」クラスをインスタンス化しています。次に、メソッドに対して型パラメータを指定してみましょう。クラスやトレイトと同じく、メソッドも型をパラメータ化できます。メソッドの場合、メソッド名と引数の間に型パラメータを指定します。メソッドの場合、メソッド名と引数の間に型パラメータを指定します。構文は下記のようになっています。関数本体では、型パラメータを1つ取れる関数funcを定義してみます。この関数は引数として受け取った値を、そのまま返すだけです。引数の型は型パラメータとして指定できます。A)Aでは、関数funcを使ってみましょう。メソッドを呼ぶときに型パラメータを指定しなくても、型推論によりうまく動作してくれます。hello上記の場合、func[String]("hello")と記述したことと同じ意味になります。型パラメータを明示的に指定するには、引数の前に[]で型を記述します。10ここでは型パラメータを使用したクラスやメソッドを定義して使ってみました。型パラメータをうまく使用することで汎用性が上がったり、コレクションを便利に扱えることが分かります。次ページでは型パラメータに制限を加える方法について紹介します。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。