Scala:避免var或mutable类型

时间:2016-09-11 08:07:50

标签: scala functional-programming immutability

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

def func: MyList = {

    var list: MyList = MyList()

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

    list
}

有没有办法避免使用var

3 个答案:

答案 0 :(得分:4)

如果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

答案 1 :(得分:4)

如果您想使用简单递归并避免使用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

答案 2 :(得分:0)

根据pamu的答案改进,你可以做一些事情;

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