我试图使用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)
解决方法
如果你的意思是如何将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].