在Scala中是否有可能生成一个不允许使用闭包的函数?
假设我有这样的功能:在Scala中是否有可能生成一个不允许使用闭包的函数?,scala,scope,closures,Scala,Scope,Closures,假设我有这样的功能: def doSomeCode(code: => Unit): Unit = { println("Doing some code!") code } 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
def doSomeCode(code: => Unit): Unit = {
println("Doing some code!")
code
}
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
}
它接收一个函数,输出“Doing some 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 doSomeCode(code: => Unit): Unit = {
println("Doing some code!")
code
}
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”}
scala> def mkClosure(i: Int) = { s: String => s"$i - $s" }
mkClosure: (i: Int)String => String
scala> mkClosure(5)
res0: String => String = <function1>
mkClosure:(i:Int)String=>String
scala>mkClosure(5)
res0:String=>String=
因为函数是否依赖于非参数的值并没有在类型系统中编码,所以这样的函数和纯函数在Scala中没有什么不同。宏不太可能做到这一点:编译器插件可能是最好的选择,特别是如果您希望允许在块内使用某些值(例如,
println
) 我怀疑这是可能的。使用某些宏可能是可行的,但这并不容易。你为什么要这个?听起来像是XY问题。编辑了这篇文章并给出了解释。基本上我只想要一个范围块,它没有任何可能的副作用,这是一个崇高的事业,但它已经失去了。打印是一种副作用,读取时钟是一种副作用。您可以在不访问任何外部内容的情况下执行许多操作。最后,所有的变量都在范围内,因为它们没有变异,所以读取它们不是副作用不管怎样,你有没有研究过猫的效果IO基本上,如果你在IO中有一个值,它只能在调用flatMap时使用。这是我所知道的最接近的。对不起,我应该更具体一点。我对传入的变量、标准IO、普通语言调用的副作用没有意见。我特别想要的是,块中的代码的行为就像在其他地方定义的函数中一样,但是是内联的。请参阅最近的编辑,为什么不始终将代码封装在带有参数的函数中?通过这种方式,您可以一目了然地知道哪些是闭包的自由变量。