Reputation: 461
Say I have:
case class User(
id: Int,
firstName: String,
lastName: String,
age: Int,
gender: Option[String])
To declare an Option value I type:
val x:Option[User] = Some(User(1,"x","x",13,Some("ss")))
how do I access x's members, for example
x.age
I get the following error with the above declaration
error: value age is not a member of Option[User]
x.age
Is this remotely possible
Upvotes: 0
Views: 1023
Reputation: 8996
So many answers ... for completeness, I think a cool way to work with Options (and any Monads for that matter) is to use a for-comprehension.
for( user <- x ) yield user.age
It will also work for arbitrary nested Options, say:
case class Address(street: String, number: Option[Int])
case class User(name: String, addr: Option[Address])
val u = Some(User("foo", Some(Address("bar", Some(2)))))
for( user <- u; addr <- user.addr; n <- addr.number) yield n
Upvotes: 1
Reputation: 51271
Study the Scaladoc page for Option. There are a surprising number of methods that return concrete types (i.e. non-monadic). Examples include fold
, getOrElse
, head
, max
, product
, sum
, and many more.
It's worth noting, however, that most of these are not safe at runtime (will throw an error if called on a None
). It's best to use methods that will supply a default when called on a None
. (fold
and getOrElse
are good.)
Upvotes: 1
Reputation: 215117
An alternative way to pattern matching for retrieving data from a monad is use flatMap
:
x.flatMap(user => Option(user.age))
// res128: Option[Int] = Some(13)
I just realize this doesn't really answer your question, but I'll still leave it here as an alternative option, unless there are different opinions.
While leaving above answer as is, I think a more idiomatic way to get values from option is getOrElse
:
x.map(_.age).getOrElse(0)
// res140: Int = 13
Or get
:
x.map(_.age).get
// res141: Int = 13
Upvotes: 1
Reputation: 973
What you are looking for is pattern matching. It lets you test the type of your x
.
You simply need to write:
x match{
case None => /* Your code if it's None */
case Some(user) => /* Here user has type User, so you can call its methods */
}
Upvotes: 0
Reputation: 498
You can access using pattern matching
val x: Option[User] = Some(User(1,"x","x",13,Some("ss"))
x match {
case Some(user) => user.age
case None => 0
}
http://www.scala-lang.org/api/2.12.x/scala/Option.html
Upvotes: 0