温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2021-06-12 11:13:57 来源:亿速云 阅读:267 作者:小新 栏目:编程语言

这篇文章主要为大家展示了“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怎么匹配自定义泛型类型”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI