Scala 2.8:_行为改变了?

发布于 2024-08-30 16:37:16 字数 1577 浏览 2 评论 0原文

使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼眸 2024-09-06 16:37:16

以下是我从 Lukas Rytz 在 scala 用户列表中得到的答案:

嗨阿列克谢,

语义发生了变化
当我们引入命名参数时。一个
表达方式

<前><代码>foo(a = _)

过去的解析方式如下:

foo(x => a = x)

在 2.8 中,“a”被视为命名的
参数,即表达式是
解析为:

<前><代码>x =>富(a = x)

我将添加一个迁移警告
这一变化。

Here is the answer I got from Lukas Rytz on the scala-user list:

Hi Alexey,

there has been a change in semantics
when we introduced named arguments. An
expression

foo(a = _)

used to be parsed as follows:

foo(x => a = x)

In 2.8, "a" is treated as a named
argument, i.e. the expression is
parsed as:

x => foo(a = x)

I will add a migration warning for
this change.

你不是我要的菜∠ 2024-09-06 16:37:16

我注意到同样的事情,并在戴夫的博客上询问:

http://www.coconut-palm-software.com/the_new_visual_editor/doku.php?id=blog:simplifying_swt_with_scala#comment__930ba2f0a020203873d33decce01ebc2

不过还没有答案。正如您所说, _ 似乎绑定到外部闭包而不是内部闭包。

更改

nodeName = _

x => nodeName = x

可解决问题。

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

nodeName = _

to

x => nodeName = x

fixes the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文