2016-04-17 13 views
2

私はScalaの型クラスの概念を見つけましたが、実際には非常に好きです。私が見つけたすべての例では、1つのオブジェクトの下に型クラス(オブジェクト)が置かれているという問題があります(http://danielwestheide.com/blog/2013/02/06/the-neophytes-guide-to-scala-part-12-type-classes.html複数の暗黙的オブジェクトからの自動インポート

多分これは間違っていますが、ですから、私がしたいのは、型クラスをいくつかのファイルに入れて、それぞれの実装を別々のオブジェクトに入れる必要があるということです。これで、すべての実装を手動でインポートする必要がある「問題」が発生するようになりました。ここで小さな例よりよく明確にする: -

package sth.like 

trait Like[T] { 
    def print(arg: T) 
} 

-

package sth.like 

object IntLike { 
    implicit object LikeIntLike extends Like[Int] { 
     def print(arg: Int): Unit = println(s"INT $arg") 
    } 
} 

-

package sth 

import sth.like.Like 
import sth.like.StringLike._ 
import sth.like.IntLike._ 

object Application extends App { 
    def t[T](arg: T)(implicit l: Like[T]) = { 
     l.print(arg) 
    } 

    t(1) 
    t("Blub") 
} 

package sth.like 

object StringLike { 
    implicit object LikeStringLike extends Like[String] { 
     override def print(arg: String): Unit = println(s"STRING: $arg") 
    } 
} 

をこれは、これまでに動作します。私は知っている、アプリケーションでのワイルドカードのインポートは必要ではありませんが、それはポイントではありません。ご覧のとおり、ApplicationでStringLikeとIntLikeの両方をインポートする必要があります。そうしないと、Applicationオブジェクトでは使用できないためです。

これを一般的な方法で行うことは可能ですか、そうすることは完全に悪い習慣ですか?

答えて

3

あなたは以前、あなたが個別に暗黙的にインポートすることができていた何を与えることになる、この特性を拡張し、特性、ないオブジェクトの内側に

trait IntLike { 
    implicit object LikeIntLike extends Like[Int] { 
    def print(arg: Int): Unit = println(s"INT $arg") 
    } 
} 

をご暗黙を配置し、同じ名前のオブジェクトを持つことができます。

object IntLike extends IntLike 

あなたは型クラスの他のすべてのインスタンスに対して同じ操作を行うことができます。

object Implicits extends StringLike with IntLike 

とインポート:あなたはこのようにすべての特徴を一緒に組み合わせることができ、

trait StringLike { 
    implicit object LikeStringLike extends Like[String] { 
    override def print(arg: String): Unit = println(s"STRING: $arg") 
    } 
} 

object StringLike extends StringLike 

、別のファイルにスコープ内のすべての暗黙的な内容を望む場合は、Implicitsオブジェクトだけです。

package sth 

import sth.like.Like 
import sth.like.Implicits._ 

object Application extends App { 
    def t[T](arg: T)(implicit l: Like[T]) = { 
    l.print(arg) 
    } 

    t(1) 
    t("Blub") 
} 

必要に応じて、あなたは

object Application extends App with StringLike with IntLike { ... } 

あるいは

trait Implicits extends StringLike with IntLike 
object Implicits extends Implicits 

object Application extends App with Implicits { ... } 
0

を行うに必要な特性をミックスインすることができ、あなたの答えをどうもありがとうございました。しかし、新しいタイプのクラスをImplicitsに手動で追加する必要がありますか?

は、私はここのようなシンプルさの理由のため、パッケージオブジェクトを使用できませんでした:

http://naildrivin5.com/scalatour/wiki_pages/PackageObjects/

私はこの部分を意味する:

package opower { 
    package object controller { 
     type Secured = org.springframework.security.access.annotation.Secured 
     type Controller = org.springframework.stereotype.Controller 
     ... 
    } 
} 

私がちょうどコントローラオブジェクトにすべてのタイプのクラスを入れることができますし、この後、インポートができた動的な方法がないようですので。

また、パッケージオブジェクトを紛らわしいですか?

関連する問題