web-dev-qa-db-ja.com

Scala typeキーワード:複数のクラスで使用する最良の方法

Scalaに戻って、Haskellを書いた呪文の後、typeキーワードを使用してクラス定義をもう少し読みやすくしました。例えば:

type RestfulParams = Map[String, String]
def canonicalize(params: RestfulParams): String = { ... }

私が遭遇した問題は、これらの型定義がクラスまたはオブジェクト内に存在する必要があるということです-Haskellのような「ファーストクラスの市民」ではありません。クラスまたはオブジェクトの外部で型を定義しようとすると、コンパイラexpected class or object definition

私の問題は、パッケージ内の複数のクラスとオブジェクトでこれらのタイプを使用する方法です?私が今やったことは非常にugいようです:

object RestfulTypes { type RestfulParams = Map[String, String] etc }

そして、別のクラスファイルで:

import utils.{RestfulTypes => RT}
def get(resource: String, params: RT.RestfulParams): String = { ... }

これを行うためのより良い方法がありますか?そして偶然にScalaの達人は、クラス/オブジェクト内でのみ型を定義できるのは良いことか悪いことだと思いますか?

70
Alex Dean

パッケージオブジェクト は機能しますか?

記事から:

2.8まで、パッケージに入れることができるのはクラス、特性、およびスタンドアロンオブジェクトだけでした。これらは、パッケージの最上位に配置される最も一般的な定義ですが、Scala 2.8は、それらだけに限定しません。クラスの場合は、パッケージの最上位に置くこともできますパッケージ全体のスコープに含めるヘルパーメソッドがある場合は、パッケージの最上位に配置します。パッケージオブジェクトに定義を配置しますパッケージごとに1つのパッケージオブジェクトを持つことができますパッケージオブジェクトに配置された定義は、パッケージ自体のメンバーと見なされます。

パッケージオブジェクトscala には既に多くの型と値が含まれているため、独自の型に対して同じ手法を使用できると思います。

71
Ray Toal

この場合の良さを構成するものはわかりませんが、2つのオプションがあります。

特性の使用:( Scala's Selfless Trait Pattern

trait RestfulTypes {
  type Params = Map[String,String]
  //...
}

object MyRestService extends RestService with RestfulTypes { /* ... */ }

または、オブジェクトのメンバーをインポートして、パッケージのように効果的に使用します。

import util.RestfulTypes._
11
Kim Stebel

Younはパッケージオブジェクトを使用して、そこに型宣言を配置できます。そのパッケージをインポートすると、タイプ定義が利用可能になります。

例 :

//package myType
package object myType {type mine = List[String]}

パッケージオブジェクトは、オブジェクトプレフィックスなしで使用できるようにパッケージと同じ名前を持っていることに注意してください。つまり、myType.mineのように別の名前で名前を付けると、次のようになります。

//package myType
package object mainType {type mine = List[String]}

「パッケージ」をインポートするときにmainType.mineでアクセスできます

詳細情報: http://www.scala-lang.org/docu/files/packageobjects/packageobjects.html

7
firephil