Актер Scala непоследовательно убивает себя

Я новичок в 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, актор внезапно умирает сам по себе. «список» — это список всех узлов. (список узловых объектов) Также это поведение непоследовательно. Вызов getMatchingNode должен выполняться 15 раз для каждого актора (для 10 узлов). Но при отладке актор убивает себя в вызове функции getMatchingNode после одного вызова, а иногда и после 3-4 вызовов. Код библиотеки 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 показывает, что этот код был вызван из цикла for в функции getMatchingNode.

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

Странно то, что иногда цикл ведет себя нормально, а иногда уходит в scala-код, который убивает актера.

Любые входные данные, что не так с кодом ??

Любая помощь будет оценена по достоинству.


person Deepti Jain    schedule 20.10.2012    source источник
comment
Ваш код очень трудно следовать. Вы добьетесь большего успеха в получении помощи, если переведете код в более простой пример, демонстрирующий проблему.   -  person cheeken    schedule 20.10.2012
comment
Сократили код только для включения цикла и функции, вызывающей ошибку.   -  person Deepti Jain    schedule 20.10.2012


Ответы (2)


Получил ошибку. Предложение «продолжить» в цикле for вызвало проблему. Я думал, что мы могли бы использовать continue в Scala, как мы это делаем в C++/Java, но это не так. Удаление продолжения решило проблему.

person Deepti Jain    schedule 21.10.2012

Из книги: "Программирование на Scala 2ed" М.Одерского

Вы могли заметить, что не было упоминания о прерывании или продолжении. Scala не учитывает эти команды, потому что они плохо сочетаются с функциональными литералами, и эта функция будет описана в следующей главе. Понятно, что означает continue внутри цикла while, но что это значит внутри функционального литерала? Хотя Scala поддерживает как императивный, так и функциональный стили программирования, в данном случае он немного склоняется к функциональному программированию в обмен на упрощение языка. Однако не беспокойтесь. Существует множество способов программирования без перерыва и продолжения, и если вы воспользуетесь преимуществами литералов функций, эти альтернативы часто могут быть короче, чем исходный код.

Я действительно рекомендую прочитать книгу, если вы хотите изучить Scala

Ваш код основан на множестве вложенных циклов for, которые чаще всего можно переписать с помощью функций высшего порядка, доступных в наиболее подходящей коллекции. эм>.

Вы можете переписать свою функцию следующим образом [я пытаюсь сделать ее доступной для новичков]:

//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 или работать с ними — это то, что делает continues и циклы for в целом менее используемыми в Scala.

Вы можете преобразовать итерацию строки аналогичным образом, но я бы посоветовал, если вам нужно много работать с индексами коллекции, вы хотите использовать IndexedSeq или одну из его реализаций, например ArrayBuffer.

person pagoda_5b    schedule 22.10.2012