Учебники

Учебник Scala

Что такое Скала?

Scala — это типизированный язык программирования, который включает функциональное и объектно-ориентированное программирование. Он в первую очередь нацелен на платформу JVM, но также может быть использован для написания программного обеспечения для нескольких платформ, включая нативные платформы, использующие Scala-Native и среды выполнения JavaScript через ScalaJs.

Scala — это язык программирования, написанный для повышения масштабируемости приложения. Это масштабируемый язык. Отсюда и название «Скала». Этот язык предназначен для решения проблем Java и одновременно является более лаконичным. Первоначально разработанный Мартином Одерским, он был выпущен в 2003 году.

В этом руководстве по программированию Scala для начинающих вы изучите:

Зачем учить Скала

Вот основные причины изучения Scala:

  • Scala легко изучить для объектно-ориентированных программистов, разработчиков Java. Это становится одним из популярных языков в последние годы.
  • Scala предлагает первоклассные функции для пользователей
  • Scala может выполняться на JVM, что открывает путь к взаимодействию с другими языками.
  • Он предназначен для приложений, которые работают одновременно, распределены и устойчивы к сообщениям. Это один из самых требовательных языков этого десятилетия.
  • Это сжатый, мощный язык и может быстро расти в соответствии с потребностями своих пользователей.
  • Он является объектно-ориентированным и обладает множеством функциональных функций программирования, которые предоставляют разработчикам большую гибкость при кодировании так, как они хотят.
  • Scala предлагает много типов утки
  • Он имеет меньший шаблон, если вы приехали с Java
  • Фреймворки Lift и Play, написанные на Scala, находятся на кривой роста.

Как установить Scala

Чтобы начать писать программы Scala, вам нужно установить его на свой компьютер. Для этого вам необходимо посетить их сайт https://www.scala-lang.org/download/ , чтобы загрузить последнюю версию Scala.

Перейдя по ссылке, мы получили два варианта установки Scala на наши машины. Для этого урока мы загрузим интегрированную среду IntelliJ.

Перейдя по ссылке для скачивания, вы найдете две версии IntelliJ IDE.

Для этого урока мы загрузим Community Edition, которая является бесплатной и содержит все необходимое для написания программ Scala.

Шаг 1) на странице щелкните раскрывающийся список на Community Edition.

Он предоставляет нам возможность загрузить IntelliJ IDE вместе с JBR, который содержит реализацию JDK (Java Development Kit) OpenJDK, которая необходима Scala для компиляции и запуска кода.

Шаг 2) После загрузки IntelliJ дважды щелкните его, чтобы запустить мастер установки и следовать диалоговому окну.

Шаг 3) Выберите место для установки IDE.

Если случайно вы не загрузили один с JDK, мы все равно получим приглашение, где мы можем проверить, чтобы загрузить его, установив флажок.

Шаг 4) Оставьте остальные значения по умолчанию и нажмите «Далее».

Шаг 5) После завершения установки запустите IntelliJ IDE, щелкнув его значок запуска в меню запуска, как обычное приложение.

Вам все еще нужно пройти дополнительный шаг добавления плагина Scala в IntelliJ; Вы можете сделать это, щелкнув раскрывающееся меню настройки в правом нижнем углу экрана и выбрав опцию плагина.

На вкладке Marketplace поиск по Scala представит плагин в качестве первого результата под тегом Languages.

Шаг 6) Нажмите «Установить», после чего плагин начнет загрузку.

Шаг 7) После завершения загрузки вам будет предложено перезапустить IDE, чтобы установленный плагин начал работать.

После перезапуска вы окажетесь на той же странице, что и раньше, когда мы запускали IDE, но на этот раз мы уже установили плагин Scala.

Программа Scala Hello World

Шаг 1) Выберите опцию «Создать проект», которая приведет нас к странице, где мы сможем выбрать язык, который будет использовать наш проект.

Шаг 2) выберите Scala, установив флажок Scala и нажмите «Далее».

