5

Is there any difference between the following

def foo(s: String) = { ... }

and

def foo(s: => String) { ... }

both these definitions accept "sss" as parameter.

Bober02
  • 15,034
  • 31
  • 92
  • 178
  • 3
    This might be interesting for you: http://stackoverflow.com/a/4545703/298389 – om-nom-nom Aug 16 '12 at 17:18
  • Did you mean to put an '=' sign before the curly braces on both functions? The answers below assume this. It makes an important difference but would be a matter for a separate discussion. – Rick-777 Aug 17 '12 at 07:13

2 Answers2

19

An argument String is a by-value parameter, => String is a by-name parameter. In the first case, the string is passed in, in the second a so-called thunk which evaluates to a String whenever it is used.

def stringGen: String = util.Random.nextInt().toString

def byValue(s: String) =
  println("We have a '" + s + "' and a '" + s + "'")

def byName(s: => String) =
  println("We have a '" + s + "' and a '" + s + "'")

byValue(stringGen)  // constant value
byName (stringGen)  // evaluated twice

Often a by-name parameter is not used to evaluate it several times, but to lazily evaluate it once.

def logMessage = {
  println("Calculating log message...")
  new java.util.Date().toString
}

def log(enabled: Boolean, message: => String): Unit = {
  lazy val fullMessage = "LOG: " + message
  println("Test")
  if (enabled) println(fullMessage)
}

log(false, logMessage)
log(true , logMessage)
0__
  • 66,707
  • 21
  • 171
  • 266
2

In many cases they are the same, but

The => passes by name

The first passes by value

jcern
  • 7,798
  • 4
  • 39
  • 47