2

我目前正试图找到进入 Scala 世界的途径。实际上,我正在尝试实现没有可变类型的循环策略。

我有一个带有初始主机列表和获取下一个主机的方法的 Scala 对象。

Object RoundRobin { 
  val optHosts: Option[List[String]] = Option[List[String]]("host1", "host2") // get from Configfile later
  var hosts: List[String] = optHosts.getOrElse(List())

  def url: String = {
    hosts = hosts.tail ++ List(hosts.head)
    hosts(0)
  }

  def execute = ??? // do something with the next host

}

我读过 Scala 中的不可变队列,但我真的不知道如何用不可变类型解决这个问题。不知何故,我必须记住一个索引,对吗?这是使用不可变类型没有意义的情况之一吗?

4

2 回答 2

3

如果我每次在对象上调用执行时我都理解正确,它应该使用不同的元素。然后因为对象必须封装状态,所以没有办法绕过var

var hosts = collection.immutable.Queue ++ optHosts.getOrElse(List())
def url: String = {
   val(element,queue) = hosts.pop
   hosts = queue.enqueue(element)
   element
}

关于你的问题...

不知何故,我必须记住一个索引,对吗?

是的,见上文。但也没有,见下文。

这是使用不可变类型没有意义的情况之一吗?

要看。如果你想object RoundRobin清楚地保持你的 then,那个对象是可变的,所以你只能在可变 val 和不可变 var 之间进行选择。(你也可以有指向可变结构的变量,但你为什么要这样做?)

另一方面,您也可以选择完全不同的方法:

class RoundRobin private(left: List[String], all: List[String]) {
   def this(all :List[String]) = this(all, all)
   assume(all.nonEmpty)
   val theElement = left.headOption.getOrElse(all.head)
   def nextRoundRobin = new RoundRobin(if(left.nonEmpty) left.tail else all, all) 
   def execute = {
       // do something with theElement
       println(theElement)
       // return an object that will execute on the next element
       nextRoundRobin
   }
 }

 new RoundRobin(List("1","2")).execute.execute.execute
 // prints 1 2 1

当您使用此版本的 RoundRobin 时,每次调用 execute 时,它​​都会为您提供一个循环对象,该对象将以循环方式使用下一个元素。显然,使用 RoundRobin 的对象又可以是可变的或不可变的。

于 2013-11-05T12:33:10.587 回答
0

进行了细微的更改,以便在执行超过 3 次(如提供的示例中所示)时,该类现在将轮流交替进行。

 class RoundRobin private(left: List[String], all: List[String]) {
      def this(all :List[String]) = this(all, all)
      assume(all.nonEmpty)
      val theElement = left.headOption.getOrElse(all.head)
      def nextRoundRobin = new RoundRobin(if(left.nonEmpty) left.tail else all.tail, all)
      def execute = {
        // do something with theElement
        println(theElement)
        // return an object that will execute on the next element
        nextRoundRobin
      }
    }
于 2014-01-31T07:04:53.257 回答