Шаг 3) Выберите место для сохранения файла наших проектов и дайте нашему проекту имя.

Если каталог не существует, IntelliJ предложит нам запросить разрешение на создание папки. Примите и нажмите Готово. Вы попадете в свой проект Scala, в котором в настоящее время нет кода Scala.

It will take some time to load some indexes so don’t worry if you’re not able to immediately do anything while there’s a progress bar at the bottom of your IDE, it simply means your IDE is loading some files necessary to run Scala and help with IDE autocompletion.

Step 4) Next, we’ll click on the projects tab on the left of the IDE and expand so we can see the contents of our project.

At the moment the project is empty and only contains a .idea folder and hello-world.iml file generated by the IDE. Our point of interest is the src folder. Src is where we store the source code for our project. It’s where we’ll create our first Scala file.

Step 5) Right-click on src to open a menu to create a new Scala file.

Затем мы создадим имя для файла, в этом уроке мы будем использовать привет, а затем выберем из выпадающего списка, что поместить в качестве содержимого файла Scala. Выберите «Объект»

Как только мы сделаем это, у нас будет файл Scala с объектом Singleton, который мы будем использовать для запуска нашего кода.

Теперь у вас есть файл Scala с объектом Hello. Вы напишите свою первую программу, расширив созданный вами объект с помощью ключевого слова App.

Расширяя наш объект с помощью App, сообщите компилятору, какой код запускать при запуске вашей программы. Сразу после расширения приложения зеленая стрелка появляется слева, указывая, что теперь вы можете запускать свою программу.

Внутри объекта Hello мы пишем одну функцию println (), которая используется для печати текста внутри него на консоли. Мы запустим наш код, нажав на зеленую стрелку.

Нажатие на стрелку предоставляет нам опцию Run, hello, после нажатия на нее наш код начнет компилироваться, и через несколько секунд мы увидим результаты нашей программы, напечатанные из консоли, встроенной в IntelliJ IDE.

И вот, мы успешно установили Scala и запустили нашу первую программу.

Что вы можете сделать с помощью Scala

  • Веб-разработка веб-интерфейса с ScalaJS
  • Разработка мобильных приложений под Android и IOS — с Scala Native
  • Серверные библиотеки, такие как HTTP4S, Akka-Http, Play Framework
  • Интернет вещей, использующих
  • Разработка игр
  • НЛП — обработка естественного языка с использованием набора библиотек ScalaNLP
  • Тестирование передовых методов программирования, таких как функциональное программирование и объектно-ориентированное программирование
  • Создайте высококонкурентное коммуникационное приложение, используя актеры, библиотеку для JVM, вдохновленную Erlang.
  • Используйте его для машинного обучения с использованием таких библиотек, как Figaro, которая занимается вероятностным программированием, и Apache Spark, которая

Анонимные функции

Язык Scala имеет анонимные функции, которые также называются функциональными литералами . Scala, являющийся функциональным языком, часто означает, что разработчики разбивают большие проблемы на множество мелких задач и создают множество функций для решения этих проблем. Чтобы упростить создание функций, Scala содержит эти функции, которые могут быть созданы без имени . Мы можем назначить их непосредственно переменным или определениям «def» следующим образом

val multiplyByTwo = (n:Int) => n * 2
def multiplyByThree = (n:Int) => n *3

Затем мы можем использовать обычные способы использования функций, передавая им параметры следующим образом.

multiplyByTwo(3)

//6

multiplyByThree(4)

//12

Эти методы пригодятся, когда мы хотим иметь чистый и лаконичный код. Мы можем использовать анонимные функции при определении методов, которые не являются большими и не требуют большого количества кода в их теле. Они очень простые и не нуждаются в церемонии для создания.

Эти методы не ограничиваются функциями с аргументами и могут использоваться для создания экземпляров методов, которые не принимают никаких аргументов.

val sayHello = ()=>{ println("hello") }

