从阵列到WrappedArray隐式转换时的模式匹配

问题描述:

在这个例子中不会发生:从阵列到WrappedArray隐式转换时的模式匹配

scala> val a: Seq[Int] = Array(1,2,3) 
a: Seq[Int] = WrappedArray(1, 2, 3) 

隐式转换发生,Array转换为WrappedArray延伸Seq,如下解释:Arrays Scala Doc

但这里:

object MyObject { 

    def main(args: Array[String]): Unit = { 

    val a = Array(1,2,3) 
    // val a: Seq[Int] = Array(1,2,3) if added explicitly works 

    val result = a match { 
     case Seq(
     first, 
     second, 
     third 
    ) => (first, second, third) 
    } 
    println(result) 
    } 
} 

该代码失败:

Error:(9, 15) scrutinee is incompatible with pattern type; 
found : Seq[A] 
required: Array[Int] 
     case Seq(

隐式转换不会发生,为什么?

+0

作为一个实用的解决方案,您可以随时“检索”您的数组。 'toSeq'方法不会构造一个新的集合,所以它只会包装数组。来源:http://www.scala-lang.org/api/2.12.1/scala/Array.html#toSeq:Seq [A] –

布拉克埃米尔给了一个理由来模式匹配不允许隐式转换(以下是从www.scala-archive.org报价)的语言设计决定:

1)类型检查模式依赖于静态信息(喜欢到处 其他在编译器中)。在模式的情况下,“预期类型”是向下传播的,以便键入可变绑定模式,并且更多地通常验证该模式是有意义的。当然,预期类型开始于监票人(也就是选择器 表达式,也就是匹配的内容)。

2)模式匹配的翻译使用(几乎)每种方式可以避免多余的类型测试 。这意味着源代码中存在的案例 被“压缩”成一种决策树 图。这后来被翻译成代码。

输入隐式转换。让监票人的类型不同 那么模式意味着我们不能在模式中使用预期的类型。 因此,我们必须键入检查模式,而不管检查者的类型为 。

这可能仍然是可行的(小心在这里,谁可以预见毛发 与序列模式的互动等)。我们可以说,模式具有独立于预期类型的​​ 类型,并且类型检查将会看到 监察者的类型是否符合模式类型 (可能在应用某种隐式转换之后)。

但是这原来是一个非规范。

implicit def fbTypeToFoo ... 
implicit def fbTypeToBar ... 

fb match { 
    case Foo(...) => 
    case Bar(...) => 
} 

什么似乎真的需要是“需要通过”申请的意见,这意味着 “内部”的模式匹配。

这与本任务执行任务2)的冲突。在存在 隐式转换的情况下,模式匹配的任务实际上会将一个 级别推得更深,因为最外层的模式将始终匹配(毕竟有一个 转换)。这是很烦人的实现和 指定,因为有花纹和图案,而不从scrutinee类型隐式转换 可能会被混合,就像在

implicit def FooToBar... 
myFoo match { 
    case Foo(...) 
    case Bar(...) 
    case Foo(...) 
} 

假设有一个顶级“富“永远不会进入”酒吧“的情况 现在是无效的(毕竟有转换)。基本上失去了所有最优层次的希望。尽管当前匹配器 将加入模式1和3的其余部分,但带有隐式调用的假设匹配器 不能设计为这样,因为它违反了第一个匹配策略 。