简体   繁体   中英

scala and akka function literal ? need help in understanding the language of functional pattern

entity(as[ConnectionData]) { connection_data =>

I am trying to understand in the above code snippet example how the connection_data, language wise (as I am new to scala), gets the result of the in unmarshaled entity function into it. Or what does the connection_data here signifies that later on I can do

m_client_id = connection_data.clientId
val port = connection_data.port

where does connection_data get set, binded, etc

Akka documentation (or more specifically, unmarshalling ) does a great job of explaning marshalling (which is a synonim for serialization/pickling of data):

"Marshalling" is the process of converting a higher-level (object) structure into some kind of lower-level representation, often a "wire format". Other popular names for it are "Serialization" or "Pickling".

In Akka HTTP "Marshalling" means the conversion of an object of type T into a lower-level target type, eg a MessageEntity (which forms the "entity body" of an HTTP request or response) or a full HttpRequest or HttpResponse.

What Akka attempts to do is look into the MessageEntity body, which is basically the payload provided by the HTTP request, and attempts to deserialize it using it's built in "deserializers", which you yourself define.

What this code means:

entity(as[ConnectionData]) { connection_data =>

Is that the Akka framework attempts to deserialize the payload received in the HTTP request to a ConnectionData object. If that succeeds, the next step will be to invoke the function where connection_data is an instance of the ConnectionData type, which you can use in your code. Akka-HTTP utilizes spray-json for it's built in unmarshalling, as an example, a possible ConnectionData deserializer would look like this:

case class ConnectionData(host: String, port: Int)

object ConnectionData extends DefaultJsonProtocol {
  implicit val connectionFormat = jsonFormat2(ConnectionData.apply)
}
def someFunction(a:Int)(b:Int => Int) = {
  a + b(2)
}

someFunction(1){ x =>
  x * 2
}

Basically it's a Function that is passed as a parameter. In this case someFunction is the entity method. x => x*2 is the conection_data => ... part. Take a look into the definition of entity function.

Additionally you could write it in single paranthesis' but for the call with the curly brackets you'll need to curry things up:

def someFunction(a:Int,b:Int => Int) = {
  a + b(2)
}

def someFunctionCurried(a:Int)(b:Int => Int) = someFunction(a, b)
def someFunctionCurried2(a:Int) = someFunction(a, _:Int => Int)

someFunctionCurried(3){ x => x * 2 }
someFunctionCurried2(4){ x => x * 2}

These are two ways to curry the function someFunction which has a single set of paranthesis in the second example.

Additionally there is a difference between def and val. You can curry the function like this:

val someFunctionCurried = (a:Int) => (b:Int => Int) => someFunction(a, b)
val someFunctionCurried2 = (a:Int) => someFunction(a, _:Int => Int)

If you take a look at the previous example (with def) the compiler will do that step for you or you could directly use val. But with val you need to know that it's evaluated when defined (as far as possible) and def everytime when used.

What did I mean with: "The compiler will do that step for you" ? Quite simple. In regard to higher-order-functions (hof) the compiler will make your method (def) to a function (val). So there's is also a semantic difference that you can make clear in the syntax. But there is much more literature out there with more examples, I hope this helps you.

But at least you can stick to "def" for not getting confused by val for function definition as the compiler will work that out. Obviously there are cases where val makes more sense in regard to performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM