模式匹配时不会发生从Array到WrappedArray的隐式转换

时间:2017-07-26 20:33:10

标签: arrays scala

在这个例子中:

a_1

发生隐式转换,cp input1.dat orig1.dat cp input2.dat orig2.dat for f in a_* ; do sed "s/a_1/$f/g" orig1.dat > input1.dat sed "s/a_1/$f/g" orig2.dat > input2.dat myprogram -i input1.dat done 转换为scala> val a: Seq[Int] = Array(1,2,3) a: Seq[Int] = WrappedArray(1, 2, 3) ,扩展为Array,如下所述:Arrays Scala Doc

但是在这里:

WrappedArray

代码失败了:

Seq

隐式转换没有发生,为什么?

1 个答案:

答案 0 :(得分:3)

Burak Emir给出了语言设计决定的理由,即禁止模式匹配中的隐式转换(以下引自www.scala-archive.org):

  

1)类型检查模式依赖于静态信息(如同所有地方一样)   否则在编译器中)。在模式的情况下,"期望类型"是   传播下来,以便键入变量绑定模式等   通常验证模式是有意义的。该   当然,预期的类型开始与审查员(又名选择器)   表达式,即匹配的内容)。

     

2)模式匹配的翻译使用(几乎)所有方法   可以避免冗余类型测试。这意味着,那个案子   在源代码中出现得到"压缩"成为一种决策树   图。这后来被转换为代码。

     

输入隐式转化。让scrutinee是一个不同的类型   然后模式意味着我们不能在模式中使用预期的类型。   因此,我们必须独立于类型来键入检查模式   各种类型的scrutinee。

     

仅此一点可能仍然可行(在这里小心,谁可以预见毛茸茸的   与序列模式的互动等)。我们可以说,模式有一个   类型独立于预期的类型,类型检查将看到   小组委员会的类型是否符合模式类型   (可能在应用一些隐式转换后)。

     

但事实证明这是一个非规范。

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

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

似乎真正需要的是应用视图"按需要",意思   "内部"模式匹配。

     

这与执行任务2)的本算法发生冲突。在场   隐式转换,模式匹配的任务实际上是推送的   更深层次,因为最外层的模式总是匹配(那里是a   毕竟转换)。这实现起来非常烦人   指定,因为模式有和模式没有隐式转换   从scrutinee类型可能会混合,如

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

假设顶级" Foo"永远不会进入" Bar"案件   现在无效(毕竟还有转换)。一个基本上失去了所有   希望优化最外层。而目前的匹配   将加入模式1和3的其余部分,一个假设的匹配器   隐式调用无法设计为这样做,因为它会违反   第一场比赛政策。