斯卡拉隐式转换(字符串到一个自定义的类和它的子类)
问题描述:
下面的代码,斯卡拉隐式转换(字符串到一个自定义的类和它的子类)
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"
的问题是如何从String
到TestBase
隐式转换和它的子类具有更加优雅和高效代码?(也许只是一个隐含的函数?)This is the Code I run in Scala REPL
答
你可以重写这一个像这样的隐式高清。
implicit def conv[A <: TestBase](str: String): A = {println(str); null.asInstanceOf[A] }
但是这取决于你是什么真正努力,有可能比将所有Strings
任何TestBase
一个更好的解决方案。
编辑: 出于某种原因,斯卡拉似乎没有选择隐式转换时要考虑的类型约束。它会变得怪异:
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]
^
所以编译器提供的NotTest <:< TestBase
一个实例bla2Test
但没有实例存在。
而当你想检查类型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"
^
另外,**类NotTest(STR:字符串)**; ** val notTest:NotTest =“abc”**不应通过编译,因为NotTest不是TestBase的子类。 – Hario