preface

I’ve heard about Scala for a long time, but I didn’t really know more about it, except that it’s a hot language in the big data space. Just as the rise of big data development in the past few years has really made this JVM-based language popular. Recently, I started to participate in the company’s big data project, and faced with the computation and processing requirements of large data volume, I had to introduce the big data framework like Spark, which is written by Scala. Although Spark provides Java API, However, in order to be able to use Spark and troubleshoot potential problems in a timely manner, it is important to fully learn The language.

The main contents of this paper are as follows:

  • Introduction to Scala
  • Introduction to Scala syntax features
  • Scala and SpringBoot in action

Example project: github.com/wrcj12138aa…

Environment support:

  • JDK 8
  • SpringBoot 2.1.5
  • Maven 3.6.0
  • Scala 2.12.8

Know the Scala

Before we get to Scala, let’s get to know how Scala is read and where it comes from. In particular, as a Chinese programmer, I have a headache because I cannot pronounce the words in the face of new technologies or the pronunciation is very twisted. Here I have found the phonetic symbols of Scala [ˈskɑlə] and the pronunciation of words in Baidu Translation for your reference.

A quick look at Scala’s history: Scala is a programming language designed by Professor Martin Odersky of ecole Polytechnique Federale de Lausanne. Facing the strict language specification of Java, Professor Martin redesigned a more modern and extensible language based on JVM. And using the Scalable Language abbreviation, Scala, as its name, that’s where Scala came in. Since the release of Scala based on the Java platform at the end of 2003, the stable version of Scala has reached 2.12.8

Getting to the point, in order to learn about Scala, let’s first read the official description of Scala:

Scala combines object-oriented and functional programming in one concise, high-level language. Scala’s static types help avoid bugs in complex applications, and its JVM and JavaScript runtimes let you build high-performance systems with easy access to huge ecosystems of libraries.

From the above passage, we can draw the following information:

  1. Scala is a statically typed high-level programming language that combines object-oriented and function-oriented programming features.
  2. Scala runs on both JVM and JavaScript runtime environments.
  3. Scala is often used to build high-performance applications and frameworks.

We’ll learn about the rich features of the Scala language in the Scala Syntax section below. In order to build high-performance programs and frameworks, Spark, Flink, Kafka and other project frameworks in the field of large databases are all developed based on Scala, which shows that the use of Scala in high-performance scenarios is undoubtedly helpful.

Language features of Scala

  • It is both an object-oriented language and a functional language
  • Statically typed languages, like Java, but also support type inference
  • Seamlessly integrated into the Java ecosystem, Java libraries can be called and mixed development with Java can be done
  • Extensibility, you can customize the functions of the extension language according to your own needs

With a general understanding of Scala, let’s quickly set up the Scala environment and write our first line of Scala code.

Scala Environment Setup

Setting up a Scala environment is actually quite simple. There are two steps that can be summarized as follows:

Note: Before downloading the Scala installation package, you need JDK 8 or above in your native environment.

  1. Download the language package 2.12.8 from the Scala official website and decompress it to a local disk.

  2. Add the Scala environment variable and specify the Scala folder to extract. Since I’m running on a Mac environment, I only need to operate in the Shell configuration file. Modify Shell configuration file ~/. Bash_profile Add the following content to the bottom of the Shell configuration file and run the source ~/. Bash_profile command to make the configuration take effect.

After completing the above steps, the Scala locale is ready when you type scala-version on the command line and get something like the following.

Scala command line interaction

Scala REPL

Unlike Java, Scala also provides command-line interaction, known as REPL(read-eval-print-loop). For details, see Scala REPL OVERVIEW. Based on this, we can use Scala directly on the command line, which should be familiar to those with Python or Node.js.

The simplest version of Scala HelloWorld is done by typing Scala into interactive mode on the command line and then typing println(“Hello, scala “) return.

Println is the Scala println method, similar to system.out.println in Java.

Compile Scala classes

Instead of using command-line interaction, let’s try implementing a Scala class HelloWorld.

Start by creating a new helloWorld. scala file and writing a main method.

Doesn’t Scala look very different from Java’s main method? Try running first, and we’ll learn more about the syntax later.

The next step is to compile and run the source code. Similar to Java, the Scala library provides the Scala compiler tool scalac, which can compile Scala files into bytecode. There is also the interpreter tool Scala for running bytecode.

