下面的代码只是通过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语句:return fileName
,那么方法getFileName
似乎陷入无限循环并且不会终止。
为什么需要明确的退货? scala编译器是否应该推断var fileName
的返回?
答案 0 :(得分:8)
正如om-nom-nom在评论中已经说过,它并不是关于类型推断,而是控制流问题。
使用return
你打破了(否则)无限循环。
此外,不是问题的真正部分,但由于您使用的是随机UUID,您可以删除重复检查代码并简单地按原样返回生成的UUID,除非您的要求非常高。
[生成重复字符串的概率]约为0.00000000006(6×10-11),相当于一年内创建几十万亿UUID并且有一个重复的可能性。
在“正常”的情况下,我只会做
def getFileName: String = java.util.UUID.randomUUID.toString
并完成它。
答案 1 :(得分:2)
由于这个障碍......
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())
}
哪个应该具有相同的效果。
答案 2 :(得分:2)
没有循环,变量或(显式)递归
def getFileName(): String = {
val fileName = Iterator.continually(java.util.UUID.randomUUID().toString())
.find(!currentFileNameList.contains(_)).get
currentFileNameList += fileName
fileName
}
答案 3 :(得分:0)
你不应该循环或使用变种:
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())
}