假设我有一些这样的函数:
def doSomeCode(code: => Unit): Unit = {
println("Doing some code!")
code
}
它接受一个函数,打印出"做一些代码!",然后调用传递的函数。例如,如果我们这样称呼它:
doSomeCode {
println("Some code done!")
}
它会打印出"正在做一些代码!",然后是"一些代码完成了!"。
但我想禁止在该代码块中使用外部变量,例如:
def otherFunction(): Unit = {
val number = 10
doSomeCode{
println("The number is " + number)
}
}
这将打印出"做一些代码!",然后是"数字是10"。但我希望它抛出一个错误,因为我不希望number
在doSomeCode的范围内。这在 Scala 中可以实现吗?
需要明确的是,我不是在问这是否是一个好主意,我只是想知道这是否可能。
编辑:我想要
这个的原因是因为我正在尝试制作一个功能完美的语法,我想要一个没有副作用的块。理想情况下,语法如下所示:
val a = 1
val b = 2
val c = 3
val d = 4
val sum = use(a, c, d){
val total = a + c + d
total
}
这样,我作为一个程序员就知道唯一使用的变量是a
、c
和d
,而sum
是唯一的输出。尝试使用其他任何东西,例如b
,会导致错误。目前无法一目了然地知道一个块正在使用哪些变量。我可以通过制作和使用这样的函数来实现这一点:
def example(): Unit = {
val a = 1
val b = 2
val c = 3
val d = 4
val sum = sum(a, c, d)
}
def sum(a: Int, b: Int, c: Int): Int = {
val total = a + b + c
total
}
它的行为与我想要的完全一样,但我希望它与其他代码内联,而不是作为外部函数在外部。
scala> def mkClosure(i: Int) = { s: String => s"$i - $s" }
mkClosure: (i: Int)String => String
scala> mkClosure(5)
res0: String => String = <function1>
由于函数是否依赖于非参数的值未在类型系统中编码,因此在 Scala 中,此类函数和纯函数之间没有编译器可强制执行的区别。 宏不太可能实现:编译器插件可能是你最好的选择,特别是如果你想允许某些值(例如println
(在块内使用。