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

前端 未结 1 1829
谎友^
谎友^ 2020-12-05 21:40

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 in

相关标签:
1条回答
  • 2020-12-05 22:04

    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).

    0 讨论(0)
提交回复
热议问题