斯卡拉演员不一致地杀死自己

时间:2012-10-20 17:51:17

标签: scala actor actor-model

我是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时,actor会自行突然死亡。 'list'是所有节点的列表。 (节点对象列表) 此行为也不一致。对每个actor(10个节点)应该调用getMatchingNode 15次。 但是调试时,actor会在一次调用后或者有时在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代码,从而杀死演员。

任何输入错误的代码??

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

  

您可能已经注意到没有提及中断或继续。   Scala省略了这些命令,因为它们与函数不能很好地融合   文字,下一章描述的一个特征。很明显还有什么   在while循环中意味着什么,但它在函数文字中意味着什么?   虽然Scala支持命令式和函数式编程,   在这种情况下,它略微倾向于功能性编程   用于简化语言。不过不用担心。有很多方法可以   程序没有休息和继续,如果你利用功能   文字,这些替代品往往比原始代码短。

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

您的代码基于大量嵌套 for loops ,使用最合适的上提供的高阶函数可以更多地重写代码。集合

你可以改写你的功能,如下所示[我正在尝试让新手们平易近人]:

//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)
}   

继续元素的轻松转换或操作的潜力是继续 for loops 的一般原因,使用较少在斯卡拉

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