Je cherche un moyen de faire correspondre une chaîne pouvant contenir une valeur entière. Si oui, analysez-le. J'aimerais écrire un code similaire à celui-ci:
def getValue(s: String): Int = s match {
case "inf" => Integer.MAX_VALUE
case Int(x) => x
case _ => throw ...
}
Le but est que si la chaîne est égale à "inf", retourne Integer.MAX_VALUE. Si la chaîne est un entier analysable, retournez la valeur entière. Sinon jeter.
Définir un extracteur
object Int {
def unapply(s : String) : Option[Int] = try {
Some(s.toInt)
} catch {
case _ : Java.lang.NumberFormatException => None
}
}
Votre exemple de méthode
def getValue(s: String): Int = s match {
case "inf" => Integer.MAX_VALUE
case Int(x) => x
case _ => error("not a number")
}
Et l'utiliser
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...
Je sais que c’est une vieille question à réponse, mais c’est mieux à mon humble avis:
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
Bien sûr, il ne jette aucune exception, mais si vous le voulez vraiment, vous pouvez utiliser
getValue(someStr) getOrElse error("NaN")
Vous pourriez utiliser un garde:
def getValue(s: String): Int = s match {
case "inf" => Integer.MAX_VALUE
case _ if s.matches("[+-]?\\d+") => Integer.parseInt(s)
}
Que diriez-vous:
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
}
une version améliorée de l'extracteur de James Iry:
object Int {
def unapply(s: String) = scala.util.Try(s.toInt).toOption
}
Depuis Scala 2.13
introduit String::toIntOption
:
"5".toIntOption // Option[Int] = Some(5)
"abc".toIntOption // Option[Int] = None
nous pouvons convertir la String
en Option[Int]
après avoir vérifié si elle est égale à "inf":
if (str == "inf") Some(Int.MaxValue) else str.toIntOption
// "inf" => Option[Int] = Some(2147483647)
// "347" => Option[Int] = Some(347)
// "ac4" => Option[Int] = None
Comme alternative au if/else
, devenu fou avec Scala 2.13
, nous pouvons utiliser le nouveau Option::when
:
str.toIntOption.orElse(Option.when(str == "inf")(Int.MaxValue))