提问人:Jared DuPont 提问时间:9/21/2019 最后编辑:Jared DuPont 更新时间:9/21/2019 访问量:50
是否可以在 Scala 中创建一个不允许使用闭包的函数?
Is it possible in Scala to make a function that disallows the use of closures?
问:
假设我有一些这样的功能:
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”。但我希望它抛出一个错误,因为我不想在 doSomeCode 的范围内。这在 Scala 中可能实现吗?
需要明确的是,我不是在问这是否是一个好主意,我只是想知道它是否可行。number
编辑:
我想要这个的原因是因为我试图制作一个功能完美的语法,我想要一个没有副作用的块。理想情况下,语法如下所示:
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
}
它的行为与我想要的完全一样,但我希望它与其他代码内联,而不是作为外部函数。
答:
1赞
Levi Ramsey
9/21/2019
#1
scala> def mkClosure(i: Int) = { s: String => s"$i - $s" }
mkClosure: (i: Int)String => String
scala> mkClosure(5)
res0: String => String = <function1>
由于函数是否依赖于非参数的值未在类型系统中编码,因此在 Scala 中,此类函数和纯函数之间没有编译器可强制执行的区别。使用宏不太可能实现:编译器插件可能是您最好的选择,特别是如果您想允许在块内使用某些值(例如)。println
评论
cats.effect.IO
flatMap