Большинство из этих анонимных функций используются в других частях нашего кода, где нам нужно создать быструю функцию на месте.

Другая причина, почему эти функции также называются встроенными функциями . Использование анонимных функций является распространенным шаблоном, который широко используется в библиотеке коллекций для выполнения быстрых действий над коллекцией.

Например, у нас есть метод filter, который использует встроенную функцию / анонимную функцию для создания другой коллекции только с элементами, которые соответствуют критериям, которые мы определили в анонимной функции.

val myList = List(1,2,3,4,5,6,7)

val myEvenList = myList.filter((n: Int) => n % 2 == 0)
//List(2,4,6)

val myOddList = myList.filter((n:Int) => n % 2 != 0)
//List(1,3,5,7)

Здесь у нас есть анонимные функции, которые проверяют, является ли значение, которое мы получаем из списка, нечетным и четным, и возвращают элемент.

//the one checking that the value is even
(n: Int) => n % 2 == 0

//the one checking that the value is odd
(n:Int) => n % 2 != 0

В Scala также можно использовать подстановочные знаки, где параметры нашей анонимной функции не названы. Например

var timesTwo = (_:Int)*2

timesTwo(5)
//10

В этом сценарии мы не называем передаваемый параметр. Единственное, что мы используем для подчеркивания, это подчеркивание.

Ленивая оценка

Большинство языков последовательно оценивают переменные и параметры функции, один за другим. В Scala у нас есть ключевое слово lazy, которое помогает работать со значениями, которые мы не хотим оценивать, пока на них нет ссылок.

Переменная, помеченная как ленивая, не будет оцениваться там, где она определена, это обычно называется нетерпеливым вычислением, она будет оцениваться только тогда, когда на нее ссылаются позже в коде.

Это может быть полезно, когда оценка значения может быть дорогостоящим вычислением, если это не тот случай, когда значение всегда необходимо, мы можем уберечь себя от выполнения дорогостоящих вычислений, которые могут замедлить наше программное обеспечение, сделав нашу переменную ленивой.

lazy val myExpensiveValue = expensiveComputation

def runMethod()={
    if(settings == true){
        use(myExpensiveValue)
    }else{
        use(otherValue)
    }
}

Это не единственный случай использования ленивых переменных. Они также помогают решать проблемы циклической зависимости в коде.

В случае ложных настроек нам может не потребоваться использовать myExoyValue, что может привести к тому, что мы избавим нас от дорогостоящих вычислений, которые помогут гарантировать, что пользователи хорошо проводят время, используя наше приложение, поскольку наши другие потребности могут быть правильно рассчитаны без чрезмерных затрат. баран.

В случае ложных настроек нам может не потребоваться использовать myExoyValue, что может привести к тому, что мы избавим нас от дорогостоящих вычислений, которые помогут обеспечить приятное времяпрепровождение пользователям при использовании нашего приложения, так как другие их потребности могут быть вычислены соответствующим образом без чрезмерных затрат. баран.

Лень также помогает с аргументами функции, где аргументы используются только тогда, когда на них ссылаются внутри функции. Эта концепция называется параметрами Call-by-name.

def sometimesUsedString(someValue:String, defaultValue:=> String)={
 if(someValue != null){
   use(defaultValue)
 }else{
   use(someValue)
   }
 }

Многие языки используют способ оценки аргументов по значению. Параметр, переданный через call-by-name, будет оцениваться только при необходимости в теле функции и не будет оцениваться до этого. Как только значение оценено, оно сохраняется и может быть повторно использовано позже без необходимости повторной оценки. Концепция, которая известна как запоминание.

Вывод типа

В Scala вам не нужно объявлять типы для каждой создаваемой вами переменной. Это происходит потому, что компилятор Scala может делать вывод типов на основе оценки правой части. Это позволяет вашему коду быть более кратким — это освобождает нас от написания шаблонов, где ожидаемый тип очевиден

var first:String = "Hello, "
var second:String = "World"
var third = first + second
//the compile infers that third is of type String

