字符串 – 从同一行读取多个输入Scala方式

我试图使用readInt()从同一行读取两个整数,但这不是它的工作原理.

val x = readInt()
val y = readInt()

输入1 727我在运行时得到以下异常:

Exception in thread "main" java.lang.NumberFormatException: For input string: "1 727"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:492)
    at java.lang.Integer.parseInt(Integer.java:527)
    at scala.collection.immutable.StringLike$class.toInt(StringLike.scala:231)
    at scala.collection.immutable.StringOps.toInt(StringOps.scala:31)
    at scala.Console$.readInt(Console.scala:356)
    at scala.Predef$.readInt(Predef.scala:201)
    at Main$$anonfun$main$1.apply$mcVI$sp(Main.scala:11)
    at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:75)
    at Main$.main(Main.scala:10)
    at Main.main(Main.scala)

我使用readf可以让程序工作,但对我来说似乎很尴尬和丑陋:

val (x,y) = readf2("{0,number} {1,number}")
  val a = x.asInstanceOf[Int]
  val b = y.asInstanceOf[Int]
  println(function(a,b))

有人建议我只使用Java的Scanner类(Scanner.nextInt()),但是在Scala中有一个很好的惯用方法吗?

编辑:
我的解决方案遵循范例的例子:

val Array(a,b) = readLine().split(" ").map(_.toInt)

跟进问题:如果在String中混合了类型,你将如何提取它? (说一个字,一个int和一个百分比作为一个双)

解决方法

如果你的意思是如何将val s =“Hello 69 13.5%”转换成(String,Int,Double),那么最明显的方法

val tokens = s.split(" ")
(tokens(0).toString,tokens(1).toInt,tokens(2).init.todouble / 100)
 // (java.lang.String,Double) = (Hello,69,0.135)

或者如前所述,您可以使用正则表达式进行匹配:

val R = """(.*) (\d+) (\d*\.?\d*)%""".r
s match {
  case R(str,int,dbl) => (str,int.toInt,dbl.todouble / 100)
}

如果你真的不知道什么数据将在String中,那么可能没有太多的理由将它从一个字符串转换成它所代表的类型,因为你如何使用可能是一个字符串和可能的东西在Int?不过,你可以这样做:

val int = """(\d+)""".r
val pct = """(\d*\.?\d*)%""".r

val res = s.split(" ").map {
  case int(x) => x.toInt
  case pct(x) => x.todouble / 100
  case str => str
} // Array[Any] = Array(Hello,0.135)

现在做任何有用的事情,你需要根据类型匹配你的值:

res.map {
  case x: Int => println("It's an Int!")
  case x: Double => println("It's a Double!")
  case x: String => println("It's a String!")
  case _ => println("It's a Fail!")
}

或者如果您想进一步了解,您可以定义一些提取器,这些提取器将为您进行转换:

abstract class StringExtractor[A] {
  def conversion(s: String): A
  def unapply(s: String): Option[A] = try { Some(conversion(s)) } 
                                      catch { case _ => None }
}

val intEx = new StringExtractor[Int] { 
  def conversion(s: String) = s.toInt 
}
val pctEx = new StringExtractor[Double] { 
   val pct = """(\d*\.?\d*)%""".r
   def conversion(s: String) = s match { case pct(x) => x.todouble / 100 } 
}

并使用:

"Hello 69 13.5%".split(" ").map {
  case intEx(x) => println(x + " is Int: "    + x.isinstanceOf[Int])
  case pctEx(x) => println(x + " is Double: " + x.isinstanceOf[Double])
  case str      => println(str)
}

版画

Hello
69 is Int: true
0.135 is Double: true

当然,你可以让任何你想要的东西(货币助记符,名字用’J’,URL来)匹配,并返回你想要的任何类型.您不仅限于匹配字符串,如果不是使用StringExtractor [A],则可以使其提取器[A,B].

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...