我是Scala的新手,在阅读一些教程和文档时,我尝试了定义自定义控件结构。
所以我尝试实现一个隐式类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中):
缺少方法的参数?在类MyBoolean中;按照这种方法 如果要将其视为部分应用函数,则使用“_”
仅当我在方法.
之前明确添加点?
时才有效。
调用方法时,Scala中的点不应该是可选的吗?有什么我想念的吗?
答案 0 :(得分:1)
这是Scala语法中最奇怪的皱纹之一。您仍然可以使用带有多个参数列表的无点样式,但您必须使用括号对对象,方法和第一个参数列表进行分组(?!)
(true ? {println("true")}) {println("false")}
工作正常。
为什么这样工作?使用/:
和:\
折叠符号非常方便;然后你可以将你的第一个元素与它应该运行的集合组合在一起。
对于其他一切,它充其量是值得怀疑的。
无论如何,你无论是括号还是圆点。
答案 1 :(得分:1)
在调用 1参数方法时,dot是可选的,但该语法对于2参数方法不起作用,即使是curry(除非@RexKerr暗示如果将其括起来)。< / p>
您可以通过“手动”currying来使其工作:编写一个单参数方法,返回带有apply的对象:
class PartiallyApplied(value: Boolean, body1: => Unit) {
def apply(body2: => Unit) = if (value) body1; else body2
}
class MyBoolean...
def ? (body1: => Unit) = new PartiallyApplied(value, body1)
答案 2 :(得分:1)
调用方法时,Scala中的点是不可选的?
排序,但这并不准确。
在这些情况下,这是真的:
a.b(c)
可以写成a b c
a.b(c, d)
可以重写为a b (c, d)
。来自language spec部分6.12.3,中缀操作:
左关联运算符的右手操作数可以包含在括号中的几个参数,例如: e op e 1 ,...,e n 。此表达式被解释为 e.op(e 1 ,...,e n )。
左关联二元运算 e 1 op e 2 被解释为 e 1 .OP(E <子> 2 子>)
但是a.b(c)(d)
形式的表达式没有相应的规则。不过,我不确定为什么。在我看来,a b {c} {d}
是一种非常合理的写作方式。