Higher-Order-Function

Функция более высокого порядка — это функция, которая может принимать функции в качестве аргументов и может возвращать функцию в качестве возвращаемого типа. В Scala функции считаются гражданами первого класса. Такое использование этих функций позволяет нам быть очень гибкими в отношении программ, которые мы можем создавать. Мы можем динамически создавать функции и динамически передавать функциональность другим функциям.

def doMathToInt(n:Int, myMathFunction:Int=>Int): Int ={
    myMathFunction(n)
}

В приведенной выше функции мы передаем int и функцию, которая принимает int и возвращает int. Мы можем передать любую функцию этой подписи. Под подписью мы подразумеваем ввод и вывод функции. Подпись Int => Int означает, что функция принимает Int в качестве входных данных и возвращает Int в качестве своих выходных.

Подпись () => Int означает, что функция ничего не принимает в качестве входных данных и возвращает Int в качестве выходных. Примером такой функции может быть случайная функция int для нас.

def generateRandomInt()={
 return scala.util.Random.nextInt()
}

Вышеуказанная функция имеет сигнатуру () => Int

У нас может быть функция с подписью scala () => Unit. Это означает, что функции ничего не принимают и не возвращают тип. Функция может выполнять какие-то вычисления, изменяя что-то, делая что-то предопределенное.

Подобные методы не приветствуются, так как они кажутся черным ящиком, который может повлиять на систему некоторыми неизвестными способами. Они также непроверены. Наличие явных типов ввода и вывода позволяет нам рассуждать о том, что делает наша функция.

Функция высшего порядка также может возвращать функцию.

Например, мы могли бы создать метод, который создаст функцию включения, то есть берет число и применяет к нему мощность.

def powerByFunction(n:Int):Int=>Int = {
  return (x:Int)=> scala.math.pow(x,n).toInt
}

Вышеуказанная функция принимает int. Наш возвращаемый тип — анонимная функция, которая принимает Int x, * мы используем int x в качестве аргумента для степенной функции.

Карринг

В Scala мы можем преобразовать функцию, которая принимает два аргумента, в один, который принимает один аргумент за раз. Когда мы передаем один аргумент, мы частично применяем его и в результате получаем функцию, которая принимает один аргумент для завершения функции. Карринг позволяет нам создавать функции, частично добавляя некоторые аргументы.

Это может быть полезно для динамического создания функций, прежде чем мы получим полный набор аргументов

def multiply two numbers(n:Int)(m:Int): Unit ={
  return n * m
}

Если нам нужно создать функцию, которая умножается на определенное число, нам не нужно создавать другой метод умножения.

Мы можем просто вызвать .curried для нашей функции выше и получить функцию, которая сначала принимает один аргумент, и вернуть частично примененную функцию

def multiplyTwoNumbers(n:Int)(m:Int): Unit ={
  return n * m
}

var multiplyByFive = multiplyTwoNumbers(5) 

multiplyByFive(4)

//returns 20

Сопоставление с образцом

В Scala есть мощный встроенный механизм, помогающий нам проверить, соответствует ли переменная определенным критериям, так же, как мы это делали бы в операторе switch в Java или в ряде операторов if / else. В языке есть сопоставление с образцом, которое мы можем использовать, чтобы проверить, относится ли переменная к определенному типу. Сопоставление с образцом в Scala является мощным средством и может использоваться для деструктуризации компонентов, которые имеют неприменимый метод, чтобы получить интересующие нас поля непосредственно из переменной, которую мы сопоставляем.

Сопоставление с образцом в Scala также обеспечивает более приятный синтаксис по сравнению с оператором switch.

myItem match {
  case true => //do something
  case false => //do something else
  case  _ => //if none of the above do this by default
}

Мы сравниваем нашу переменную с набором параметров, и когда соответствующая переменная соответствует критериям, выражение в правой части жирной стрелки (=>) вычисляется и возвращается как результат сопоставления.

