scala – 案例类的隐式解析和伴随对象
我正在尝试向(我认为是)案例类的伴随对象添加隐式值,但是找不到此隐式值.
我正在尝试实现以下内容: package mypackage object Main { def main(args: Array[String]): Unit = { val caseClassInstance = MyCaseClass("string") val out: DataOutput = ... serialize(out,caseClassInstance) // the above line makes the compiler complain that there is no // Serializer[MyCaseClass] in scope } def serialize[T : Serializer](out: DataOutput,t: T): Unit = { ... } } object MyCaseClass { // implicits aren't found here implicit val serializer: Serializer[MyCaseClase] = ... } case class MyCaseClass(s: String) { // some other methods } 我在这里明确添加了包,以表明MyCaseClass案例类和对象都应该在范围内.我知道该对象实际上正在构建,因为如果我添加,我可以编译它 implicit val serializer = MyCaseClass.serializer to main(虽然特别是如果我添加import MyCaseClass.serializer). 我担心MyCaseClass对象实际上并不是case类的伴侣,因为如果我在对象上显式定义apply和unapply然后尝试在main中调用MyCaseClass.apply(“string”),编译器会给出以下内容错误: ambiguous reference to overloaded definition,both method apply in object MyCaseClass of type (s: String)mypackage.MyCaseClass and method apply in object MyCaseClass of type (s: String)mypackage.MyCaseClass match argument types (String) val a = InputRecord.apply("string") ^ 如果不可能采用这种方法,有没有办法在每次必须将其带入范围时使用带有case类的类型类而不创建隐式值? 编辑:我正在使用scala 2.10.3. 编辑2:以下是充实的例子: package mypackage import java.io.{DataOutput,DataOutputStream} object Main { def main(args: Array[String]): Unit = { val caseClassInstance = MyCaseClass("string") val out: DataOutput = new DataOutputStream(System.out) serialize(out,t: T): Unit = { implicitly[Serializer[T]].write(out,t) } } object MyCaseClass { // implicits aren't found here implicit val serializer: Serializer[MyCaseClass] = new Serializer[MyCaseClass] { override def write(out: DataOutput,t: MyCaseClass): Unit = { out.writeUTF(t.s) } } } case class MyCaseClass(s: String) { // some other methods } trait Serializer[T] { def write(out: DataOutput,t: T): Unit } 但这实际上是编译的.我在使用Scoobi的WireFormat [T]而不是Serializer时遇到了这个问题,但由于复杂性和Scoobi依赖性,无法提供简洁,可运行的示例.我将尝试创建一个更相关的示例,但似乎问题并不像我想象的那么普遍. 解决方法
事实证明,类型类实例实际上需要是隐式值,而不是对象.上面的MyCaseClass对象有效,因为它的序列化程序被赋值为隐式值.但是,这个实现
object MyCaseClass { implicit object MyCaseClassSerializer extends Serializer[MyCaseClass] { override def write(out: DataOutput,t: MyCaseClass): Unit = { out.writeUTF(t.s) } } } 因错误而失败 Main.scala:9: error: could not find implicit value for evidence parameter of type mypackage.Serializer[mypackage.MyCaseClass] serialize(out,caseClassInstance) ^ 在我的实际代码中,我使用辅助函数来生成Serializer [T](参见https://github.com/NICTA/scoobi/blob/24f48008b193f4e87b9ec04d5c8736ce0725d006/src/main/scala/com/nicta/scoobi/core/WireFormat.scala#L137).尽管函数具有自己的显式返回类型,但编译器未正确推断指定值的类型. 以下是使用此类Serializer-generator的问题的完整示例. package mypackage import java.io.{DataOutput,DataOutputStream} object Main { import Serializer._ def main(args: Array[String]): Unit = { val caseClassInstance = MyCaseClass("string") val out: DataOutput = new DataOutputStream(System.out) serialize(out,caseClassInstance) } def serialize[T : Serializer](out: DataOutput,t) } } object MyCaseClass { import Serializer._ // does not compile without Serializer[MyCaseClass] type annotation implicit val serializer: Serializer[MyCaseClass] = mkCaseSerializer(MyCaseClass.apply _,MyCaseClass.unapply _) } case class MyCaseClass(s: String) trait Serializer[T] { def write(out: DataOutput,t: T): Unit } object Serializer { // does not compile without Serializer[String] type annotation implicit val stringSerializer: Serializer[String] = new Serializer[String] { override def write(out: DataOutput,s: String): Unit = { out.writeUTF(s) } } class CaseClassSerializer[T,A : Serializer]( apply: A => T,unapply: T => Option[A]) extends Serializer[T] { override def write(out: DataOutput,t: T): Unit = { implicitly[Serializer[A]].write(out,unapply(t).get) } } def mkCaseSerializer[T,A : Serializer] (apply: A => T,unapply: T => Option[A]): Serializer[T] = new CaseClassSerializer(apply,unapply) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |