您好,登录后才能下订单哦!
这篇文章主要为大家展示了“scala怎么匹配自定义泛型类型”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“scala怎么匹配自定义泛型类型”这篇文章吧。
我正在尝试使用模式匹配来检测基于 this answer的我自己的自定义类型的泛型类型.
作者提供的代码按预期工作:
import scala.reflect.runtime.{universe => ru} def matchList[A: ru.TypeTag](list: List[A]) = list match { case strlist: List[String @unchecked] if ru.typeOf[A] =:= ru.typeOf[String] => println("A list of strings!") case intlist: List[Int @unchecked] if ru.typeOf[A] =:= ru.typeOf[Int] => println("A list of ints!") } matchList(List("a", "b", "c")) matchList(List(1,2,3))
正确显示:
A list of strings! A list of ints!
现在基于此我试图应用相同的模式来检测我的自定义类Foo的泛型类型.下面的代码是copy-pased,除了它使用Foo而不是List:
import scala.reflect.runtime.{universe => ru} class Foo[T](val data: T) def matchFoo[A: ru.TypeTag](foo: Foo[A]) = { println("Is string = " + (ru.typeOf[A] =:= ru.typeOf[String])) println("Is int = " + (ru.typeOf[A] =:= ru.typeOf[Int])) foo match { case fooStr: Foo[String @unchecked] if ru.typeOf[A] =:= ru.typeOf[String] => println("Found String") case fooInt: Foo[Int @unchecked] if ru.typeOf[A] =:= ru.typeOf[Int] => println("Found Int") } } matchFoo(new Foo[String]("str")) println("------------") matchFoo(new Foo[Int](123))
只有这次它输出的不是我所期望的:
Is string = trueIs int = falseFound String ------------ Is string = falseIs int = trueFound String // wth?
第二个调用matchFoo(new Foo [Int](123))如何显示Found String?正如你所看到的,我甚至明确地印出了比赛条件,他们很好.
在线代码:http://goo.gl/b5Ta7h
编辑:
我通过将匹配条件提取到变量中来实现它:
def matchFoo[A: ru.TypeTag](foo: Foo[A]) = { val isString: Boolean = ru.typeOf[A] =:= ru.typeOf[String] val isInt: Boolean = ru.typeOf[A] =:= ru.typeOf[Int] println("Is string = " + isString) println("Is int = " + isInt) foo match { case fooStr: Foo[String @unchecked] if isString => println("Found String") case fooInt: Foo[Int @unchecked] if isInt => println("Found Int")} }
在线代码:http://goo.gl/mLxYY2
但在我看来,原始版本也应该有效.我不认为我在这里缺少运算符优先级,因为将条件包装到括号中也没有帮助.
它是Scala中的错误吗?我正在使用Scala SDK v.2.11.5和JDK v.1.8.0_25.在线CodingGround使用Scala SDK v.2.10.3.
编辑2:
我已经在Scala的bugtracker中打开了一个问题.你可以投票支持here.
这看起来非常像编译器中的一个错误,它无法解析正确的隐式(可能是@unchecked的存在?).
case fooStr: Foo[String @unchecked] if ru.typeOf[A] =:= ru.typeOf[String] => println(implicitly[TypeTag[String]]) // will print TypeTag[Int]
通过查看字节代码,编译器使用传递给方法的TypeTag($evidence).
(有限的)解决方法可能是使用ru.definitions.IntTpe:
case fooStr: Foo[Int @unchecked] if ru.typeOf[A] =:= ru.definitions.IntTpe => println("That's an Int")
以上是“scala怎么匹配自定义泛型类型”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。