Scala 隐式转换(字符串到自定义 class 及其子class)

Scala implicit conversion(String to a custom class and its subclass)

这是代码,

trait TestBase{}

class TestA(str:String) extends TestBase

class TestB(str:String) extends TestBase

class TestC(str:String) extends TestBase

implicit def mystr2TestA(str:String):TestA = {println(str);null.asInstanceOf[TestA]}

implicit def mystr2TestB(str:String):TestB = {println(str);null.asInstanceOf[TestB]}

implicit def mystr2TestC(str:String):TestC = {println(str);null.asInstanceOf[TestC]}

val testA:TestA = "abc"

val testB:TestB = "abc"

val testC:TestC = "abc"

问题是如何用更优雅高效的代码创建从StringTestBase及其子类的隐式转换?(也许只有一个隐式函数?)This is the Code I run in Scala REPL

您可以像这样将其重写为一个隐式定义。

implicit def conv[A <: TestBase](str: String): A = {println(str); null.asInstanceOf[A] }

但是根据您真正的尝试,可能有比将所有 Strings 转换为任何 TestBase.[=18 更好的解决方案=]


编辑: 出于某种原因,Scala 在选择隐式转换时似乎没有考虑类型约束。它变得更加奇怪:

scala> implicit def bla2Test[A](str: String)(implicit ev: A <:< TestBase): A = null.asInstanceOf[A]
warning: there were 1 feature warning(s); re-run with -feature for details
bla2Test: [A](str: String)(implicit ev: <:<[A,TestBase])A

scala> val notTest: NotTest = "str"
notTest: NotTest = null

scala> implicitly[NotTest <:< TestBase]
<console>:15: error: Cannot prove that NotTest <:< TestBase.
              implicitly[NotTest <:< TestBase]
                        ^

因此编译器向 bla2Test 提供了一个 NotTest <:< TestBase 的实例,但不存在实例。

当你想检查类型时 A:

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

scala>  implicit def bla2Test[A <: TestBase](str: String)(implicit tag: TypeTag[A]): A = { println(tag); null.asInstanceOf[A] }
warning: there was one feature warning; re-run with -feature for details
bla2Test: [A <: TestBase](str: String)(implicit tag: reflect.runtime.universe.TypeTag[A])A

scala> val notTest: NotTest = "str"
<console>:21: error: type mismatch;
 found   : String("str")
 required: NotTest
       val notTest: NotTest = "str"
                              ^

scala> val notTest: TestBase = "str"
<console>:20: error: macro has not been expanded
       val notTest: TestBase = "str"
                               ^