在布尔选项中捕获一个字符串

时间:2016-04-13 14:19:18

标签: scala dictionary functional-programming boolean case

当有人未选择scala中的某个选项时,如何防止错误。这是使用Map获取选项,我尝试在case选项中实现Try和catch块,但它不起作用。我不确定这是否是正确的方法,如果还有其他方式让我知道。错误是线程“main”中的异常java.lang.NumberFormatException:对于输入字符串:“e”。

object main extends menu {
  def main(args: Array[String]): Unit = {
    var opt = 0
    do { opt = readOption }
    while (menu(opt))
  }
}   

class menu extends database {
  def menu(option: Int): Boolean = try {
    actionMap.get(option) match {
      case Some(a) => a()
      case None => println("That didn't work.")
      false
    }
  } catch {
  case _: NumberFormatException => true
  }
  val actionMap = Map[Int, () => Boolean](1 -> cWords, 2 -> cCharacters, 3 -> exit)

def readOption: Int = {
    println(
      """|Please select one of the following:
         |  1 - Count Words
         |  2 - Count Characters in words
         |  3 - quit""".stripMargin)
    StdIn.readInt()
}

3 个答案:

答案 0 :(得分:1)

scala.util.Try上使用readInt()

import scala.io._
import scala.util._

Try(StdIn.readInt()).toOption
// returns Some(123) for input 123

Try(StdIn.readInt()).toOption
// returns None for input 1a3

因此readOption传递Option[Int]。然后

def menu(option: Option[Int]): Boolean = option match {
  case Some(a) => actionMap(a)()
  case None    => println("Try again..."); false
}

注意

main的更简洁版本,

def main(args: Array[String]): Unit = while (menu(readOption)) ()

menu true Unit ()(或<?php //CREATE CONNECTION $servername = "localhost"; $username = "root"; $password = "root"; $conn = new mysqli($servername, $username, $password); // CHECK THE CONNECTION if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // CREATE ESTATE AGENTS DATABASE $sql = "CREATE DATABASE IF NOT EXISTS estate_agents"; if ($conn->query($sql) === TRUE) { $dbname= "estate_agents"; $newConnection = new mysqli($servername, $username, $password,$dbname); //CREATE PROPERTIES TABLE $sql = "CREATE TABLE IF NOT EXISTS properties ( property_id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, property_name VARCHAR(50) NOT NULL, property_cost VARCHAR(50) NOT NULL, property_description VARCHAR(500) NOT NULL )"; if ( $newConnection->query($sql) === TRUE) { $query = "SELECT * FROM properties"; $result = $newConnection->query($query); foreach ($result as $row) { $id = $row['property_id']; $name = $row['property_name']; $cost = $row['property_cost']; $description = $row['property_description']; echo $id; } } else { echo "Error creating table: " . $newConnection->error . "</br>"; } } else { echo "estate_agents not functional: " . $newConnection->error . "</br>"; } ?> )。

答案 1 :(得分:0)

以下是一些有效的实施方案:

import scala.io.StdIn
import scala.util.Try

object Main extends Menu with App {
    while (menu(readChoice)) ()
}

class Menu {
  val actionMap = Map[Int, () => Boolean](1 -> (() => true), 2 -> (() => true), 3 -> (() => false))

  def menu(choice: Option[Int]): Boolean = {
    choice.flatMap(actionMap.get)
      .map(action => action())
      .getOrElse({ println("That didn't work."); false })
  }

  def readChoice: Option[Int] = {
    println(
      """|Please select one of the following:
         |  1 - Count Words
         |  2 - Count Characters in words
         |  3 - quit""".stripMargin)
    Try(StdIn.readInt).toOption
  }
}

对于第一个,您可以混合使用App trait跳过main方法样板。

您可以像这样简化do while循环,它必须在内部不执行任何操作,因此您需要一些表达式或块。 Unit值可以是您的表达式,不执行任何操作。

在scala中,我们使用camel case命名类,以大写字母开头。

当输入错误时,当readInt抛出时,您可以使用Try来捕获它,这将返回Success(result) Failure(exception)并将此结果更改为Option放弃例外。

菜单中发生的事情是

的简写
choice match {
  case Some(number) =>
    actionMap.get(number) match {
      case Some(action) =>
        action()
      case None =>
        println("That didn't work.")
        false
    }
  case None =>
    println("That didn't work.")
    false
}

可以和for

一起编写
(for {
  number <- choice
  action <- actionMap.get(number)
} yield {
  action()
}) getOrElse {
  println("That didn't work.")
  false
}

在旁注中,您将用户的选择命名为&#34;选项&#34;不幸的是,这也是一个广泛使用的scala类,我重命名变量以避免混淆。

答案 2 :(得分:0)

我会readOption返回Try[Int],(Try周围StdIn.readInt()),然后处理menu函数中的可能案例