scala中的字符串伴随对象

时间:2017-03-29 09:04:50

标签: scala scala-implicits

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

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. 我可以使用implicits进行f(String)编译吗?
  2. 如果字符串不可能,那么具有伴随对象的类怎么样,我可以这样做:

    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编译吗?

3 个答案:

答案 0 :(得分:1)

  

我可以使用implicits进行f(String)编译吗?

没有。当然,您可以定义一个名为String的值,但它不会与String类型相关。

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

A.type必须是;它与类型参数A无关。

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

当然,如果你不坚持使用()代替[],那就变得微不足道了:

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

f1[String]
f1[TheClass]

答案 1 :(得分:1)

您可以为协同类型MyClass定义隐式实例,而不是为类型MyClass.type定义隐式实例。

implicit val TheClassConverter: Converter[MyClass.type] = new Converted[MyClass.type] {
  def perform = Converted("MyClass")
}

答案 2 :(得分: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)