Урок за Scala
⚡ Умно обобщение
Учебникът за Scala представя статично типизиран, JVM-базиран език, който обединява обектно-ориентирано и функционално програмиране. Ръководството обхваща инсталирането, синтаксиса, основните функции и рамки, които правят Scala идеален за изграждане на едновременни, мащабируеми и сбити съвременни приложения.

Какво е Scala?
Scala е статично типизиран език за програмиране, който комбинира обектно-ориентирано и функционално програмиране, за да подобри мащабируемостта на приложенията. Scala работи предимно на платформата JVM и разработчиците могат да го използват и за писане на софтуер за нативни платформи чрез Scala-Native или за браузъра чрез ScalaJs и... JavaСценарий време на изпълнение.
Scala е мащабируем език, използван за изграждане на софтуер за множество платформи, откъдето идва и името му. Езикът е проектиран да реши няколко проблема с многословието, открити в Java като същевременно остава кратък. Мартин Одерски проектира Scala, а първата публична версия се появи през 2004 г.
Защо да научите Scala
Ето основните причини да научите езика за програмиране Scala:
- Scala е лесен за научаване от обектно-ориентирани програмисти и Java разработчици и се превърна в един от популярните езици през последните години.
- Scala предлага първокласни функции за потребителите.
- Scala може да се изпълни на JVM, проправяйки пътя за оперативна съвместимост с други езици.
- Той е проектиран за приложения, които са едновременни, разпределени и устойчиви, задвижвани от съобщения, което го прави един от най-търсените езици за програмиране на това десетилетие.
- Това е кратък, мощен език, който може бързо да расте според търсенето на своите потребители.
- Той е обектно-ориентиран и включва много функционални функции за програмиране, което дава на разработчиците голяма гъвкавост в начина, по който пишат код.
- Скала предлага Duck Typing чрез структурни типове.
- Има по-малко шаблонни формулировки от Java.
- Фреймворците Lift и Play, написани на Scala, продължават да се развиват и да набират популярност.
Как да инсталирате Scala
За да започнете да пишете програми на Scala, трябва да го инсталирате на компютъра си. За целта посетете официалния сайт на адрес https://www.scala-lang.org/download/ за да изтеглите най-новата версия на Scala.
Следвайки връзката, ще ви бъдат представени две опции за инсталиране на Scala. За този урок за Scala ще използваме IntelliJ IDEA, което осигурява отлична поддръжка на Scala веднага щом е инсталирано.
След като посетите връзката за изтегляне, ще намерите две издания на IntelliJ IDE.
За този урок по Scala ще изтеглим Community Edition, който е безплатен и включва всичко необходимо за писане на Scala програми.
Стъпка 1) Изберете Издание за общността.
На страницата щракнете върху падащото меню на „Издание за общността“.
Той предлага опция за изтегляне на IntelliJ IDE заедно с JBR, която съдържа JDK имплементация (Java Комплект за разработка), като например OpenJDK, от който Scala се нуждае, за да компилира и изпълни код.
Стъпка 2) Стартирайте инсталацията.
След като изтеглите IntelliJ, щракнете двукратно върху инсталатора и следвайте инструкциите на екрана.
Стъпка 3) Изберете местоположение.
Изберете място за инсталиране на IDE.
Ако не сте изтеглили пакета с JDK, инсталаторът все пак ще ви подкани да добавите JDK чрез квадратче за отметка по време на настройката.
Стъпка 4) Кликнете върху Напред.
Оставете останалите настройки по подразбиране такива, каквито са, и щракнете върху „Напред“.
Програма Scala Hello World
Стъпка 5) Щракнете върху иконата за стартиране.
След като инсталацията приключи, стартирайте IntelliJ IDE, като щракнете върху иконата му за стартиране в менюто "Старт" като обикновено приложение.
Все още трябва да добавите плъгина Scala към IntelliJ. Кликнете върху падащото меню в менюто за конфигуриране в долния десен ъгъл на екрана и изберете опцията „Плъгини“.
В раздела „Пазар“ потърсете Scala. Плъгинът се показва като първия резултат под етикета „Езици“.
Стъпка 6) Инсталирайте плъгина.
Щракнете върху „Инсталиране“, за да започнете изтеглянето на плъгина Scala.
Стъпка 7) Рестартирайте IDE.
След като изтеглянето приключи, ще бъдете подканени да рестартирате IDE, за да може инсталираният плъгин да започне да работи.
След рестартиране се връщате на същата страница както преди, но сега плъгинът Scala е инсталиран и готов.
Стъпка 8) Изберете „Създаване на проект“, което води до страница, където можете да изберете езика за проекта.
Стъпка 9) Изберете Scala, като поставите отметка в квадратчето Scala и щракнете върху Напред.
Стъпка 10) Изберете място за запазване на файла на проекта и дайте име на проекта.
Ако директорията не съществува, IntelliJ ще поиска разрешение за създаването ѝ. Приемете и щракнете върху „Готово“. След това ще бъдете пренасочени към вашия Scala проект, който в момента не съдържа Scala код.
Зареждането на индексите отнема известно време, така че не се притеснявайте, ако не можете да взаимодействате с IDE, докато в долната част се показва лента за напредък. IDE зарежда файловете, необходими за стартиране на Scala и осигуряване на автоматично довършване.
Стъпка 11) Щракнете върху раздела Проект отляво на IDE и го разгънете, за да видите съдържанието на проекта.
В този момент проектът е празен и съдържа само папка .idea и файл hello-world.iml, генериран от IDE. Интересна е папката src, която съдържа изходния код на проекта. Това е мястото, където създавате първия си Scala файл.
Стъпка 12) Щракнете с десния бутон върху src, за да отворите меню и да създадете нов Scala файл.
Изберете име за файла. За този урок по Scala използвайте здравей, след което изберете Обект от падащото меню за типа съдържание на Scala файла.
След като направите това, ще имате Scala файл, който съдържа singleton обект, който ще използвате за изпълнение на кода.
След като вече имате Scala файл с обект Hello, напишете първата си програма, като разширите създадения от вас обект с помощта на ключовата дума App.
Разширяването на обекта с App указва на компилатора кой код да изпълни при стартиране на програмата. Веднага след разширяването на App, отляво се появява зелена стрелка, показваща, че програмата вече е изпълнима.
Вътре в обекта Hello напишете функцията println(), за да отпечатате текста в конзолата. Стартирайте програмата, като щракнете върху зелената стрелка.
Щракването върху стрелката показва опцията „Изпълни Hello“. Избирането ѝ компилира кода и след няколко секунди изходът на програмата се появява в конзолата на IntelliJ.
Вече успешно инсталирахте Scala и стартирахте първата си програма.
Какво можете да правите със Scala
Scala се използва широко в много области поради своята гъвкавост и JVM оперативна съвместимост. Често срещани случаи на употреба включват:
- Фронтенд уеб разработка със ScalaJS.
- Мобилна разработка за Android и iOS със Scala Native.
- Сървърни библиотеки като HTTP4S, Akka-Http и Play Framework.
- Приложения на Интернет на нещата (IoT).
- Разработка на игри.
- Обработка на естествен език с помощта на пакета библиотеки ScalaNLP.
- Практикуване на напреднали техники като функционално програмиране и обектно-ориентирано програмиране едновременно.
- Приложения за високоефективна комуникация, използващи актьори, библиотека за JVM, вдъхновена от Erlang.
- Машинно обучение с библиотеки като Figaro за вероятностно програмиране и Apache Spark за обработка на данни в голям мащаб.
Анонимни функции
Езикът Scala поддържа анонимни функции, наричани още функционални литералиТъй като Scala е функционален език, разработчиците често разделят големи проблеми на много малки задачи и създават много функции. За да улесни това, Scala позволява функциите да бъдат... инстанциран без имеМожете да ги присвоите директно на променливи или на дефиниции, използвайки def, както е показано в следния пример в Scala:
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) } }
Това не е единственият случай на употреба на лениви променливи. Те също така помагат за справяне с циклични зависимости в кода.
Ако флагът за настройките е „false“, не е необходимо да използвате myExpensiveValue, което ви спестява скъпоструващи изчисления. Това помага да се гарантира, че потребителите имат безпроблемно преживяване, защото ресурсите не се губят за стойности, които никога не се четат.
Мързелът помага и с аргументите на функциите, където аргументите се използват само когато са посочени във функцията. Тази концепция се нарича параметри с извикване по име.
def sometimesUsedString(someValue:String, defaultValue: => String) = { if(someValue != null) { use(defaultValue) } else { use(someValue) } }
Много езици използват подхода „извикване по стойност“ за оценка на аргументи. Параметър, предаден чрез извикване по име, се оценява само когато е необходим в тялото на функцията. След като стойността бъде оценена, тя се съхранява и може да бъде използвана повторно по-късно без повторна оценка, концепция, известна като мемоизация.
Извод за тип
В Scala не е необходимо да декларирате типове за всяка променлива, която създавате, защото компилаторът на Scala може да изведе типове от дясната страна на израза. Това позволява кодът ви да бъде по-кратък и ви освобождава от писане на шаблонни формулировки, където очакваният тип е очевиден.
var first:String = "Hello, " var second:String = "World" var third = first + second //the compiler infers that third is of type String
Функция от по-висок ред
Функция от по-висок ред е функция, която може да приема функции като аргументи и да връща функция като тип връщане. В Scala функциите се считат за пълноценни. Използването на функции по този начин ви позволява да бъдете много гъвкави във видовете програми, които можете да изграждате. Можете да създавате функции динамично и динамично да предоставяте функционалност на други функции.
def doMathToInt(n:Int, myMathFunction:Int=>Int): Int = { myMathFunction(n) }
Във функцията по-горе, вие предавате Int и функция, която приема Int и връща IntМожете да предадете всяка функция от този подпис. Под подпис имаме предвид входа и изхода на функцията. Подпис на Int => Int означава, че функцията приема Int като вход и връща Int като изход.
Подпис на () => Int означава, че функцията не приема нищо като вход и връща Int като изход. Пример за такава функция е тази, която генерира произволно цяло число.
def generateRandomInt() = { return scala.util.Random.nextInt() }
Горната функция има сигнатура () => Int.
Функцията може да има и сигнатура () => UnitТова означава, че функцията не приема нищо и не връща тип. Вместо това функцията може да промени някакво състояние или да изпълни предварително определено действие.
Този вид методи не се препоръчват, защото могат да действат като черна кутия, която влияе на системата по неизвестни начини. Освен това са по-трудни за тестване. Наличието на явни типове вход и изход ви позволява да разсъждавате за това какво прави вашата функция.
Функция от по-висок ред също може да върне функция. Например, можете да създадете метод, който връща степенна функция, която приема число и прилага степен към него.
def powerByFunction(n:Int): Int=>Int = { return (x:Int) => scala.math.pow(x,n).toInt }
Функцията по-горе приема Int. Типът на връщане е анонимна функция, която приема Int. x и го използва като аргумент за степенната функция.
Къри
В Scala можете да конвертирате функция, която приема два аргумента, в такава, която приема по един аргумент. Когато подадете един аргумент, вие го прилагате частично и в крайна сметка получавате функция, която приема останалия аргумент, за да завърши извикването. Кърирането ви позволява да изграждате функции чрез частично добавяне на някои аргументи.
Това е полезно за динамично създаване на функции, преди да имате пълен набор от аргументи.
def multiplyTwoNumbers(n:Int)(m:Int): Int = { return n * m }
Ако ви е необходима функция, която умножава по определено число, не е необходимо да създавате друг метод за умножение. Можете да приложите един аргумент към карираната функция и да използвате повторно резултата:
def multiplyTwoNumbers(n:Int)(m:Int): Int = { return n * m } var multiplyByFive = multiplyTwoNumbers(5) _ multiplyByFive(4) //returns 20
Съвпадащ модел
Scala има мощен вграден механизъм, който ви помага да проверите дали дадена променлива отговаря на определени критерии, подобно на оператора switch в Java или верига от if/else оператори. Езикът поддържа съпоставяне на шаблони, което можете да използвате, за да проверите дали дадена променлива е от определен тип. Съпоставянето на шаблони в Scala е мощно и може да деструктурира компоненти, които имат unapply метод за получаване на полетата, които ви интересуват, директно от променливата, която се съпоставя.
Съпоставянето на шаблони в 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 _ => //unknown type, do something else }
В горния код можете да откриете типа на myItem променлива и въз основа на това да се разклони към специфичен код.
Съпоставянето на шаблони проверява дали променливата съвпада с всеки случай по ред.
Подчертаването работи като заместител, който съответства на всяко условие, което другите case оператори не изпълняват. Вземате променлива myItem и се обадете на match метод.
- Проверете дали
myItemistrueи изпълнете логиката от дясната страна на дебелата стрелка „=>“. - Използвайте долната черта, за да намерите съвпадение с всичко, което не съответства на нито един от case операторите, дефинирани в кода.
С case класовете можете да деструктурирате класа до extract полета вътре в обекта.
Чрез използване на sealed ключова дума за дефиниране на класове, получавате предимството компилаторът да проверява изчерпателно случаите, които се опитвате да съпоставите, и да ви предупреждава, ако забравите да обработите някой от тях.
Неизменност
Възможно е да се създадат стойности, които не могат да бъдат променяни от други функции в Scala, като се използва val ключова дума. Това се постига чрез Java като използвате final ключова дума. В Scala използвате val при създаване на променлива вместо var, което е алтернативата за променливи променливи.
Променлива, дефинирана с помощта на val ключовата дума е само за четене, докато тази, дефинирана с var може да бъде прочетено и променено по-късно от други функции или от потребителя в кода.
var changeableVariable = 8 changeableVariable = 10 //the compiler does not complain, and the code compiles successfully println(changeableVariable) //10 val myNumber = 7 myNumber = 4 //this will not compile
Опитвам се да присвоя стойност на myNumber след като го обяви за 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 a rectangle with length $length and breadth $breadth" } object RectObject { def main(args: Array[String]) { val rect = new Rectangle(4, 5) println(rect.toString) println(rect.getArea) } }
Всички полета и методи са публични по подразбиране в Scala. Важно е да се използват override , защото toString вече е дефиниран за всеки обект в Scala.
наследяване
Scala има множество видове наследяване (единично, многостепенно, множествено, йерархично и хибридно), които имат много общи черти с традиционните форми, открити в JavaМожете да наследявате както от класове, така и от характеристики. Наследявате членовете на един клас в друг клас, използвайки ключовата дума extendsТова позволява повторна употреба.
Възможно е да се наследява от един клас или от множество класове. Възможно е също така да се наследява от подкласове, които сами по себе си имат свои собствени суперкласове, създавайки йерархия на наследяване в процеса.
В примера на Scala по-долу, базовият клас е Circle, а производният клас е SphereОкръжността има стойност, наречена радиус, която се наследява от класа Sphere. Методът calcArea се презаписва с помощта на ключовата дума override.
Пример:
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 } }
Коремни мускулиtracАЦИ
В Scala можете да създавате коремни мускулиtract методи и полета на членове, използващи abstract класове и черти. Вътрешен коремtract класове и черти, можете да дефинирате абсtract полета, без да ги имплементирате.
Пример:
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" } }
Тези полета се реализират от класовете, които разширяват характеристиката или abs.tract клас. Можете да използвате черти, за да създадете contracts за това какво трябва да прави едно приложение и след това да имплементират тези методи по-късно.
trait DatabaseService { def addItemName(itemName:String) def removeItem(itemId:Int) def updateItem(itemId:Int, newItemName:String) }
По този начин можете да планирате как ще изглежда приложението, без да имплементирате методите, helpping Вие си представяте как ще се появят различните методи. Това следва модел, известен като програмиране на коремните мускули.tracциите, а не към самото изпълнение.
Клас, предшестван от abstract Ключовата дума може да съдържа и двете абс.tracт и не-абсtract методи. Множественото наследяване обаче не се поддържа в abstract класове, така че можете да разгънете само един коремtracт клас.
Единични обекти
Сингълтонът е клас, чиято инстанция се създава само веднъж в програмата. Той произлиза от популярен и полезен модел за програмиране, известен като „модел на сингълтон“. Той е полезен за създаване на инстанции, които са предназначени да бъдат дълготрайни и често достъпни в цялата програма, където състоянието е неразделна част от координирането на събитията в системата. Създаването на такъв клас в Scala е лесно, защото Scala предоставя прост начин за създаване на сингълтони, използвайки object ключова дума.
object UserProfile { var userName = "" var isLoggedIn:Boolean = false }
След това можете да се обърнете към този обект в цялата програма с гаранцията, че всички части на програмата виждат едни и същи данни, защото има само един негов екземпляр.
def getLoggedInStatus():Boolean = { return UserProfile.isLoggedIn } def changeLoggedInStatus():Boolean = { UserProfile.isLoggedIn = !UserProfile.isLoggedIn return UserProfile.isLoggedIn }
Концепцията за статични членове не съществува в Scala, поради което се използват singleton обекти, които действат като статични членове на клас.
Неявни класове
Имплицитните класове са функция, добавена във версия 2.10, и се използват предимно за добавяне на нова функционалност към съществуващи затворени класове.
- implicit Ключовата дума трябва да бъде дефинирана в клас, обект или характеристика. Основният конструктор на имплицитен клас трябва да има точно един аргумент в първия си списък с параметри. Той може също да включва допълнителен имплицитен списък с параметри.
В примера на Scala по-долу е добавена нова функционалност за заместване на гласни на низ с *.
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) }
Обектно-ориентирано програмиране (ООП) срещу функционално програмиране (ФП)
В обектно-ориентирано програмиране (OOP), програмите се конструират групово.ping данните и функциите, които работят с тези данни, в силно свързани единици. Обектите носят данните си в полета, а методите работят с тях. В този стил на програмиране, основните абс.tracцията са данните, защото създадените методи са предназначени да работят с данните.
Функционално програмиране, от друга страна, разделя данните и функциите, които работят с тях. Това позволява на разработчиците да третират функциите като абстрактен елемент.tracция и движеща сила при моделиране на програми.
Scala позволява функционално програмиране, като третира функциите като първокласни граждани, позволявайки им да бъдат предавани като стойности на други функции и също така да бъдат връщани като стойности. Комбинацията от тези две парадигми направи Scala чудесен избор за изграждане на сложен софтуер в индустрии като науката за данни.
Важни рамки на Scala
Ето някои важни рамки за Scala:
- Пусни видео е рамка за уеб приложения с отворен код, която използва MVC архитектураПуснат през 2007 г. и сега лицензиран под Apache, той се превърна в една от най-популярните рамки в GitHub до 2013 г. Компании като LinkedIn, Walmart, Samsung и Eero използват тази рамка.
- Асансьор е друга безплатна уеб рамка, написана на Scala, пусната през 2007 г. Foursquare използва рамката Lift. Това е високопроизводителна рамка, с която се изгражда бързо.
- Ака предоставя набор от инструменти за изграждане на високоефективни, разпределени и устойчиви приложения, управлявани от съобщения, върху JVM.
- Котки е библиотека, която предоставя коремни мускулиtracции за функционално програмиране.
- Spark е унифициран аналитичен енджин за обработка на мащабни данни, широко използван в работни процеси, свързани с големи данни и машинно обучение.
Поддръжка на едновременност
- Стойностите в Scala са непроменими по подразбиране, което го прави много адаптивен към едновременни среди.
- Scala има много функции, които го правят идеален за едновременни приложения.
- Futures и Promises улесняват асинхронната обработка на данни, като по този начин поддържат паралелизма.
- Akka е инструментариум, който използва модела за паралелизъм на актьорите. Актьорите действат, когато получават съобщения.
- Паралелност с използване на нишки от Java също се поддържа в Scala.
- Поточната обработка е друга чудесна функция, която позволява непрекъсната обработка на данни в реално време.
Scala има някои от най-добрите библиотеки за паралелност в Java екосистема:
- Роден Java конци.
- Влакна от библиотеки като Vertx.
- ZIO, библиотека, която има примитиви, които помагат за справяне с паралелизъм и асинхронни изчисления.
- Софтуерна транзакционна памет (STM) за транзакции.
- Future, който е вграден в езика Scala.
Java срещу Скала
Ето основните разлики между Java и Скала.
| Scala | Java |
|---|---|
| По-компактен и сбит. | Сравнително по-големи парчета код. |
| Проектиран и разработен едновременно като обектно-ориентиран и функционален. Поддържа голямо разнообразие от функции за функционално програмиране, като например паралелизъм и непроменимост. | Първоначално разработен като обектно-ориентиран език и започна да поддържа функции за функционално програмиране в по-нови версии. Той все още не е толкова силен, колкото Scala за функционално програмиране. |
| Използва актьорския модел за поддържане на паралелизъм. | Използва конвенционалния базиран на нишки модел за едновременност. |
| Поддържа рамки като Play и Lift. | Поддържа Spring, Grails и много други. |
| Поддържа лениво оценяване. | Не поддържа lazy evaluation ntively. |
| Няма статични членове. | Съдържа статични членове. |
| Поддържа претоварване на оператори. | Не поддържа претоварване на оператори. |
| Компилирането на изходния код е сравнително бавно. | Компилацията на изходния код е по-бърза от тази на Scala. |
| Чертите действат като Java 8 интерфейса. | Java 8 интерфейса се опитват да преодолеят разликата между класовете и интерфейсите. |
| Понякога е необходимо пренаписване при надграждане на версии. | Пренаписването обикновено не е необходимо между версиите. |
| Безопасността на типа осигурява силна надеждност на кода, но не и абсолютна гаранция за липса на грешки. | Силно статично електричествоping помага за намаляване на много дефекти по време на изпълнение. |
| Има някои ограничения за обратна съвместимост между основните версии. | Силна дългосрочна обратна съвместимост. |
| OperaПроцесорите се третират като извиквания на методи. | OperaМетодите са със специален синтаксис и не са извиквания на методи. |
| Поддържа множествено наследяване чрез използване на черти. | Не поддържа множествено наследяване чрез класове; вместо това използва интерфейси. |
| Code е написано в компактен вид. | Code е написано в по-подробна форма. |
| Scala не съдържа ключовата дума static. | Java съдържа ключовата дума static. |






















