Scala 2.8:_行为改变了?
使用 XScalaWT,在 Scala 2.7 下编译:
class NodeView(parent: Composite) extends Composite(parent) {
var nodeName: Label = null
this.contains(
label(
nodeName = _
)
)
}
使用 2.8.0 RC1,我收到此错误:
类型不匹配;发现:main.scala.NodeView 需要:org.eclipse.swt.widgets.Label
类型为:
label(setups: (Label => Unit)*)(parent: Composite) : Label
contains(setups: (W => Unit)*) : W
所以看起来 _ 现在绑定到外部函数而不是内部函数。
这个改变是有意为之吗?
更新:这是一个最小化的示例:
Scala 2.7.7:
scala> var i = 0
i: Int = 0
scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: ((Int) => Unit)(Boolean) => Unit
scala> def foo(g: Boolean => Unit) { g(true) }
foo: ((Boolean) => Unit)Unit
scala> foo(conv(i = _))
scala> i
res4: Int = 1
Scala 2.8.0RC3:
scala> var i = 0
i: Int = 0
scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: (f: (Int) => Unit)(Boolean) => Unit
scala> def foo(g: Boolean => Unit) { g(true) }
foo: (g: (Boolean) => Unit)Unit
scala> foo(conv(i = _))
<console>:9: error: type mismatch;
found : Boolean
required: Int
foo(conv(i = _))
^
scala> foo(conv(j => i = j))
scala> i
res3: Int = 1
有趣的是,这有效:
scala> foo(conv(println _))
1
Using XScalaWT, this compiled under Scala 2.7:
class NodeView(parent: Composite) extends Composite(parent) {
var nodeName: Label = null
this.contains(
label(
nodeName = _
)
)
}
With 2.8.0 RC1, I get this error:
type mismatch; found : main.scala.NodeView required: org.eclipse.swt.widgets.Label
The types are:
label(setups: (Label => Unit)*)(parent: Composite) : Label
contains(setups: (W => Unit)*) : W
So it looks like _ now binds to the outer function instead of inner.
Is this change intentional?
UPDATE: Here is a minimized example:
Scala 2.7.7:
scala> var i = 0
i: Int = 0
scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: ((Int) => Unit)(Boolean) => Unit
scala> def foo(g: Boolean => Unit) { g(true) }
foo: ((Boolean) => Unit)Unit
scala> foo(conv(i = _))
scala> i
res4: Int = 1
Scala 2.8.0RC3:
scala> var i = 0
i: Int = 0
scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: (f: (Int) => Unit)(Boolean) => Unit
scala> def foo(g: Boolean => Unit) { g(true) }
foo: (g: (Boolean) => Unit)Unit
scala> foo(conv(i = _))
<console>:9: error: type mismatch;
found : Boolean
required: Int
foo(conv(i = _))
^
scala> foo(conv(j => i = j))
scala> i
res3: Int = 1
Interestingly enough, this works:
scala> foo(conv(println _))
1
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
以下是我从 Lukas Rytz 在 scala 用户列表中得到的答案:
Here is the answer I got from Lukas Rytz on the scala-user list:
我注意到同样的事情,并在戴夫的博客上询问:
http://www.coconut-palm-software.com/the_new_visual_editor/doku.php?id=blog:simplifying_swt_with_scala#comment__930ba2f0a020203873d33decce01ebc2
不过还没有答案。正如您所说, _ 似乎绑定到外部闭包而不是内部闭包。
更改
为
可解决问题。
I noticed the same thing and asked on Dave's blog:
http://www.coconut-palm-software.com/the_new_visual_editor/doku.php?id=blog:simplifying_swt_with_scala#comment__930ba2f0a020203873d33decce01ebc2
No answer there yet though. Just as you're saying, it seems like the _ binds to the outer closure rather than the inner one.
Changing
to
fixes the problem.