Below I have some scala code that should log "hi" if the argument to example is true
. However this logs ()
3 times.
class Poplar {
def hello (): String =
"hi"
def example (runHello: Option[Boolean]) {
if (runHello.isDefined) hello
None
}
}
object Main extends App {
val p = new Poplar()
println(p.example(Some(true)))
println(p.example(Some(false)))
println(p.example(None))
}
What is wrong about the above code that doesn't allow the code to log 'hi'?
CodePudding user response:
def example(runHello: Option[Boolean]) {
// code
}
is (deprecated) syntactic sugar for
def example(runHello: Option[Boolean]): Unit = {
// code
}
Unless the -Ywarn-value-discard
compiler option (which will reject code like this, which is why it's a very useful compiler option) is in effect, the code block can result in any value: since there's only one possible value for Unit
(that value is ()
) the "conversion" is trivial (albeit literally one which discards the value).
Your println
then prints the value (()
) which it receives from calling example
, thus the three printings of ()
.
I would suggest:
changing the result type of
example
toOption[String]
: it will returnSome("hi")
if the given option containstrue
andNone
otherwiseIn your
main
, printing the results usingforeach
:
p.example(Some(true)).foreach(println _)
p.example(Some(false)).foreach(println _)
p.example(None).foreach(println _)
CodePudding user response:
With the help of the others in this post I arrived at:
class Poplar {
def hello (): String =
"hi"
def example (runHello: Option[Boolean]): Option[String] = {
val rh = runHello.getOrElse(false)
if (rh) Some(hello)
else None
}
}
object Main extends App {
val p = new Poplar()
println(p.example(Some(true)))
println(p.example(Some(false)))
println(p.example(None))
}
Which will only log "hi" for the first println.