命令行菜单循环Scala

时间:2017-06-09 15:30:15

标签: scala

我有以下问题:

我想编写一个命令行工具,用户可以在其中输入命令,执行后,菜单会再次弹出下一个命令,直到用户插入x

在Java中,我会这样做(或者在循环中使用布尔值,设置它并在最后,询问它是否为真。但是这不是一个Java问题,这只是一个例子来显示我想要的是什么):

loop1: do{
    printMenu();
    String input = readFromConsole();
    switch(input){
        case "a": //dostuff
            break;
        case "x": break loop1;
    }
}while (true);

由于Scala没有中断,我应该怎么做?

一种有效的方法如下:

var cont = true
do{
    printMenu()
    val cmd = scala.io.StdIn.readLine()
    cmd match{
      case "c" => {
         //dostuff
      }
      case "x" => cont=false
      case _ => println("invalidCommand")

    }
}while(cont)

但是由于循环和可变变量不是经典的功能概念,我想有更好的,更像Scala的方式。

另一种方式是递归函数,每次“x”未插入时调用自身,但这似乎也不是好的样式。

我该怎么做(什么是最好的风格)? 如前所述,我已经找到了一个可行的解决方案,但它似乎并不是最佳选择。如果是,请告诉我。

很抱歉,如果这是一个微不足道的问题,但我搜索了一下,并没有找到关于这个主题的更多信息。

2 个答案:

答案 0 :(得分:1)

尾递归应该足够了。

@tailrec
final def printMenu():Option[String] = {
  println("Put something: ")
  val cmd = scala.io.StdIn.readLine()
  cmd match{
    case "c" => {
      return Some("Foo")
    }
    case "x" => return None
    case _ => printMenu()
  }
}

printMenu()

答案 1 :(得分:1)

创建一个无限迭代器,然后takeWhile输入不是退出命令。

Iterator.continually(io.StdIn.readLine)
        .takeWhile(_ != "x")
        .foreach{
           case "this" => /* do this */
           case "that" => /* do that */
           case _      => /* default */
        }