Can anyone explain how the symbol “=>” is used in

2020-01-31 08:20发布

问题:

I've read a lot of code snippets in scala that make use of the symbol =>, but I've never really been able to comprehend it. I've tried to search in the internet, but couldn't find anything comprehensive. Any pointers/explanation about how the symbol is/can be used will be really helpful.

(More specifially, I also want to know how the operator comes into picture in function literals)

回答1:

More than passing values/names, => is used to define a function literal, which is an alternate syntax used to define a function.

Example time. Let's say you have a function that takes in another function. The collections are full of them, but we'll pick filter. filter, when used on a collection (like a List), will take out any element that causes the function you provide to return false.

val people = List("Bill Nye", "Mister Rogers", "Mohandas Karamchand Gandhi", "Jesus", "Superman", "The newspaper guy")
// Let's only grab people who have short names (less than 10 characters)
val shortNamedPeople = people.filter(<a function>)

We could pass in an actual function from somewhere else (def isShortName(name: String): Boolean, perhaps), but it would be nicer to just place it right there. Alas, we can, with function literals.

val shortNamedPeople = people.filter( name => name.length < 10 )

What we did here is create a function that takes in a String (since people is of type List[String]), and returns a Boolean. Pretty cool, right?

This syntax is used in many contexts. Let's say you want to write a function that takes in another function. This other function should take in a String, and return an Int.

def myFunction(f: String => Int): Int = {
  val myString = "Hello!"
  f(myString)
}
// And let's use it. First way:
def anotherFunction(a: String): Int = {
  a.length
}
myFunction(anotherFunction)
// Second way:
myFunction((a: String) => a.length)

That's what function literals are. Going back to by-name and by-value, there's a trick where you can force a parameter to not be evaluated until you want to. The classic example:

def logger(message: String) = {
  if(loggingActivated) println(message)
}

This looks alright, but message is actually evaluated when logger is called. What if message takes a while to evaluate? For example, logger(veryLongProcess()), where veryLongProcess() returns a String. Whoops? Not really. We can use our knowledge about function literals to force veryLongProcess() not to be called until it is actually needed.

def logger(message: => String) = {
  if(loggingActivated) println(message)
}
logger(veryLongProcess()) // Fixed!

logger is now taking in a function that takes no parameters (hence the naked => on the left side). You can still use it as before, but now, message is only evaluated when it's used (in the println).



标签: scala