Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Scala中是否有可能生成一个不允许使用闭包的函数?_Scala_Scope_Closures - Fatal编程技术网

在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、普通语言调用的副作用没有意见。我特别想要的是,块中的代码的行为就像在其他地方定义的函数中一样,但是是内联的。请参阅最近的编辑,为什么不始终将代码封装在带有参数的函数中?通过这种方式,您可以一目了然地知道哪些是闭包的自由变量。