0

我是 scala 的新手,我正在编写 scala 代码来实现糕点协议。协议本身并不重要。有节点,每个节点都有一个我要填充的路由表。这是代码的一部分:

def act () {
def getMatchingNode (initialMatch :String) : Int = {
val len = initialMatch.length
  for (i <- 0 to noOfNodes-1) {
    var flag : Int = 1
    for (j <- 0 to len-1) { 
      if (list(i).key.charAt(j) == initialMatch(j)) {
        continue
      } 
      else {
        flag = 0
      }
    }
    if (flag == 1) {
      return i
    }
  }
 return -1
}


// iterate over rows
for (ii <- 0 to rows - 1) {
  for (jj <- 0 to 15) {
    var initialMatch = ""
     for (k <- 0 to ii-1) {
       initialMatch = initialMatch + key.charAt(k)
     }
     initialMatch += jj
     println("initialMatch",initialMatch)
     if (getMatchingNode(initialMatch) != -1) {
       Routing(0)(jj) =  list(getMatchingNode(initialMatch)).key
     }
     else {
       Routing(0)(jj) =  "NULL"
     }
  }
 }

}// act

问题是当对 getMatchingNode 的函数调用发生时,演员自己突然死亡。'list' 是所有节点的列表。(节点对象列表)此外,这种行为并不一致。每个参与者(对于 10 个节点)应该调用 getMatchingNode 15 次。但是在调试时,演员在一次调用后或有时在 3-4 次调用后会在 getMatchingNode 函数调用中杀死自己。被执行的 scala 库代码是这样的:

def run() {
try {
  beginExecution()
  try {
    if (fun eq null)
      handler(msg)
    else
      fun()
  } catch {
    case _: KillActorControl =>
      // do nothing

    case e: Exception if reactor.exceptionHandler.isDefinedAt(e) =>
      reactor.exceptionHandler(e)
  }
  reactor.kill()
}

Eclipse 显示此代码已从 getMatchingNode 函数中的 for 循环调用

def getMatchingNode (initialMatch :String) : Int =  {
  val len = initialMatch.length
  for (i <- 0 to noOfNodes-1) 

奇怪的是,有时循环表现正常,有时它会进入杀死演员的scala代码。

任何输入代码有什么问题?

任何帮助,将不胜感激。

4

2 回答 2

0

来自书中:M.Odersky 的“Scala 2ed 编程”

您可能已经注意到没有提到中断或继续。Scala 省略了这些命令,因为它们不能很好地与函数字面量相结合,这一特性将在下一章中描述。很清楚 continue 在 while 循环中意味着什么,但在函数文字中意味着什么?虽然 Scala 同时支持命令式和函数式编程风格,但在这种情况下,它略微倾向于函数式编程以换取简化语言。不过不要担心。有很多方法可以在没有中断和继续的情况下进行编程,如果您利用函数文字,这些替代方法通常会比原始代码短。

如果您想学习scala,我真的建议您阅读这本书

您的代码基于大量嵌套的 for 循环,这些循环通常可以使用最合适的Collection上可用的高阶函数重写。

你可以像下面这样重写你的函数[我试图让它对新手来说平易近人]:

//works if "list" contains "nodes" with an attribute "node.key: String"
def getMatchingNode (initialMatch :String) : Int = {

  //a new list with the corresponding keys
  val nodeKeys = list.map(node => node.key)

  //zips each key (creates a pair) with the corresponding index in the list and then find a possible match
  val matchOption: Option[(String, Int)] = (nodeKeys.zipWithIndex) find {case (key, index) => key == initialMatch}

  //we convert an eventual result contained in the Option, with the right projection of the pair (which contains the index)
  val idxOption = matchOption map {case (key, index) => index} //now we have an Option[Int] with a possible index

  //returns the content of option if it's full (Some) or a default value of "-1" if there was no match (None). See Option[T] for more details
  idxOption.getOrElse(-1)
}   

轻松转换或操作Collection元素的潜力是使continuefor 循环在一般情况下在 Scala 中较少使用的原因

您可以以类似的方式转换行迭代,但我建议如果您需要对集合的索引进行大量工作,您可以使用IndexedSeq或其实现之一,例如ArrayBuffer

于 2012-10-22T13:32:31.483 回答
0

得到错误.. for 循环中的“继续”子句引起了麻烦。我认为我们可以像在 C++/Java 中一样在 Scala 中使用 continue ,但似乎并非如此。删除 continue 解决了这个问题。

于 2012-10-21T17:01:50.920 回答