Scala:避免使用 var 或可变类型

Scala: Avoid var or mutable type

我有如下所示的伪代码。 ItemChurner.churn() 是抽象组件,生成对象直到 x 次,其中 x 是未知的。 :

def func: MyList = {

    var list: MyList = MyList()

    while(ItemChurner.canChurn) {
        list = new MyList(ItemChurner.churn(), list)
    }

    list
}

有没有办法避免使用 var

如果 canChurn 正常工作:

def func(churner: ItemChurner) = {
  val iterator = new Iterator {
    def hasNext = churner.canChurn
    def next = churner.churn()
  }
  iterator.toList
}

关于包含针对 churn() 的已捕获异常检查的(问题的)版本:

如果真的希望有一些例外,那么 canChurn 有什么意义呢?

无论如何,如果您关心异常:

 Iterator.continually(Try(churner.churn)).takeWhile(_.isSuccess).map(_.get).toList

这实际上不是很精确,因为 churn 可能会抛出一些必须传播的其他异常,所以这里 scala 的 Exception helpers) 派上用场了:

def step = catching(classOf[NoMoreElementsException]) opt churner.churn()
Iterator.continually(step).takeWhile(_.nonEmpty).map(_.get).toList

如果你想使用简单递归并避免var。这是函数式编程中使用的一般策略。

使用Vector代替List有效append

def func[T](): List[T] = {

  @tailrec
  def helper(result: List[T]): List[T] = {
    if (ItemChurner.canChurn) helper(result ++ List(ItemChurner.churn))
    else result
  }

  helper(List.Empty[T])
}

假设ItemChurner.canChurn没有抛出任何异常。如果它抛出异常,只需将其包装在 Try

改进 pamu 的回答,你可以做一些事情;

def func: MyList = {
  def process(cur: MyList): MyList = {
    if (ItemChurner.canChurn) process(new MyList(ItemChurner.churn(), cur))
    else cur
  }
  process(new MyList())
}