Scala Common syntax

Source: Internet
Author: User

Clojure was first FP, but because of the JVM, there was a need to make some compromises, including some OO programming methods
Scala first is OO, Java syntax is too redundant, a more mediocre language, Scala first do is to simplify, in a more concise way to write Oo, the main use of ' type inference ' can be inferred, you do not have to write, but if only this, it is better to use Python
So Scala, like its name, "Extensible Language", is a big bazaar that actively absorbs the excellent features of other languages, most importantly FP, you can use Scala to write Oo, but it recommends using FP to write Scala; Also includes the Actor model in Erlang
So Scala is not easy to learn, because it's more complicated.

0Scala Interpreter
Scala> 1 + 2res0:int = 3scala> Res0 * 3res1:int = 9scala> println ("Hello, world!") Hello, world!.

Code paragraph

In Scala, often omitted, but if there are multiple statements on one line, you must add

val s = "Hello"; println (s)

If a statement is to be written in multiple lines

X
+ y

This will be treated as 2 statements, two methods resolved,

(x
+ y)//brackets

X +
Y +
z//Put the operator in the previous line, implying that this sentence is not finished

1 Basic Syntax Basic types

Rich wrappers, providing more operations for basic types

Variable definition

val, immutable variable, constant, suitable for FP
var, variable variable, suitable for OO

scala> val msg = "Hello, world!" msg:java.lang.String = Hello, world!scala> msg = "Goodbye cruel world!" <console>:5:error:reassignment to Val msg = "Goodbye cruel world!"  

function definition

can be abbreviated to, the return value type does not need to write, you can infer that there is only one statement, so {} can be omitted

else YMAX2: (int,int) Int

Simple Funciton, the return value is unit, similar to void (the difference is void is no return value, and Scala has a return value, just returned as Unit, ())

Scala> def greet () = println ("Hello, world!") Greet: () Unit

Scala> greet () = = ()
Boolean = True

function parameter is not variable

def add (b:byte): Unit = {
b = 1//This won ' t compile, because B is a Val
sum + = b
}

Repeating parameters, the last * represents a mutable argument list, can pass in multiple string

for (Arg <-args) println (ARG)

scala> echo ("Hello", "world!")
Hello
world!

Function literal

How to translate ...
The basis of the Scala FP, function as first class, is passed as a parameter in the form of function literal

Args.foreach ((arg:string) = println (ARG))
Args.foreach (arg = println (ARG))//omitted type
Args.foreach (println)//actually even the list of entries can be omitted

You can see that Scala can say enough to omit the code, as long as you can infer that you do not write, which is a form of static type system to make up

For OO programmers, it may be more difficult to understand, in fact, equal to

for (Arg <args)
println (ARG)

Control structure

Because Scala is biased to FP, all control structures have return values, which makes it easy for FP to program

If, you can return a value

val filename =    if (!args.isempty) args (0)    Else "default.txt"  

while, in the FP does not recommend the use of loops, should be recursive, as far as possible to avoid

