具有两个块的自定义控制结构
Custom control structure with two blocks
我是 Scala 的新手,在阅读一些教程和文档时,我尝试定义自定义控制结构。
所以我尝试实现一个隐式 class MyBoolean
,它提供一个带有两个参数列表的 ?
方法。第一个参数是一个块,如果 MyBoolean
为真,则执行第二个参数,如果 MyBoolean
为假,则执行第二个参数。
下面是生成的控制结构的语法示例:
true ? {println("true")} {println("false")};
所以本质上只是一个简单的 if-else 语句,作为布尔方法实现。
这是我的实现:
object Test extends App {
implicit class MyBoolean(val value: Boolean) {
def ? (body1: => Unit)(body2: => Unit){
if (value) body1;
else body2
}
}
override def main(args: Array[String]): Unit = {
// true ? {println("true")} {println("false")}; //--> compiler error
true.? {println("true")} {println("false")}; // works fine...
}
}
我面临的问题是我使用预期语法(在 Eclipse 中)遇到以下编译器错误:
missing arguments for method ? in class MyBoolean; follow this method
with `_' if you want to treat it as a partially applied function
只有在方法 ?
之前明确添加点 .
才有效。
在 Scala 中调用方法时点不应该是可选的吗?有什么我想念的吗?
这是 Scala 语法中最奇怪的问题之一。您仍然可以使用带多个参数列表的无点样式 ,但您必须使用括号 (?!)
对对象、方法和第一个参数列表进行分组
(true ? {println("true")}) {println("false")}
工作正常。
为什么会这样?使用 /:
和 :\
折叠符号非常方便;然后你可以将你的第一个元素与它应该 运行 通过的集合组合在一起。
对于其他一切,充其量是有问题的。
无论如何,你都被括号或点卡住了。
在调用 1 参数 方法时,点是可选的,但该语法不适用于 2 参数方法,即使在柯里化时也是如此(除非 @RexKerr 建议您括起来)。
您可以通过 "manual" currying 使其工作:编写一个单参数方法,returns 一个具有应用的对象:
class PartiallyApplied(value: Boolean, body1: => Unit) {
def apply(body2: => Unit) = if (value) body1; else body2
}
class MyBoolean...
def ? (body1: => Unit) = new PartiallyApplied(value, body1)
Shouldn't the dot be optional in Scala when calling methods?
有点像,但这并不完全准确。
在这些情况下,确实如此:
a.b(c)
可以写成a b c
a.b(c, d)
可以改写为a b (c, d)
.
来自 language spec 节 6.12.3,中缀操作:
The right-hand operand of a left-associative operator may consist of several arguments enclosed in parentheses, e.g. e op e1, …, en. This expression is the interpreted as e.op(e1, …, en).
A left-associative binary operation e1 op e2 is interpreted as e1.op(e2).
但是a.b(c)(d)
形式的表达式没有相应的规则。不过,我不太确定为什么。在我看来,a b {c} {d}
是一种完全合理的写法。
我是 Scala 的新手,在阅读一些教程和文档时,我尝试定义自定义控制结构。
所以我尝试实现一个隐式 class MyBoolean
,它提供一个带有两个参数列表的 ?
方法。第一个参数是一个块,如果 MyBoolean
为真,则执行第二个参数,如果 MyBoolean
为假,则执行第二个参数。
下面是生成的控制结构的语法示例:
true ? {println("true")} {println("false")};
所以本质上只是一个简单的 if-else 语句,作为布尔方法实现。
这是我的实现:
object Test extends App {
implicit class MyBoolean(val value: Boolean) {
def ? (body1: => Unit)(body2: => Unit){
if (value) body1;
else body2
}
}
override def main(args: Array[String]): Unit = {
// true ? {println("true")} {println("false")}; //--> compiler error
true.? {println("true")} {println("false")}; // works fine...
}
}
我面临的问题是我使用预期语法(在 Eclipse 中)遇到以下编译器错误:
missing arguments for method ? in class MyBoolean; follow this method with `_' if you want to treat it as a partially applied function
只有在方法 ?
之前明确添加点 .
才有效。
在 Scala 中调用方法时点不应该是可选的吗?有什么我想念的吗?
这是 Scala 语法中最奇怪的问题之一。您仍然可以使用带多个参数列表的无点样式 ,但您必须使用括号 (?!)
对对象、方法和第一个参数列表进行分组(true ? {println("true")}) {println("false")}
工作正常。
为什么会这样?使用 /:
和 :\
折叠符号非常方便;然后你可以将你的第一个元素与它应该 运行 通过的集合组合在一起。
对于其他一切,充其量是有问题的。
无论如何,你都被括号或点卡住了。
在调用 1 参数 方法时,点是可选的,但该语法不适用于 2 参数方法,即使在柯里化时也是如此(除非 @RexKerr 建议您括起来)。
您可以通过 "manual" currying 使其工作:编写一个单参数方法,returns 一个具有应用的对象:
class PartiallyApplied(value: Boolean, body1: => Unit) {
def apply(body2: => Unit) = if (value) body1; else body2
}
class MyBoolean...
def ? (body1: => Unit) = new PartiallyApplied(value, body1)
Shouldn't the dot be optional in Scala when calling methods?
有点像,但这并不完全准确。
在这些情况下,确实如此:
a.b(c)
可以写成a b c
a.b(c, d)
可以改写为a b (c, d)
.
来自 language spec 节 6.12.3,中缀操作:
The right-hand operand of a left-associative operator may consist of several arguments enclosed in parentheses, e.g. e op e1, …, en. This expression is the interpreted as e.op(e1, …, en).
A left-associative binary operation e1 op e2 is interpreted as e1.op(e2).
但是a.b(c)(d)
形式的表达式没有相应的规则。不过,我不太确定为什么。在我看来,a b {c} {d}
是一种完全合理的写法。