以下代码无法编译:
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>
答案 0 :(得分:2)
根据Scala language specification,生成器p <- e
被转换为withFilter
调用,除非该模式是“无可辩驳的”。给出了一个无可辩驳的模式的三个条件:
p
是一种变量模式。显然,事实并非如此。
p
是一种打字模式x : T'
和'T <: T'
,其中e : T
。同样,事实并非如此。
p
是构造函数模式c(p1,...,pn)
,类型T
是类c
的实例,类型为T
的主构造函数(第5.3节)参数类型T1, ..., Tn
,pi
每个Ti
都无法参与。 这里的问题是虽然 (x,y,z)
是Tuple3
的构造函数模式,但类型T
(此处T3
)不是{{Tuple3
的实例1}} - 只有foreach
方法的返回类型。转换非无可辩驳的模式是消除for
表达式的第一步,因此在考虑返回类型foreach
之前。
因此,模式无法显示为无可辩驳。
编辑:虽然根据规范上述内容似乎有道理,但我看不出实际上有什么意义!例如,我的解释表明以下模式应该是无可辩驳的:
(a,b) <- (1,2)
尽管它没有任何意义!它显然正在寻找一些东西来确定结果类型以检查无法反驳,似乎有些东西是withFilter
方法。这表明它需要withFilter
方法才能确定是否需要withFilter
方法......
似乎存在各种各样的错误:例如https://github.com/scala/scala/pull/1893。我猜这也许是另一个破案。
答案 1 :(得分: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
理解似乎需要盒装值。