سؤال

وأنا أبحث عن وسيلة لمطابقة السلسلة التي قد تحتوي على قيمة عددية. إذا كان الأمر كذلك، تحليل ذلك. أود أن كتابة التعليمات البرمجية مشابهة لما يلي:

  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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top