在 Scala 中,如何针对具有类型参数的类型测试“Any"对象的类型? [英] In Scala, how to test the type of an 'Any' object against a type with type parameter?

查看:62
本文介绍了在 Scala 中,如何针对具有类型参数的类型测试“Any"对象的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获得一种类型安全的方式来转换解析 JSON 字符串的结果.我想检查一个字段是 Map[String, any] 还是普通字符串.我的第一次尝试是

I am trying to get a type-safe way of converting the result of parsing a JSON string. I want to check whether a field is Map[String, any] or a plain string. My first attempt is

def test(x:Any) = {
    x match {
        case m:Map[String,Any] => ...
        ...
}

这会导致类型模式 Map[String,Any] 中的非变量类型参数 String 未被检查,因为它被擦除消除了"

This causes "non-variable type argument String in type pattern Map[String,Any] is unchecked since it is eliminated by erasure"

查看 TypeTag 和 ClassTag 的文档,我找不到实现此目的的好方法.以下代码不会导致警告,但我想知道它为什么会起作用.

Looking through the document of TypeTag and ClassTag, I could not find a good way to accomplish that. The following code does not cause the warning, but I wonder why it works.

type StringMap = Map[String,Any]
def test(x:Any) = {
    x match {
        case m:StringMap => ...
        ...
}

推荐答案

这是一个错误.它已在 2.11 中修复:

It was a bug. It's fixed in 2.11:

scala> type StringMap = Map[String, Any]
defined type alias StringMap

scala> (Map(4 -> true): Any) match {
     |   case m: StringMap => true
     |   case _ => false
     | }
<console>:10: warning: non-variable type argument String in type pattern scala.collection.immutable.Map[String,Any] (the underlying of StringMap) is unchecked since it is eliminated by erasure
                case m: StringMap => true
                        ^
res0: Boolean = true

它不起作用的原因是由于擦除,您无法分辨类型参数是什么.如果你想确定它是一个 Map[String, Any] 而不是其他类型的地图,你必须去检查每个键并确保它是一个 String.

The reason it doesn't work is that you can't tell, due to erasure, what the type arguments were. If you want to be sure it's a Map[String, Any] instead of some other kind of map, you have to go check every key and make sure it's a String.

case m: Map[_,_] if m.keySet.forall(_.isInstanceOf[String]) => 
  m.asInstanceOf[Map[String,Any]]

这篇关于在 Scala 中,如何针对具有类型参数的类型测试“Any"对象的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