Compile using Scalac to generate helloWorld.class file;

scalac HelloWorld.scala
Copy the code

Finally, to run, execute Scala HelloWorld, and the console type HelloWorld to indicate success.

With the two simplest versions of HelloWorld available in Scala, let’s take a look at Scala’s basic syntax and features.

Scala syntax

variable

Scala has two keywords for declaring variables: var & val. Var is a declaration of variable, short for variable. Val is used to declare constants and is short for value. A colon (:) is used to separate the variable name from the type.

val x: Int = 1+1
var y: String = "abc"
Copy the code

Scala does not allow a semicolon to indicate the end of a statement; a newline is considered the beginning of a new statement

But unlike Java, where variables must be declared with a specified type, Scala’s type inference feature eliminates the need to explicitly declare a type, so we can write it as follows:

val x = 1+1
var y = "abc"
Copy the code

Var differs from val: val is a declared constant that cannot be changed after being assigned a value, and attempts to change the value will compile errors.

In addition, when a variable val is assigned to a reference object, its properties can be changed, but it can no longer point to any other object, so val can be understood as a variable that Java modifies with final.

The data type

Everything is an object in Scala. First, take a look at the official Scala type hierarchy, which includes both Java data types and Scala-specific types.

Java has eight basic data types, while Scala has nine basic data types. In addition to Double, Float, Long, Int, Short, Byte, and Boolean, there is an additional Unit type, which represents a type that does not make any sense and has one and only one value: Void (); void (); void ();

Each of these base types has a parent class AnyVal, which represents the generic value type. The opposite of AnyVal is the reference type AnyRef. Scala’s collection objects (Set, Map), String classes (String), and custom classes all belong to AnyRef. Equivalent to java.lang.object in Java.

Above AnyVal and AnyRef is Scala’s top type, which defines some of the most common methods like equals, hashCode, and toString.

Nothing and Null

There are two other types at the bottom of the Scala type hierarchy: Nothing and Null. Nothing is a subtype of all types and has no value under this type. Null, on the other hand, is a subtype of a reference type and has only one value: Null, which is mainly used when interacting with Java.

Value type conversion

Scala also supports type conversions for different value types, and they are one-way. Here is a diagram of the direction of value conversions.

Type mismatch: mismatch: type mismatch: type mismatch: type mismatch: type mismatch: type mismatch: type mismatch: type mismatch: type mismatch: type mismatch:

Method/function

Methods and functions are usually considered the same thing in Scala, but functions can be used as separate variables, which can be understood as Java8 Lambda expressions. First, let’s look at how they are defined, which is quite different from Java.

This is the simplest way to define a function/method. Scala allows you to omit braces and return keywords for single-line expressions.

Add (Int, Int) => Int (Int, Int) => Int (Int, Int) => Int (Int, Int) => Int ());

Anonymous functions, also called closures: represents functions that have no name. Use the function defined without specifying a variable name, for example, (x: Int) => x + 1

Scala defines methods using the def keyword, which Java does not have, and def is followed by the method name, argument list, return type, and method body. Common method definition syntax is shown below

Note that the result of the last line of statements is the default return value in Scala methods. (Like Java, Scala has the return keyword, but it’s rarely used for brevity.) If the method defines a return value of type Unit, the method returns no value.

In addition, if a function or method is called with no input arguments, you can omit the parentheses.

Following some of the features supported in Scala functions/methods: mutable arguments, default arguments, named arguments:

1. Variable parameters

Scala allows you to specify that the last argument to a function is repeatable by placing an asterisk * after the parameter type. Java uses… :

Similarly, an array is used internally to receive variable arguments.

2. Default parameters

Scala allows you to specify default values for function arguments, so that even if the function is called without passing parameters, the default values are ignored. This is a feature that Java doesn’t have, but it’s also easy to use.

3. Name parameters

Although the argument list order is specified when a function is defined, Scala allows arguments to be passed by specified parameter names instead of the order defined, as shown in the following example:

Process control

There are two kinds of flow control usually involved in the program: conditional judgment and cyclic processing.

conditional

Scala has the same if-else syntax as Java for conditional judgment, but also provides a mechanism for pattern matching for conditional judgment.

This is an updated version of the Java switch statement.

This uses the new keyword match. The left side represents the value to be matched. The right side contains four case expressions, each representing a condition.

The match expression allows you to accept a return value, just as the above example returns a String, so pattern matching is usually defined in functions as follows:

