我刚刚找到了Scala的类型类概念,并且非常喜欢它。问题我发现我发现的所有例子都把类型(对象)放在一个对象下(比如这里:http://danielwestheide.com/blog/2013/02/06/the-neophytes-guide-to-scala-part-12-type-classes.html)
也许这是错的,但我是每个班级有一个文件的朋友。所以我喜欢做的是将类型类放入几个文件中,这意味着每个实现都需要放入一个单独的对象中。这现在导致了问题"我需要手动导入每个实现。为了更好地澄清一个小例子:
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
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.like
object StringLike {
implicit object LikeStringLike extends Like[String] {
override def print(arg: String): Unit = println(s"STRING: $arg")
}
}
到目前为止这是有效的。我知道,Application中的通配符导入不是必需的,但这不是重点。如您所见,我需要在Application中导入StringLike和IntLike,否则它们不适用于Application对象。
那么可以通用的方式做到这一点,还是以这种方式做到这一点是完全不好的做法?
答案 0 :(得分:4)
你可以把你的暗示放在特征中,而不是对象
trait IntLike {
implicit object LikeIntLike extends Like[Int] {
def print(arg: Int): Unit = println(s"INT $arg")
}
}
然后让对象具有相同的名称,扩展这个特性,这将为您提供前面的内容,您可以单独导入每个内容。
object IntLike extends IntLike
您可以对类型类的所有其他实例执行相同的操作:
trait StringLike {
implicit object LikeStringLike extends Like[String] {
override def print(arg: String): Unit = println(s"STRING: $arg")
}
}
object StringLike extends StringLike
在另一个文件中,您可以将所有特征组合在一起:
object Implicits extends StringLike with IntLike
并仅导入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 { ... }
答案 1 :(得分:0)
非常感谢你的回答。但我还需要手动将新类型类添加到Implicits,不是吗?
出于简单原因,我不能使用then包对象:
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
...
}
}
由于似乎没有动态方法,我可以将所有类型类放入控制器对象中,然后可以导入。
或者我是否会错过理解包对象?