如何在Scala中编写循环的函数

如何在循环中编写模拟的函数?它应该需要2个参数:condition和expression才能执行.

我试过以下:

val whileLoop: (Boolean,Any)=>Unit = (condition:Boolean,expression:Any) => {
 expression
 if(condition) whileLoop(condition,expression)
 () }

但它似乎不起作用,例如我有数组:

val arr = Array[Int](-2,5,-5,9,-3,10,3,4,1,2,-20)

我也有变量i:

var i = 0

我想打印arr的所有元素.我可以使用以下代码

while(i<arr.length) { println(tab(i)); i+=1 }

我想使用我的whileLoop函数做同样的事情.但是我无法写入引用变量并修改它的函数.我可以通过只使用一个元素的数组,例如

val nr = Array(0)

功能

val printArray: Array[Int]=>Unit = (n:Array[Int]) => {
 println(arr(n(0)))
 n(0)+=1
 ()
}

然后在我的whileLoop中使用:

whileLoop(nr(0)<arr.length,printArray)

使用上面的代码后,我得到StackOverflowError,nr(0)等于零.还有以下功能

val printArray: Array[Int]=>Unit = (n:Array[Int]) => {
 println(arr(nr(0)))
 nr(0)+=1
 ()
}

给出相同的结果.

我如何在执行时编写正确的函数,并使用它来打印所有的arr元素?

提前感谢建议.

解决方法

您的实现的主要问题是,当您首次调用whileLoop时,条件和表达式仅计算一次.在递归调用中,只需传递一个值,而不是一个表达式.

您可以使用by-name参数来解决此问题:

def whileLoop(cond : =>Boolean,block : =>Unit) : Unit =
  if(cond) {
    block
    whileLoop(cond,block)
  }

举个例子:

scala> val a = Array(1,3)
scala> var i = 0
scala> whileLoop(i < a.length,{ println(i); i += 1 })
1
2
3

请注意,变量a和i被正确引用.在内部,Scala编译器为条件和表达式(块)构建了一个函数,并且这些函数保持对它们的环境的引用.

还要注意,对于更多的句法糖,你可以定义whileLoop作为一个currified函数

def whileLoop(cond : =>Boolean)(block : =>Unit) : Unit =
  if(cond) {
    block
    whileLoop(cond)(block)
  }

这样就可以像实时while循环一样调用它:

whileLoop(i < a.length) {
  println(a(i))
  i += 1
}

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...