Мы используем подчеркивание для отлова случаев, которые не встречаются в нашем коде. Он отражает поведение случая по умолчанию при работе с операторами switch.

class Animal(var legs:Int,var sound:String)
class Furniture(var legs:Int, var color:Int, var woodType:String)

myItem match {
case myItem:Animal => //do something
case myItem:Furniture => //do something else
case _ => //case we have a type we don't recognize do sth else
}

В приведенном выше коде вы можете узнать тип переменной myItem и на основе этой ветви перейти к некоторому конкретному коду.

Сопоставление с образцом проверяет, соответствует ли переменная

Подчеркивание работает как заполнитель, который соответствует любому другому условию, которое не соответствует другим элементам в описаниях выше. Мы берем переменную myItem и вызываем метод match.

  • мы проверяем, является ли myItem истинным с помощью и делаем некоторую логику в правой части жирной стрелки «=>.»
  • мы используем подчеркивание, чтобы соответствовать чему-либо, что не соответствует ни одному из операторов case, которые мы определили в коде.

С классами Case мы можем даже пойти дальше и деструктурировать класс, чтобы получить поля внутри объекта.

Используя ключевое слово sealed для определения наших классов, мы получаем преимущество, заключающееся в том, что компилятор тщательно проверяет случаи, с которыми мы пытаемся сопоставить, и предупреждает нас, если мы забываем обработать конкретный.

неизменность

Можно создать значения, которые не могут быть изменены другими функциями в Scala, используя ключевое слово val. Это достигается в Java с помощью ключевого слова final. В Scala мы используем ключевое слово val при создании переменной вместо var, что является альтернативой, которую мы использовали бы для создания изменяемой переменной.

Переменная, определенная с использованием ключевого слова val, доступна только для чтения, тогда как переменная, определенная с помощью var, может быть прочитана и изменена другими функциями или произвольно пользователем в коде.

var changeableVariable = 8

changeableVariable =10
//the compiler doesn't complain, and the code compiles successfully

println(changeableVariable)
//10

val myNumber = 7

myNumber = 4

//if we try this the code won't compile

Попытка присвоить значение myNumber после того, как мы объявили его как val, выдает ошибку времени компиляции или «переназначение в val».

Зачем использовать неизменность?

Неизменность помогает нам предотвратить непредвиденное изменение кода и других программистов нашими значениями, что может привести к неожиданным результатам, если они намерены использовать хранимое нами значение, вместо этого они могут сделать его копию. Таким образом, ошибки, которые могут быть вызваны несколькими действующими лицами, меняющими одну и ту же переменную, предотвращаются.

Классы и объекты:

Все мы знаем, что объекты — это объекты реального мира, а класс — это шаблон, который определяет объекты. Классы имеют как состояние, так и поведение. Состояния являются значениями или переменными. Поведение — это методы в Scala.

Давайте посмотрим, как вы можете определить класс, создать его экземпляр и использовать его с помощью Scala.

Здесь класс называется Rectangle, который имеет две переменные и две функции. Вы также можете использовать параметры l и b непосредственно как поля в программе. У вас есть объект, который имеет метод main и создал экземпляр класса с двумя значениями.

Пример:

class Rectangle( l: Int,  b: Int) {
  val length: Int = l
  val breadth: Int = b
  def getArea: Int = l * b
  override def toString = s"This is rectangle with length as $length and breadth as  $breadth"
  }
object RectObject {
  def main(args: Array[String]) {
    val rect = new Rectangle(4, 5)
    println(rect.toString)
    println(rect.getArea)    
  }
}

Все поля и метод по умолчанию общедоступны в Scala. Важно использовать переопределение, потому что метод toString определен для объекта в Scala.

наследование

Scala has multiple types of inheritance (like single, multi-level, multiple, hierarchical, hybrid,) that share a lot in common with traditional forms found in Java. You can inherit both from classes and traits. You can inherit the members of one class into another class using the keyword «extends». This enables reusability.

