我正在使用Scala构建DSL,我有这样一个对象:
object block {
def apply(content: String): String = "{\n" + content + "}\n"
def apply(): String = block("empty block")
}
以便稍后在我的DSL中我可以说:
block {
"good stuff goes here"
}
没关系,但是我想使用第二个apply()
方法来允许用户写空块,以便稍后填充它们。但编译器不允许使用花括号调用无参数apply()
方法...除了使用括号之外,还有什么方法吗?如果不是,那为什么不允许这样做?
更新:供参考:两个答案应合并以获得完整图片。
答案 0 :(得分:6)
代替不带任何参数的apply方法,您可以让它采用被忽略的Unit
类型的参数:
def apply(ignored: Unit) = "{\n}\n"
然后你可以写
block {}
答案 1 :(得分:0)
最后
object block {
def apply[T](content: => T) = "{\n" +
(content match {
case s: String => s
case u: Unit => ""
case a => a.toString
}) + "}\n"
}
修改
使block {}
正常工作:
object block { def apply(content: => Unit) = "{\n" + content + "}\n" }
我坚持使用副名称参数,而不仅仅是另一个答案中的Unit
。因为=> Unit
实际上创建了一个可以由block.apply()
方法执行的函数,而content: Unit
只是将一个代码块作为参数,该代码块将在原地执行(block.apply()
之前1}})。
我们假设block.apply
将打印“Hoho”。现在:
// content: Unit
block { println("Haha") }
// Haha
// Hoho
// content: => Unit
block { println("Haha") }
// Hoho
// Haha
...
使用by-name参数:
object block { def apply(content: => String) = "{\n" + content + "}\n" }