for, no use or brevity of Python and Clojure

 for (File <-fileshere //generator, for Traversal,  Each file is newly initialized if file.isfile;  //filter conditions, multiple rooms need to be used; if file.getName.endsWith (".scala"); //Second filter line <-filelines (file) //nesting for trimmed = Line.trim //mid-stream variable bindings, Val type, similar to Clojure let if trimmed.matches (pattern)) println (file + ":" + trimmed)        
For default does not produce a new collection, you must use yielddef Scalafiles = for  {    file <fileshere    if File.getName.endsWith (" . Scala ")  //yield produces a new collection, similar to Python   

match, switch-case

Can return values, FP style, so that only one last println is required
Default will break, do not need to add each time

Else "val friend =  Firstarg Match {case    "Salt "+" case "chips" + "case"eg GS "=" case_ = "//default}println (Friend)        

2 array of data structures
Variable sequence of homogeneous objects, suitable for OO scenarios
Val greetstrings = new Array[string] (3)//greetstrings is Val, but the inner array value is variable
Greetstrings (0) = "Hello" //scala with () rather than []
Greetstrings (1) = ","
Greetstrings (2) = "world!\n"
for (i <-0 to 2)
Print (Greetstrings (i))

Scala operators are equivalent to methods, so any method can be used in the form of an operator

1 + 2//(1). + (2), in the case of only one parameter, can be omitted. and ()

0 to 2//(0) to (2)

Greetstrings (0)//greetstrings.apply (0), which is why Scala uses () rather than []

Greetstrings (0) = "Hello"//greetstrings.update (0, "Hello")

Simplified array Initialization
Val numnames = Array ("zero", "one", "one")  //array.apply ("zero", "one", "one")
List

List is an immutable sequence of objects relative to array, suitable for FP scenes

Val onetwo = List (1, 2)
Val threefour = List (3, 4)

Val zeroonetwo = 0:: Onetwo//::
Val onetwothreefour = onetwo::: Threefour


The most common operators for list are::, cons, put the new elem on the list front
:::, merge of two lists

Right operand,::

In general, the left operand, for example, a * b = a.* (b)
But when the method name is: End, the right operand
1:: Twothree = twothree.::(1)

Append not supported
The reason is that the time of this operation will grow linearly with the length of the list, so it is not supported, only support the front-end cons, it is necessary append can consider Listbuffer

Tuple

The tuple and list are immutable, except that the Elem in the list must be of the same type, but the tuple can contain different types of elem

Val pair = ("//Auto inferred type is, Tuple2[int, String]println (pair._1)  //elem access method differs from list, due to different elem types in tuples 

Set and map

var jetSet = Set ("Boeing", "Airbus")
JetSet + = "Lear"
println (Jetset.contains ("Cessna"))


Val treasuremap = Map[int, String] () Treasuremap + = (1--"Go to Island") Treasuremap + = (2, "Find big X on ground.") println (Treasuremap (2)) 
Val romannumeral = Map (1, "I", 2--"II", 3--"III")//shorthand  

Scala requires both OO and FP, so mutable and immutable versions are required
Here the default is immutable, if you need to use the mutable version, you need to display the reference before use ...

Import Scala.collection.mutable.Set
Import Scala.collection.mutable.Map

3 Object-oriented-oo classes and objects

Relatively simple compared to Java definitions, default public

Class Checksumaccumulator {
private var sum = 0
def add (b:byte): Unit = {
sum + = b
} def checksum (): Int = {
return ~ (Sum & 0xFF) + 1
}
}

Further simplification, removing {} and return, defaults to returning the last computed value
Do not write return is the recommended way because the function tries not to have multiple exits

Class Checksumaccumulator {
private var sum = 0
def add (b:byte): Unit = sum + = b
def checksum (): Int = ~ (Sum & 0xFF) + 1
}

In fact, for the Unit (void), that is, there is no return value, for the FP, that function will only produce side effect, there is another shorthand way

Class Checksumaccumulator {
private var sum = 0
def add (b:byte) {sum + = b}//For the unit returned, another shorthand, with {} to indicate no return, so the front is not to write
def checksum (): Int = ~ (Sum & 0xFF) + 1
}

Instantiation of

Val acc = new Checksumaccumulator
Val CSA = new Checksumaccumulator
Acc.sum = 3


Singleton object

Scala cannot define static members, so use singleton objects to achieve the same goal

Import Scala.collection.mutable.Mapobject Checksumaccumulator {       //Use object instead of class  private Val cache = map[string, int] ()  def calculate (s:string): int =    if (Cache.contains (s))      cache (s)     for (c <s) Acc.add (c.tobyte) Val cs = acc.checksum () cache + = (S-CS) cs}}    

The most common scenario is that, as the entrance to the Scala program,

To run a Scala program, you must supply the name of a standalone singleton object with a Main method tha T takes one parameter (array[string]), and has a result type of Unit.

Import checksumaccumulator.calculate  object Summer {    def main (args:array[string]) {for      (Arg < args)        println (arg + ":" + Calculate (ARG))    }}  

Immutable objects

Applies to the FP scene object, so it is also called functional Objects.
Benefits, eliminate the complexity of the variable, can be assured when the parameters passed, multi-threaded use AH ...

The following is an example of defining a rational number class

Class Rational (N:int, D:int)  //Minimalist mode, no classes body

As defined above, there is no need to define member variables, but only through parameters, because there is no member variable defined, so there is nowhere to be mutable.

Class Rational (N:int, D:int) {require (d! = 0)Precondition, if require returns false will throw illegalargumentexception, block initializationPrivate Val g = gcd (N.abs, d.abs) val numer = n/g//Add immutable Member field for easy reference val denom = d/g def this (n:int) = This ( N, 1) //Auxiliary constructor Def + (that:rational): Rati Onal = //define operator new Rational (Numer * that.denom + that.numer * denom, Denom * that.denom //can also use This.number reference to ) def + (i:int): Rational = //Typical member function overloading new Rational (Numer + i * denom, denom) override def toString = Numer + " /"+ denom //override, method overload Private Def gcd (A:int, b:int): Int = if (b = = 0) A else gcd (b, a% b) }

4 function programming-FP functions and closures

member functions , OO Way

internal functions that require sharding and do not want to contaminate external namespaces

first-class function, unnamed function literal
Function-like variables can be assigned and passed as arguments, but in Scala it needs to be in the form of functions literal, which is instantiated at run time as a value

scala> var increase = (X:int) + x + 1scala> Increase (10)

Partially applied functions

scala> def sum (a:int, b:int, c:int) = a + B + cscala> val A = Sum _  //Replace the entire parameter list with placeholders scala> a (1, 2, 3) 
    //partial function, substituting a placeholder for a parameter scala> B (2) Res15:int = 6 

Closures

On the explanation of closures,
For the usual function, (x:int) + = x + 1, called closed term
and for (X:int) = x + more, called open term
So for the open, it must be at the time of the definition of the free variable more dynamic binding, so the context must have a definition of more, the closure of the open term process produced closure

scala> var more = 1scala> val Addmore = (x:int) + x + more  //generated closures, binding morescala> Addmore (Res19:int) = 11scala> more = 9999 scala> Addmore (Ten) Res21:int = 10009  //visible closure binding is not value, but the variable itself

Just see some surprised, go to clojure inside try, also such, bind the variable itself, the closure will take the latest value
Of course, the use of closures is generally not the case.

The following example is a more common case where the parameters of the function are closed
How can I access a variable that does not already exist when the closure is called? When a closure is generated, the compiler puts the variable from the stack into the heap, so the function ends up with access to the

def makeincreaser (more:int) = (X:int) + x + more

scala> val inc1 = makeincreaser (1)
scala> val inc9999 = makeincreaser (9999)
Scala> INC1 (10)
Res24:int = 11
Scala> inc9999 (10)
Res25:int = 10009

Currying

Increase the comparison of the two versions of Sum first,

Scala> def plainoldsum (x:int, y:int) = x + yscala> plainoldsum (1, 2) Res4:int = 3scala> def curriedsum (X:int) ( Y:int) = x + y  //currying version of sumcurriedsum: (int) (int) intscala> curriedsum (1) (2) Res5:int = 3

In fact currying, equivalent to calling two functions, first returns the function value of the second function, where closure x

Scala> def first (x:int) = (Y:int) + x + yfirst: (int) (int) + int

Remove the function value, the effect is to reduce the number of parameters, the first function of the parameters have been closure in the second function, and partially somewhat similar (difference)

scala> val onePlus = curriedsum (1) _oneplus: (int) + int = <function>scala> OnePlus (2) Res7:int = 3

What's the use? Used to create a control structure that is more like built-in
As below, {} is more like built-in, but {} has a restriction that only a single parameter list of arguments can be replaced with {}, so this time you need to use currying to reduce the number of entries

Scala> println ("Hello, world!")    //Like method call Scala> println {"Hello, world!"}  //More like the control structure of the built-in, such as if   

For FP, use inheritance and polymorphism with respect to OO, use functions as parameters to implement code reuse, and hopefully you can put function values in {} and appear more like built-in
For example, the following, each open file, operation, close files, fixed mode, so implementation of Withprintwriter, each time a different OP can be different operations, regardless of the file switch
In the case of OO implementations, it is necessary to pass in the base class object and use the polymorphic implementation to make the function more lightweight

def withprintwriter (file:file, op:printwriter = Unit) {  new PrintWriter (file)  try {    op (writer  finally {    writer.close ()}  }//To use Withprintwriter (  "date.txt") in the way that the method is called ), writer = writer.println (new java.util.Date))      

The parameters are reduced by currying, so you can use the {}

The new File ("date.txt") withprintwriter (file) {writer = writer.println (//) puts the value of the function in {}, much like built-in


Tail recursion, Tail recursion

As I said earlier, the FP avoids using loops and should use recursion
But the recursive efficiency is problematic, the stack is constantly stacked and it's easy to explode
So for some sort of recursion, tail recursion, the compiler automatically optimizes the loop execution to avoid using the stack multiple times.
The limitation is that not all situations can be written as tail recursion, in fact, only the loop can ...
Better than Clojuer, the compiler will automatically optimize

While, circular version, Oodef Approximateloop (initialguess:double): Double = {  var guess = initialguess while  (! Isgoodenough (guess))    guess improve (guess)  guess}//recursive version, Fpdef approximate (guess:double): Double =  if (Isgoodenough (guess)) Guess  else approximate (improve (guess))   

Scala Common syntax

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.