在 Scala 中将 Nil 和 List 作为 case 表达式 [英] Nil and List as case expressions in Scala

查看:45
本文介绍了在 Scala 中将 Nil 和 List 作为 case 表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码编译:

def wtf(arg: Any) = {  
  arg match {  
    case Nil => "Nil was passed to arg"  
    case List() => "List() was passed to arg"  
    case _ =>"otherwise"  
  }  
}

但是这个没有:

def wtf(arg: Any) = {  
  arg match {  
    case List() => "List() was passed to arg"  
    case Nil => "Nil was passed to arg"  
    case _ =>"otherwise"  
  }  
}  

case Nil => ... 被标记为无法访问的代码.为什么,在第一种情况下,行 case List() => ... 没有用相同的错误标记?

The line case Nil => ... is marked as unreachable code. Why, in the first case, the line case List() => ... is not marked with the same error?

推荐答案

实际的答案需要理解一个不幸的实现细节,我花了很多时间去发现.

The actual answer requires understanding an unfortunate implementation detail which cost me a lot of time to discover.

1) case List() 调用提取器,因为提取器调用任意函数,因此在一般情况下不可能进行穷举性/不可达性检查.到目前为止一切顺利,我们不能指望推翻停机问题.

1) case List() invokes an extractor, for which no exhaustivity/unreachability checking is possible in the general case because extractors invoke arbitrary functions. So far so good, we can't be expected to overturn the halting problem.

2) 早在编译器更狂野的西部"时代,如果将case List()"翻译成case List()",模式匹配的速度会大大加快(并且不会丢失穷举性检查)在早期编译器阶段case Nil",这样它就可以避免提取器.情况仍然如此,尽管它可以撤消,但显然很多人都被告知case List() => "非常好,我们不想突然对他们的所有代码进行悲观.所以我只需要找出一条出路.

2) Way back in the more "wild west" days of the compiler, it was determined that pattern matching could be sped up rather a lot (and not lose exhaustivity checking) if "case List()" were just translated to "case Nil" during an early compiler phase so it would avoid the extractor. This is still the case and although it could be undone, apparently lots of people have been told that "case List() => " is perfectly fine and we don't want to pessimize all their code all of a sudden. So I just have to figure out a road out.

您可以通过与其他类一起尝试来凭经验看到 List 具有特权.没有不可访问性错误.

You can see empirically that List is privileged by trying it with some other class. No unreachability errors.

import scala.collection.immutable.IndexedSeq
val Empty: IndexedSeq[Nothing] = IndexedSeq()
def wtf1(arg: Any) = {  
  arg match {  
    case Empty => "Nil was passed to arg"  
    case IndexedSeq() => "IndexedSeq() was passed to arg"  
    case _ =>"otherwise"  
  }  
}

def wtf2(arg: Any) = {  
  arg match {  
    case IndexedSeq() => "IndexedSeq() was passed to arg"  
    case Empty => "Nil was passed to arg"  
    case _ =>"otherwise"  
  }  
}  

这篇关于在 Scala 中将 Nil 和 List 作为 case 表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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