成都网站建设设计

将想法与焦点和您一起共享

scala怎么匹配自定义泛型类型

这篇文章主要为大家展示了“scala怎么匹配自定义泛型类型”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“scala怎么匹配自定义泛型类型”这篇文章吧。

创新互联公司主要从事做网站、成都网站建设、网页设计、企业做网站、公司建网站等业务。立足成都服务崇州,10多年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:13518219792

我正在尝试使用模式匹配来检测基于   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怎么匹配自定义泛型类型”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联行业资讯频道!


标题名称:scala怎么匹配自定义泛型类型
网页链接:http://chengdu.cdxwcx.cn/article/gpojej.html