It’s possible to inherit from one class or multiple classes. It’s also possible to inherit from subclasses that themselves have their superclasses, creating a hierarchy of inheritance in the process.

In the below example, the Base class is Circle, and derived class is Sphere. A circle has a value called radius, which is inherited in the Sphere class. The method calcArea is overridden using the keyword override.

Example:

class Circle {
  val radius = 5;
  def calcArea = {
    println(radius * radius )
  }
}
class Sphere extends Circle{
 override def calcArea = {
    println(radius * radius * radius )
  }
}
  object SphereObject{
    def main(args : Array[String]){
      new Sphere().calcArea 
    }
  }

Abstraction

In Scala, we can create abstract methods and member fields using abstract classes and traits. Inside abstract classes and traits, we can define abstract fields without necessarily implementing them.

Example:

trait MakesSound{
    var nameOfSound:String
    def sound():String
}
abstract class HasLegs(var legs:Int){
    val creatureName:String

    def printLegs():String={
        return s"$creatureName has this number of legs: $legs"
    }
}

These fields are implemented by the classes that extend the trait or abstract class. You can use traits to create contracts as to what our application should be able to do and then implement those methods later.

trait DatabaseService{
    def addItemName(itemName:String)
    def removeItem(itemId:Int)
    def updateItem(itemId:Int, newItemName:String)
}

This way, we can plan out how our application will look like without implementing the methods which can help us envision how various methods will look like. It follows along a pattern know as programming to abstractions and not the actual implementation.

The class which is prefaced with keyword abstract can contain both abstract and non-abstract methods. But, multiple inheritances is not supported in abstract class. So, you can extend at most one abstract class.

Singleton Objects

A Singleton is a class that is only instantiated once in a program. It’s from a popular and useful programming pattern known as the «singleton pattern». It’s useful in creating instances that are meant to be long-living and will be commonly accessed throughout your program whose state is integral in coordinating the events of a system. Creating such a class in Scala is easy as Scala provides us with a simple means of creating singletons using the object keyword.

object UserProfile{
    var userName=""
    var isLoggedIn:Boolean = false
}

We can then reference this object throughout our program with the guarantee that all parts of our program will see the same data as there’s only one instance of it.

def getLoggedInStatus():Boolean={
   return UserProfile.isLoggedIn
}

def changeLoggedInStatus():Boolean={
    UserProfile.isLoggedIn = !UserProfile.isLoggedIn
    return  UserProfile.isLoggedIn
}

В Scala отсутствует понятие статических членов, поэтому вам нужно использовать одноэлементные объекты, которые действуют как статические члены класса.

Неявные классы

Неявные классы — это новая функциональность, добавленная после версии 2.1. Это в первую очередь, чтобы добавить новую функциональность для закрытых классов.

Неявное ключевое слово должно быть определено в классе, объекте или признаке. Первичный конструктор неявного класса должен иметь ровно один аргумент в своем первом списке параметров. Он также может включать дополнительный список неявных параметров.

В приведенном ниже примере добавлена ​​новая функциональность для замены гласных строки на *.

object StringUtil {
  implicit class StringEnhancer(str: String) {
    
    def replaceVowelWithStar: String = str.replaceAll("[aeiou]", "*")
  }
}

Вам нужно импортировать в тот класс, где вы его используете.

import StringUtil.StringEnhancer

object ImplicitEx extends App {
  val msg = "This is Guru99!"
  println(msg.replaceVowelWithStar)
}

Объектно-ориентированное программирование (ООП) против функционального программирования (ФП)

В ООП программы создаются путем группировки данных и функций, которые оперируют этими данными, в сильно связанные блоки. Объекты переносят свои данные в те поля и методы, которые с ними работают. В этом стиле программирования основной абстракцией являются данные, поскольку создаваемые методы предназначены для работы с данными.

Функциональное программирование, с другой стороны, разделяет данные и функции, которые работают с данными. Это позволяет разработчикам рассматривать функции как абстракцию и движущую силу при моделировании программ.

