2014-05-22 26 views
29

tôi đang cố gắng để có được một số ra khỏi một trường xmlScala: chuyển đổi chuỗi int hoặc Không

... 
<Quantity>12</Quantity> 
... 

qua

Some((recipe \ "Main" \ "Quantity").text.toInt) 

Đôi khi có thể không có một giá trị trong xml, mặc dù . Văn bản sẽ là "" và điều này sẽ ném ra một java.lang.NumberFormatException.

Cách sạch sẽ để nhận Int hoặc Không là gì?

+0

có thể trùng lặp của [Scala là một chuỗi parseable như một đôi] (http://stackoverflow.com/questions/9542126/scala-is-a- string-parseable-as-a-double) – thSoft

Trả lời

52
scala> import scala.util.Try 
import scala.util.Try 

scala> def tryToInt(s: String) = Try(s.toInt).toOption 
tryToInt: (s: String)Option[Int] 

scala> tryToInt("123") 
res0: Option[Int] = Some(123) 

scala> tryToInt("") 
res1: Option[Int] = None 
+5

Nếu bạn đang phân tích cú pháp nhiều chuỗi rỗng, bạn có thể muốn bắt chúng một cách rõ ràng thay vì ném một ngoại lệ mỗi lần: 'if (s.isEmpty) None else Try (s.toInt) .toOption'. –

8

Thêm ghi chú phụ về cách sử dụng sau câu trả lời được chấp nhận. Sau import scala.util.Try, hãy xem xét

implicit class RichOptionConvert(val s: String) extends AnyVal { 
    def toOptInt() = Try (s.toInt) toOption 
} 

hoặc tương tự nhưng trong một chút hình thức xây dựng hơn là địa chỉ duy nhất một ngoại lệ có liên quan trong việc chuyển đổi sang những giá trị không thể thiếu, sau import java.lang.NumberFormatException,

implicit class RichOptionConvert(val s: String) extends AnyVal { 
    def toOptInt() = 
    try { 
     Some(s.toInt) 
    } catch { 
     case e: NumberFormatException => None 
    } 
} 

Như vậy,

"123".toOptInt 
res: Option[Int] = Some(123) 

Array(4,5,6).mkString.toOptInt 
res: Option[Int] = Some(456) 

"nan".toInt 
res: Option[Int] = None 
5

Đây là một cách khác để làm điều này mà không yêu cầu viết chức năng của riêng bạn và cũng có thể được sử dụng để nâng lên Either.

scala> import util.control.Exception._ 
import util.control.Exception._ 

scala> allCatch.opt { "42".toInt } 
res0: Option[Int] = Some(42) 

scala> allCatch.opt { "answer".toInt } 
res1: Option[Int] = None 

scala> allCatch.either { "42".toInt } 
res3: scala.util.Either[Throwable,Int] = Right(42) 

(Một nice blog post về đề tài này.)

+0

Ví dụ cuối cùng của bạn sẽ không cho kết quả đó. Có vẻ như lỗi cắt-dán. – jwvh

+0

oops. cảm ơn. chỉ thay đổi nó bởi vì bên trái là khó chịu dài. – Caoilte

Các vấn đề liên quan