gpt4 book ai didi

scala - 如何匹配自定义泛型类型?

转载 作者:行者123 更新时间:2023-12-01 06:08:12 25 4
gpt4 key购买 nike

我正在尝试使用模式匹配来检测基于 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 .下面的代码是复制粘贴的,除了它使用 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 = true
Is int = false
Found String
------------
Is string = false
Is int = true
Found 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.5JDK 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]

通过查看字节码,编译器使用传递给方法 ( $evidence ) 的 TypeTag。

一个(有限的)解决方法可能是使用 ru.definitions.IntTpe :
case fooStr: Foo[Int @unchecked] if ru.typeOf[A] =:= ru.definitions.IntTpe =>
println("That's an Int")

关于scala - 如何匹配自定义泛型类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35087731/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com