【问题标题】:match tuple with null将元组与 null 匹配
【发布时间】:2010-01-08 01:13:05
【问题描述】:

我不明白为什么以下情况不匹配。 Null 应该是 Any 的一个实例,但它不匹配。有人可以解释发生了什么吗?

val x = (2, null)
x match {
    case (i:Int, v:Any) => println("got tuple %s: %s".format(i, v))
    case _ => println("catch all")
}

prints catch all

谢谢。

【问题讨论】:

    标签: scala null pattern-matching tuples


    【解决方案1】:

    这与指定的完全一致。

    Type patterns consist of types, type variables, and wildcards.
    A type pattern T is of one of the following forms:
    
    * A reference to a class C, p.C, or T#C.
    This type pattern matches any non-null instance of the given class.
    

    有趣的是,null 是 Any 的成员。它是除 AnyVal 和 Nothing 之外的所有类型的成员。

    【讨论】:

    • 我认为这个选择的动机是它与 JVM 上“instanceof”字节码的行为相匹配。
    • 那,让 null 通过会完全糟透了。你必须有一个淫秽的零容忍度才能去寻找动机!
    • "Obscene null tolerance" 与否,有一个论点认为类型模式 "x: T" 最自然和最直接的含义是匹配类型 T 的任何成员。例如,它会避免像“val x: Any = null”这样的违规行为——很好,但是“val (x: Any, y: Any) = (null, null)”——MatchError。这也“完全糟透了”。我并不是说 Scala 做出了错误的选择,也不是说它特别重要,因为惯用的 Scala 避免使用 null。
    • 这是一个糟糕的例子,因为该问题与 null 无关。 "val (x: Int, y: Long) = (5, 5)" 也因匹配错误而失败。无论如何,如果您使用 null 的方式出现这种情况,我建议您做错了。
    • 恐怕我不关注你了。我想你的例子失败了,因为第二个 5 是类型推断为 Int,所以它没有通过运行时类型测试,但这似乎不适用于我的例子。
    【解决方案2】:

    您是否尝试过将v 占位符用于任何东西

    val x = (2, null)
    x match {
        case (i:Int, v) => println("got tuple %s: %s".format(i, v))
        case _ => println("catch all")
    }
    

    【讨论】:

      【解决方案3】:

      这是指定的(Scala 参考 2.7,第 8.2 节):

      对 C、p.C 或 T#C 类的引用。 此类型模式匹配给定类的任何非空实例。 注意类的前缀,如果 它是给定的,与 确定类实例。为了 例如,模式 p.C 仅匹配 C类的实例 以路径 p 作为前缀创建。

      【讨论】:

        【解决方案4】:

        我只是在这里猜测,因为我不是 scala 专家,但根据 scala 中 Any 类的documentation,我认为由于 null 不是对象,它不会派生自 Any 和因此与第一个列出的情况不匹配。

        添加下面的代码示例。它在运行时会打印“其他内容”。

        val x = (2, null)  
        x match {  
            case (i:Int, v:Any) => println("got tuple %s: %s".format(i, v))  
            case (i:Int, null) => println("something else %s".format(i))
            case _ => println("catch all")  
        }  
        

        经过更多研究,似乎 null 应该与任何意义相匹配,documentation 说它扩展了 AnyRef,它扩展了 Any。

        编辑:就像其他人所说的那样。第一种情况故意与 null 不匹配。它在文档中指定。

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-18
        • 2014-01-09
        • 1970-01-01
        • 1970-01-01
        • 2018-04-15
        • 1970-01-01
        • 1970-01-01
        • 2017-11-26
        相关资源
        最近更新 更多