If multiple statements need to be executed in a matching condition, then braces {} will be used to contain the statement. Note that once a matching condition is successfully matched, the other conditions will not be executed, with the effect of a break.

Scala’s pattern matching is only briefly demonstrated in this article, with extensive usage details in the official documentation – Pattern Matching section

Circulation processing

Scala’s loop syntax is unique in that it uses for + <- to iterate over elements and provides convenient until and to methods to iterate over elements. Note that the until method uses a half-closed interval and does not contain the last digit of the index. The until and to methods basically build a Range object and iterate over it.

In addition to the above simple usage, the for loop can also be iterated with if conditions, as shown in the following simple example.

class

The concept of class in Scala is basically the same as that in Java, but the syntax form and usage are more flexible.

Here is the simplest Scala class definition and use, creating a User object and assigning it to the user1 variable.

The new keyword is used to create the instance, and since the current User does not define any constructors, there is only one default no-parameter constructor, which can simply omit the parentheses ().

The constructor

If it seems strange to see how a class with a custom constructor is defined, the arguments required by the constructor are immediately following the parentheses of the class name.

There is a question: if there are multiple constructor functions, how should the class be defined? For example, def this(…) based on the original constructor. A new method is defined that executes this(name, age) internally, actually calling the original constructor. Scala calls this definition method the secondary constructor, following the primary constructor after the class name.

Scala allows a class to have multiple helper constructors, but only one primary constructor, and the primary constructor must be called on the first line inside the helper constructor, which is indirectly called through multiple helper constructors.

If the secondary constructor has additional construction parameters, field associations need to be added, and fields such as the name and age of the Person class above will not be automatically generated as the primary constructor does.

Member variables and Getter/Setter syntax

In Java development, it is common to privatize a Java Bean’s member variable and provide getters/setters for external manipulation of that variable. How to do that in Scala classes is actually quite simple. First look at the example. Members of a member variable are public by default, and they can be hidden outside the function using the private access modifier.

Note that the field declaration uses the _ keyword, which in Scala represents the default value for a particular type and is used as a placeholder, or an empty String if it is a String.

Inheritance to rewrite

Inheritance is one of the most important features of object-oriented languages, and Scala, like Java, uses extends and only allows single inheritance. There are two kinds of inheritance, one is that the parent class adopts the default constructor, the other is that the parent class has a custom constructor, the subclass definition must meet the requirements of the parent class constructor parameters, will execute the parent class’s main constructor first, then execute the subclass’s own constructor.

When a subclass inherits a parent class, it is also easy to override the parent method. Using the override keyword to modify the access that needs to be overridden, subclasses default to the parent method of the form super.foo(), which we can simply adjust to a custom implementation.

Trait

Traits are similar to Java interfaces that extend our classes. Like Java’s interfaces, traits cannot be instantiated and typically provide several abstract methods and fields, implemented by concrete classes using the extends keyword.

One difference is that when a class needs to implement multiple traits, the extends can only refer to one Trait, and the rest of the traits need to be associated with the with keyword, as shown in the example below.

Case Class

A Case Class is a special Class that is unique to Scala and is defined in the same way as a normal Class, but with the Case Class combination keyword. Mainly used in immutable data and pattern matching.

Instead of using the new keyword to instantiate Case Class classes, there is a default apply method that takes care of object creation. And assignment fields are decorated with public val by default, making the field immutable.

An additional note is that when two Case Class objects are compared ==, Scala compares them by value, not by reference.

singleton

Scala declares singletons separately using the object keyword and defines them in the same way as classes, such as Object Box. But singletons are also a special class that has one and only one instance and is created the first time it is used.

Associated objects and associated classes

Scala allows a singleton to share a name with a class, and the two form a companion relationship, with the singleton becoming the companion of the class and the class becoming the companion of the singleton. The associated relationship is defined by the member defined in the associated object, which can be used in the associated class.

The Tuple tuples

Tuples are also a special class in Scala that allows different types of elements to be contained and are immutable. The common usage is when we need the function to return multiple values, this is powerful.

Let’s start with the creation and use of tuples

The Tuple2 class belongs to the element class defined in Scala, which starts from Tuple2… Tuple22 has a total of 21 such classes, each class represents the current corresponding number of parameters, that is, the tuple contains a maximum of 22 parameters.

