0

给定一个具有“转换器”的类型,我想使用该类型的伴随对象对方法调用进行自动转换。也就是说,给定以下定义,

case class Converted(name: String)

trait Converter[A] {
  def perform: Converted
}

implicit val StringConverter = new Converter[String] {
  def perform = Converted("String")
}

使以下代码工作:

implicit def toConverter(a: String.type): Converted = 
  implicitly[Converter[String]].perform // Error: `Found String.type, required AnyRef`

def f(needsConverted: Converted) = ???

f(String) // <- That's what I would like to be able to write.

但这失败了,两次转换尝试都失败了。请注意,我无法更改f,因为它是由第三方库提供的并且其中有很多。

  1. 我可以f(String)使用隐式进行编译吗?

如果字符串不可能,那么具有伴生对象的类呢,我一般可以这样做吗:

object TheClass

case class TheClass()

implicit val TheClassConverter = new Converter[TheClass] {
  def perform = Converted("TheClass")
}

implicit def toConverter[A: Converter](a: A.type): Converted =
  implicitly[Converter[A]].perform // Error: `Not found value A`

implicit def toConverter(a: TheClass.type): Converted = 
  implicitly[Converter[TheClass]].perform // This works but is not generic

f(TheClass) // This works.
  1. 我可以先toConverter编译吗?
4

3 回答 3

1

我可以使用隐式编译 f(String) 吗?

不。当然,您可以定义一个名为 的值String,但它与 type 无关String

implicit toConverter[A: Converter](a: A.type): Converted =
    implicitly[Converter[A]].perform

AinA.type必须是一个;它与类型参数无关A

事实上,就 Scala 的类型系统而言,类/特征与其伴生对象之间没有任何关系。所以你不能做你想做的事情。

当然,如果你不坚持使用()而不是[],它变得微不足道:

def f1[A: Converter] = f(implicitly[Converter[A]].perform)

f1[String]
f1[TheClass]
于 2017-03-29T12:24:31.743 回答
1

MyClass您可以为伴生类型定义一个隐式实例,而不是为该类型定义一个隐式实例MyClass.type

implicit val TheClassConverter: Converter[MyClass.type] = new Converted[MyClass.type] {
  def perform = Converted("MyClass")
}
于 2017-03-29T12:33:30.453 回答
0

不确定,您要完成什么,但以下对我有用

case class Converted(name: String)

trait Converter[A] {
  def perform: Converted
}

implicit def toConverted(name: String) = Converted("String")
implicit def toIntConverted(int: Int) = Converted("Int")

def f(needsConverted: Converted): String = needsConverted.name

f("some")
f(5)
于 2017-03-29T09:34:10.570 回答