从一个类映射到一个匹配的通用

从一个类映射到一个匹配的通用

问题描述:

我想创建一个从ClassTag到MyHelperClass [该类]的scala中的地图,像这样(它不编译,因为地图不支持这种元素方式匹配):从一个类映射到一个匹配的通用

import scala.reflect._ 
import scala.reflect.runtime.universe._ 

val MAP_CONSTANT = map[ClassTag[T], MyHelperClass[T]](
    classTag[SomeClass] -> helperForSomeClass, 
    classTag[AnotherClass] -> helperForAnotherClass, 
) 

有没有一种很好的方法来做到这一点?我需要编译器知道返回的帮助程序是与输入类标记相同的类的通用类。

我宁愿不做与之匹配的几起案件,因为

  • 这将是丑陋的代码
  • 这将是很难建立在这样的代码没有信心同样丑陋的测试
  • 比赛迭代检查每个条件,这可能很慢,许多可能的帮手

这被称为typeclass并更优雅地解决上下文边界和隐式参数。

trait MyHelperClass[T] { 
    def takeOverTheWorld: Unit = .. 
} 
object MyHelperClass { 
    def apply[T : MyHelperClass]: MyHelperClass[T] = implicitly[MyHelperClass[T]] 
} 

现在,所有你需要做的就是定义一堆帮手:为def x[T]()(implicit ev: MyHelperClass[T])

+0

这看起来非常有前途的

class X class Y object Helpers { implicit object XHelper extends MyClassHelper[X] { override def takeOverTheWorld: Unit = println("Hey I'm X") } implicit object YHelper extends MyClassHelper[Y] { override def takeOverTheWorld: Unit = println("Hey I'm actually an Y") } def doAction[T : MyHelperClass]: Unit = MyHelperClass[T].takeOverTheWorld doAction[X] // will print "Hey I'm an X" doAction[Y] // will print "Hey I'm actually an Y" } 

def x[T : MyHelperClass]是简写语法,但我有麻烦它工作。具体来说,我有一个通用的任何类型的T: 'process [T](data:Seq [T])(隐式帮手:MyHelperClass [T]):...' 我想抛出运行时if T不匹配助手,但我不能编译: '无法找到隐式值的参数助手:com ... MyHelperClass [_ $ 1]' – mwlon

+0

@mwlon为什么你会喜欢运行时间超过编译时间?从代码质量的角度来看,这毫无意义,我宁愿早点知道“我错了”。如果用户想为一个给定类型'T'实现一个'MyHelperClass',那么他们可以简单地'隐式对象bla自己扩展MyHelperClass [T]',所以你不能阻止人们添加帮助者,如果你所关心的。任何其他理由偏好运行时? – flavian

+0

假设我有一个X和Y的序列,并且希望将相应的隐式帮助应用于每个隐式帮助。如果我试图做 'val entries = Seq [_](new X(),new Y()); entries.foreach(entry => Helpers.doAction(entry))'我得到相同的错误。我怎样才能强制执行所有条目可以隐式转换为MyHelperClass的约束呢? – mwlon