4

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

更新:供参考:这两个答案应该结合起来以获得全貌。

4

2 回答 2

6

代替没有任何参数的 apply 方法,您可以让它接受一个Unit被忽略的类型的参数:

def apply(ignored: Unit) = "{\n}\n"

然后你可以写

block {}
于 2012-12-27T14:47:53.300 回答
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())。

假设这block.apply将打印“Hoho”。现在:

// content: Unit
block { println("Haha") }
// Haha
// Hoho

// content: => Unit
block { println("Haha") }
// Hoho
// Haha

...

使用按名称参数:

object block { def apply(content: => String) = "{\n" + content + "}\n" }
于 2012-12-27T14:42:04.870 回答