Tuples are also easy to access, using tuple._n to fetch the NTH element.

A collection of

In addition to the Java-compatible collection framework, Scala also provides a rich and powerful collection class. Let’s take a look at some of the most common collections in Scala.

Set

A container object that contains no repeating elements. There are immutable sets and mutable sets. The default is immutable.

The common operation methods of immutable Set are

  • xs.contains(x).xs(x)Determines whether the element exists in the collection
  • xs intersect ys.xs & ysTake the intersection of two sets
  • xs union ys.xs | ysTake the union of two sets
  • xs diff ys.xs &~ ysTake the difference between the two sets

The common operation methods of mutable Set are

  • xs add xAdd to collection
  • xs remove xRemove from the collection
  • xs.clear()Empty the collection
  • xs(x) = bxs.update(x, b)Update the collection

Map

Map collections are typically stored as key-value pairs. There are two types of usage syntax:

  • key -> valueWay to add elements
  • (key, value)Way to add elements

A Map Set, like a Set, can be immutable or immutable. The default value is immutable.

Common Map operations are as follows

  • map.keysReturns an iterable containing all keys
  • map.keySetReturns a collection of all keys
  • map.valuesReturns an iterable containing all values
  • map(k) = vUpdate the element
  • map.put(k, v)The new element
  • map.remove(k)Remove elements
  • map.clear()Clearing the Map Collection

An array of

Scala arrays correspond to Java arrays one to one. Using Array as an Array identifier, let’s take a look at how to declare a fixed-length Array and use it simply.

When accessing a specified element in an array, use the parentheses and index format. When the element has no value, use null to indicate that the element has no value.

In addition to fixed-length arrays, Scala also provides ArrayBuffers, an array implementation of Scala’s mutable container that can directly access and modify the underlying array as follows:

Scala provides many variable container collection, such as ArrayBuffer ListBuffer, list, queue, etc., are encapsulated in Scala. Collections. Mutable. * package.

Use an array can have cross-border access, when there was a cross-border access Scala arrays, throw Java. Lang. IndexOutOfBoundsException anomalies.

Scala: Scala + Spring Boot

With all the syntax and features of Scala exposed, let’s see how it mixes with Java development by writing a simple Spring Boot Web application in Scala that accesses hello requests.

We use IDEA as a development tool and use Scala. In order for the IDE to provide better Scala language support, we can install Scala plug-ins first

IO/create a normal SpringBoot project, download it to a local directory, unzip it and open it with IDEA.

Create a new Scala source directory based on the original directory interface.

After the Scala source directory is created, go to the Pom file and modify the XML configuration:

  1. Let’s start with the Scala library, version 2.12.8

  2. After adding the Scala dependencies, we also need to add a Maven Plguin for Scala compilation.

Now that the Scala project configuration is complete, you can write Scala code.

In order to accept Hello requests, the project POM relies on spring-boot-starter-Web

Create a new Scala class HelloContrroller. Scala that implements a method that accepts/Hello requests as follows

Then start the project directly the bootstrap class com. Blog4one. Learn. ScalaActionsApplication, start log below indicates start is successful, the default service listening on port 8080.

Open a browser, type http://localhost:8080/hello, return can see the result.

The browser’s successful response also shows that HelloContrroller written in Scala can accept and process the response, while the underlying is still built based on the Java framework Spring Boot.

conclusion

The basic Syntax and features of Scala are introduced here. Scala is run on JVM, but its syntax and functions are extremely flexible. It will take some time to master Scala’s advanced features and uses. Interested partners can follow my wechat public account, I will update as soon as possible.

reference

  • Scala: fanyi.baidu.com/?aldtype=16…
  • Introduction to Scala: www.baeldung.com/scala-intro
  • From Java to Scala to Kotlin: juejin.cn/post/684490…
  • Scala – wikipedia, the free encyclopedia: zh.wikipedia.org/wiki/Scala
  • Scala repl overview: docs.scala-lang.org/overviews/r…
  • Learn Scala in Minutes:learnxinyminutes.com/docs/zh-cn/ Y…
  • GETTING STARTED WITH SCALA IN INTELLIJ: docs.scala-lang.org/getting-sta…
  • TOUR OF SCALA: docs.scala-lang.org/tour/tour-o…
  • Scala Class: Twitter.github. IO /scala_schoo…
  • SpringBoot quick Start guide for Scala developers: afoo.me/posts/2015-…