Scala - `apply()`不带参数方法和调用时的曲线括号

时间:2012-12-27 14:33:25

标签: scala dsl

我正在使用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()方法...除了使用括号之外,还有什么方法吗?如果不是,那为什么不允许这样做?

更新:供参考:两个答案应合并以获得完整图片。

2 个答案:

答案 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" }