zam
zam

Reputation: 461

Accessing Option type members

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

Answers (5)

marios
marios

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

jwvh
jwvh

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

akuiper
akuiper

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

Omar
Omar

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

gaston
gaston

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

Related Questions