2

以下代码无法编译:

scala> case class T3( x:Int,y:Int,z:Int) { def foreach[U](f:((Int,Int,Int)) => U) = f( (x,y,z) ) }
defined class T3

scala> for ( (x,y,z) <- T3(1,2,3) ) { println (x,y,z) }
<console>:10: error: value filter is not a member of T3
              for ( (x,y,z) <- T3(1,2,3) ) { println (x,y,z) }
                                 ^

我不明白为什么这段代码需要过滤器,因为它总是匹配的?

编辑 对于我的问题,添加一个无意义的过滤器实现就足够了:

scala> case class T3( x:Int,y:Int,z:Int) { def foreach[U](f:((Int,Int,Int)) => U) = f( (x,y,z) )
     | def filter(p: ((Int,Int,Int)) => Boolean) = this }
defined class T3

scala> for ( (x,y,z) <- T3(1,2,3) ) { println (x,y,z) }
(1,2,3)

scala> 
4

2 回答 2

2

根据Scala 语言规范,除非模式是“无可辩驳的”,否则生成器p <- e将被转换为调用。withFilter一个模式不可辩驳的三个条件:

  1. p是可变模式。

显然,情况并非如此。

  1. p是一个类型化的模式x : T''T <: T',其中e : T.

同样,这显然不是这种情况。

  1. p是构造函数模式c(p1,...,pn),类型T是类的实例,类型c的主构造函数(第 5.3 节)T具有参数类型T1, ..., Tn,并且每个类型pi都是无可辩驳的Ti

这里的问题是,虽然(x,y,z)是 的构造函数模式Tuple3,但类型T(此处T3)不是的实例Tuple3- 只有foreach方法的返回类型是。不可辩驳的模式转换是表达式脱糖的第一步for,因此在考虑返回类型 to 之前foreach

因此,这种模式不能被证明是无可辩驳的。

编辑:虽然根据规范,上述内容似乎是有道理的,但我看不出它实际上有什么意义!例如,我的解释表明以下模式应该是无可辩驳的:

(a,b) <- (1,2)

尽管它没有任何意义!它显然是在寻找一些东西来确定结果类型以检查不可辩驳性,而且似乎这就是withFilter方法。这表明它需要一种withFilter方法来确定是否withFilter需要该方法......

周围似乎有各种各样的错误:例如https://github.com/scala/scala/pull/1893 。我猜这也许是另一个破案子。

于 2013-04-16T13:07:23.137 回答
0

这将起作用:

 for ( T3(x,y,z) <- List(T3(1,2,3)) ) { println (x,y,z) }

还有这个:

 for ( T3(x,y,z) <- Some(T3(1,2,3)) ) { println (x,y,z) }

似乎for理解期望装箱值。

于 2013-04-16T13:41:53.590 回答