Scala 为什么在这个代码块中需要返回?
下面的代码只是通过Scala 为什么在这个代码块中需要返回?,scala,Scala,下面的代码只是通过getFileName方法返回一个随机字符串: import scala.collection.mutable.ListBuffer object RTest extends App { var currentFileNameList: ListBuffer[String] = new ListBuffer def getFileName(): String = { var fileName = java.util.UUID.randomUUID().to
getFileName
方法返回一个随机字符串:
import scala.collection.mutable.ListBuffer
object RTest extends App {
var currentFileNameList: ListBuffer[String] = new ListBuffer
def getFileName(): String = {
var fileName = java.util.UUID.randomUUID().toString();
while (true) {
if (!currentFileNameList.contains(fileName)) {
currentFileNameList = currentFileNameList :+ fileName
return fileName
} else {
fileName = java.util.UUID.randomUUID().toString();
}
}
throw new RuntimeException("Error - filename not generated")
}
println(getFileName())
}
如果删除第行中的return语句:returnfilename
,则方法getFileName
似乎陷入无限循环,并且不会终止
为什么需要显式返回?scala编译器是否应该推断var
fileName
?的返回,正如om-nom-nom在评论中所说的那样,这实际上不是类型推断,而是控制流问题
通过使用return
您正在打破(否则)无限while循环
另外,这并不是问题的一部分,但由于您使用的是随机UUID,您可能会删除重复的检查代码,并简单地返回生成的UUID,除非您有非常高的要求 , [生成重复字符串的概率]约为0.00000000006(6×10−11) ,相当于在一年内创建数十万亿个UUID并复制一个UUID的几率 在“正常”情况下,我只会这么做
def getFileName: String = java.util.UUID.randomUUID.toString
就这样吧。因为这个块
while (true) {
if (!currentFileNameList.contains(fileName)) {
currentFileNameList = currentFileNameList :+ fileName
return fileName
} else {
fileName = java.util.UUID.randomUUID().toString();
}
}
你处于一个无止境的循环中,因为“真实”永远不会改变。通过返回函数,您将跳出这个循环(以及完全跳出函数)
你可以做一些像
object RTest extends App {
var currentFileNameList: ListBuffer[String] = new ListBuffer
def getFileName(): String = {
var fileName = java.util.UUID.randomUUID().toString();
while (currentFileNameList.contains(fileName)) {
fileName = java.util.UUID.randomUUID().toString();
}
currentFileNameList = currentFileNameList :+ fileName;
return fileName;
}
println(getFileName())
}
这应该具有相同的效果。您不应该循环或使用变量:
import scala.collection.mutable.ListBuffer
object Test extends App {
val currentFileNameList: ListBuffer[String] = new ListBuffer
@annotation.tailrec
def getFileName(): String = {
val fileName = java.util.UUID.randomUUID().toString();
if (!currentFileNameList.contains(fileName)) {
currentFileNameList += fileName
fileName
} else {
getFileName()
}
}
println(getFileName())
}
没有循环、变量或(显式)递归
def getFileName(): String = {
val fileName = Iterator.continually(java.util.UUID.randomUUID().toString())
.find(!currentFileNameList.contains(_)).get
currentFileNameList += fileName
fileName
}
否则您将继续下一次迭代?这不是关于推断什么东西,而是关于流量控制,首先,要很好地使用。让我们给你一些分数。