Scala обеспечивает функциональное программирование, имея функции в качестве первоклассных граждан, позволяя передавать их как значения другим функциям и возвращать как значения. Сочетание этих двух парадигм сделало Scala отличным выбором для создания сложного программного обеспечения в различных отраслях, таких как Data Science.

Важные рамки на Scala

Вот некоторые важные рамки Scala

  • Play — это платформа веб-приложений с открытым исходным кодом, использующая архитектуру MVC. Выпущенный в 2007 году и теперь лицензированный под Apache, он стал самым популярным фреймворком на GitHub в 2013 году. Такие фреймворки используют такие компании, как LinkedIn, Walmart, Samsung, Eero.
  • Lift — это еще один бесплатный веб-фреймворк, написанный на Scala, выпущенный в 2007 году. Foursquare использует Lift-фреймворк. Он высокопроизводительный, быстрее создает фреймворк.
  • Akka
  • коты
  • искра

Поддержка параллелизма

  • Значения в Scala по умолчанию неизменны. Это делает его очень адаптивным к параллельной среде.
  • В Scala есть множество функций, которые делают его лучшим для параллельных приложений.
  • Фьючерсы и обещания облегчают асинхронную обработку данных, поддерживая параллелизм.
  • Akka — инструментарий, использующий модель параллелизма Actor. Есть ряд актеров, которые действуют, когда они получают сообщения.
  • Параллельность с использованием потоков из Java также может поддерживаться в Scala.
  • Потоковая обработка — это еще одна замечательная функция, которая обеспечивает непрерывную обработку данных в реальном времени.

Scala обладает одними из лучших библиотек параллелизма в экосистеме Java.

  • Нативные потоки Java
  • Волокна из библиотек типа Vertex
  • ZIO — библиотека, которая имеет примитивы, помогающие нам справляться с параллелизмом и асинхронными вычислениями
  • СТМ — Сделка
  • Будущее — встроено в язык Scala

Ява против Скала

Вот основное различие между Java и Scala.

Scala Ява
Более компактный и лаконичный Сравнительно большие куски кода
Разработан и разработан как объектно-функциональный язык. Поддерживает широкий спектр функциональных функций программирования, таких как параллелизм, неизменность. Изначально развивался как объектно-ориентированный язык и начал поддерживать функциональные возможности программирования в последние дни. Все еще не силен как функциональный язык программирования.
Использует модель актора для поддержки параллелизма, которая является современной Использует традиционную потоковую модель для параллелизма.
Поддерживает рамки — Play, Lift Поддерживает Spring, Grails, многое другое
Поддерживает ленивую оценку Не поддерживает ленивую оценку
Нет статических членов Содержит статические члены
Поддерживает перегрузку оператора Не поддерживает перегрузку оператора
Компиляция исходного кода сравнительно медленная Компиляция исходного кода быстрее, чем Scala
Черты — действуют как интерфейсы Java 8 Интерфейсы Java 8 пытаются преодолеть разрыв между классами и интерфейсами
Переписать нужно Перезапись не требуется
Нет гарантий насчет кодов без ошибок Полная гарантия меньших дефектов
Поддерживает обратную совместимость. Scala не поддерживает обратную совместимость.
Операторы обрабатываются по-разному в Java и не являются вызовами методов. Все операторы в записях создаются с помощью метода, вызываемого в Scala.
Поддерживает множественное наследование с использованием классов, но не абстрактными классами Не поддерживает множественное наследование с использованием классов, но по интерфейсам
Код написан в компактной форме. Код написан в полной форме.
Scala не содержит статического ключевого слова. Java содержит ключевое слово static.

Резюме:

Из этого урока вы узнали, как начать работу со Scala. Вы также изучили функциональные и объектно-ориентированные функции. Вы также обнаружили сходства и различия между Java и Scala. Этот урок должен был помочь вам с множеством примеров, которые хорошо продемонстрированы.