سكالا: تطابق وتحليل سلسلة صحيح؟
سؤال
وأنا أبحث عن وسيلة لمطابقة السلسلة التي قد تحتوي على قيمة عددية. إذا كان الأمر كذلك، تحليل ذلك. أود أن كتابة التعليمات البرمجية مشابهة لما يلي:
def getValue(s: String): Int = s match {
case "inf" => Integer.MAX_VALUE
case Int(x) => x
case _ => throw ...
}
والهدف هو أنه إذا كان سلسلة يساوي "المشع"، والعودة Integer.MAX_VALUE. إذا كانت السلسلة هو عدد صحيح قابلة للتحليل، إرجاع قيمة عدد صحيح. رمي خلاف ذلك.
المحلول
وتحديد مستخرج
object Int {
def unapply(s : String) : Option[Int] = try {
Some(s.toInt)
} catch {
case _ : java.lang.NumberFormatException => None
}
}
ومن طريقة سبيل المثال
def getValue(s: String): Int = s match {
case "inf" => Integer.MAX_VALUE
case Int(x) => x
case _ => error("not a number")
}
واستخدامه
scala> getValue("4")
res5: Int = 4
scala> getValue("inf")
res6: Int = 2147483647
scala> getValue("helloworld")
java.lang.RuntimeException: not a number
at scala.Predef$.error(Predef.scala:76)
at .getValue(<console>:8)
at .<init>(<console>:7)
at .<clinit>(<console>)
at RequestResult$.<init>(<console>:4)
at RequestResult$.<clinit>(<console>)
at RequestResult$result(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Na...
نصائح أخرى
وأنا أعلم أن هذا هو القديم، سؤال أجاب، ولكن هذا هو أفضل IMHO:
scala> :paste
// Entering paste mode (ctrl-D to finish)
val IntRegEx = "(\\d+)".r
def getValue(s: String): Option[Int] = s match {
case "inf" => Some(Integer.MAX_VALUE)
case IntRegEx(num) => Some(num.toInt)
case _ => None
}
// Exiting paste mode, now interpreting.
IntRegEx: scala.util.matching.Regex = (\d+)
getValue: (s: String)Option[Int]
scala> getValue("inf")
res21: Option[Int] = Some(2147483647)
scala> getValue("123412")
res22: Option[Int] = Some(123412)
scala> getValue("not-a-number")
res23: Option[Int] = None
وبطبيعة الحال، فإنه لا يلقي أي استثناءات، ولكن إذا كنت تريد ذلك حقا، يمكنك استخدام
getValue(someStr) getOrElse error("NaN")
هل يمكن استخدام أحد الحراس:
def getValue(s: String): Int = s match {
case "inf" => Integer.MAX_VALUE
case _ if s.matches("[+-]?\\d+") => Integer.parseInt(s)
}
وماذا عن:
def readIntOpt(x: String) =
if (x == "inf")
Some(Integer.MAX_VALUE)
else
scala.util.Try(x.toInt).toOption
def getValue(s: String): Int = s match {
case "inf" => Integer.MAX_VALUE
case _ => s.toInt
}
println(getValue("3"))
println(getValue("inf"))
try {
println(getValue("x"))
}
catch {
case e => println("got exception", e)
// throws a java.lang.NumberFormatException which seems appropriate
}
ونسخة محسنة من مستخرج جيمس IRY ل:
object Int {
def unapply(s: String) = scala.util.Try(s.toInt).toOption
}
ومنذ Scala 2.13
قدم <لأ href = "https://www.scala-lang.org/api/2.13.x/scala/collection/StringOps.html#toIntOption:Option[Int]" يختلط = "نوفولو noreferrer" > String::toIntOption
:
"5".toIntOption // Option[Int] = Some(5)
"abc".toIntOption // Option[Int] = None
ويمكننا أن يلقي String
باعتبارها Option[Int]
بعد التحقق ما اذا كان يساوي "المشع":
if (str == "inf") Some(Int.MaxValue) else str.toIntOption
// "inf" => Option[Int] = Some(2147483647)
// "347" => Option[Int] = Some(347)
// "ac4" => Option[Int] = None