【问题标题】:Scala : How to stop a program when Ctrl-d is pressedScala:按下Ctrl-d时如何停止程序
【发布时间】:2017-02-22 12:42:35
【问题描述】:

如何通过按 Ctrl-d 停止类似 REPL 的控制台应用程序,而无需等待用户键入 Ctr-d 然后进入?

这是一个代码示例:

def isExit(s: String): Boolean = s.head.toInt == 4 || s == "exit"

def main(args: Array[String]) = {
    val continue: Boolean = true
    while(continue){
        println "> "
        io.StdIn.readLine match {
            case x if isExit(x) => println "> Bye!" ; continue = false
            case x              => evaluate(x) 
        }
    }
}

s.head.toInt == 4用于测试输入行的第一个字符是否为 ctrl d。

编辑:运行它的完整源代码:

object Test {

    def isExit(s: String): Boolean = s.headOption.map(_.toInt) == Some(4) || s == "exit"

    def evaluate(s: String) = println(s"Evaluation : $s")

    def main(args: Array[String]) = {
        var continue = true
        while(continue){
            print("> ")
            io.StdIn.readLine match {
                case x if isExit(x) => println("> Bye!") ; continue = false
                case x              => evaluate(x)
            }
        }
    }
}

有了这个,我在 s.headOption 上得到了 NullPointerException (因为 null s)

【问题讨论】:

    标签: scala read-eval-print-loop


    【解决方案1】:

    对代码稍作修改

    def main(args: Array[String]) = {
        var continue: Boolean = true // converted val to var
        while(continue){
            println("> ")
            io.StdIn.readLine match {
                case x if isExit(x) => println("> Bye!") ; continue = false
                case x              => evaluate(x) 
            }
        }
    }
    

    您的 isExit 方法未处理您的读取行可能为空的情况。所以修改后的isExit 如下所示。否则,您的示例将按预期工作

    def isExit(s: String): Boolean = s.headOption.map(_.toInt) == Some(4) || s == "exit"
    

    【讨论】:

    • s 的值在 ctrl-d 上的 isExit 上仍然是 null,所以仍然存在 NullPointerException。
    【解决方案2】:

    好的,如中所说 Read Input until control+d Ctrl-D 按键将该行刷新到 JVM 中。 如果行中有写的东西,就会被发送(只是连续两次ctrl-d后,我不知道为什么),否则io.StdIn.readLine会收到一个流结束字符并返回null ,如 scala 文档中所示 http://www.scala-lang.org/api/2.12.0/scala/io/StdIn$.html#readLine():String

    知道了这一点,我们可以将s.headOption... 替换为简单的s == null 来满足我们的需求。 完整的工作示例:

    object Test {
    
        def isExit(s: String): Boolean = s == null || s == "exit"
    
        def evaluate(s: String) = println(s"Evaluation : $s")
    
        def main(args: Array[String]) = {
            var continue = true
            while(continue){
                print("> ")
                io.StdIn.readLine match {
                    case x if isExit(x) => println("Bye!") ; continue = false
                    case x              => evaluate(x)
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      相关资源
      最近更新 更多