Несъмнено има известна истина в твърдението, че „Scala е трудна“, но кривата на обучение заслужава инвестицията. Някои от по-сложните характеристики на езика ( Кортежи , Функции , Макроси , да назовем само няколко) в крайна сметка улесняват разработчика да пише по-добър код и увеличаване на производителността чрез програмиране в Scala. Честно казано, ние сме програмисти и ако не сме достатъчно умни, за да научим език, който има известна сложност, значи сме в грешен бизнес.
Стълба е безопасен за типа JVM език, който включва обектно ориентирано и функционално програмиране в изключително кратък, логичен и изключително мощен език. Някои може да бъдат изненадани да разберат, че Scala не е толкова нова, колкото си мислеха, след като беше представена за първи път през 2003 г. Въпреки това, особено през последните няколко години, Scala започна да развива значителни последователи . Което поражда въпроса „Защо Scala?“.
Тази статия разглежда предимствата на Scala, особено спрямо Java (тъй като Scala е написана да работи в JVM). Scala не е единственият опит за създаване на „по-добра Java“. Алтернативи като Котлин и Цейлон също са тръгнали по този път, но те са взели основното решение да останат много близки по синтаксис до самия език Java, за да минимизират кривата на обучение. Това може да изглежда като чудесна идея, но в крайна сметка донякъде се самоунищожава, тъй като ви принуждава да останете в рамките на редица същите тези парадигми на Java, които са били причината да се създаде „по-добра Java“ на първо място.
За разлика от тях, Scala е създадена специално с цел да бъде по-добра език , отделяйки онези аспекти на Java, които счита за ограничаващи, прекалено досадни или разочароващи за разработчика. В резултат на това наистина има разграничения между кодовете и промени в парадигмата, които могат да направят малко по-трудно ранното изучаване на програмирането на Scala, но резултатът е много по-изчистен и добре организиран език, който в крайна сметка е по-лесен за използване и увеличава производителността.
Въпреки че простотата на езика Java е част от успеха му, по ирония на съдбата той също допринася за неговата сложност. Разбира се, можете да пишете почти всичко на Java, но редовете код, необходими за това, могат да бъдат плашещи. Програмирането в Scala, от друга страна, има малко по-сложна структура. Но ако можете да напишете малко по-сложен неженен ред от код, който замества 20 „по-прости“ реда на Java, кой от тях е наистина по-сложен?
Истината е, че Java често е твърде многословна. В Scala компилаторът е невероятно умен, така че това избягва разработчикът да има нужда да посочва изрично онези неща, които компилаторът може да направи. Сравнете например това просто „Hello World!“ програма в Java срещу Scala:
Hello World в Java:
public class HelloJava { public static void main(String[] args) { System.out.println('Hello World!'); } }
Hello World в Scala:
object HelloScala { def main(args: Array[String]): Unit = { println('Hello World!') } }
Въпреки че тук няма голяма разлика между двата езика, Scala е по-малко подробна дори в този прост пример.
За по-практичен пример, нека да разгледаме създаването на прост списък от низове:
Java:
List list = new ArrayList(); list.add('1'); list.add('2'); list.add('3');
Стълба:
val list = List('1', '2', '3')
Със сигурност в Java има някои трикове за малко съкращаване на кода, но не и при стандартна употреба.
Сега разгледайте случай, в който имаме списък с низове, които са числа, но ние искаме да преобразуваме този списък в списък с цели числа:
Java:
List ints = new ArrayList(); for (String s : list) { ints.add(Integer.parseInt(s)); }
Стълба:
val ints = list.map(s => s.toInt)
Благодарение на функционалните свойства на Scala, това преобразуване става изключително лесно.
Нека да направим нещата стъпка по-напред и да сравним стандартния боб / обикновен стар Java обект (POJO) създаване в Java и Scala.
Първо, версията на Java:
public class User { private String name; private List orders; public User() { orders = new ArrayList(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public List getOrders() { return orders; } public void setOrders(List orders) { this.orders = orders; } } public class Order { private int id; private List products; public Order() { products = new ArrayList(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public List getProducts() { return products; } public void setProducts(List products) { this.products = products; } } public class Product { private int id; private String category; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
Фу. Lotta код.
Сега версията на Scala:
class User { var name: String = _ var orders: List[Order] = Nil } class Order { var id: Int = _ var products: List[Product] = Nil } class Product { var id: Int = _ var category: String = _ }
Кой език казахме, че е по-сложен ?!
Ако сте стигнали дотук и сте програмист на Java, в този момент може би си мислите, че правя несправедливо сравнение на кода. В края на краищата нищо не ми пречи да правя публични променливи в Java и след това да се отърва от гетерите и настройвачите.
Ако обаче се върнете към разсъжденията зад гетерите и сетерите в Java, това е специално за бъдещи проверки. Тоест, ако по-късно трябва да добавите някаква логика към получаването или настройката на променливи, ще трябва да пренапишете тези публични променливи, за да използвате методи вместо това (поради което използването на гетъри и сетери за начало се насърчава в Java ). При програмирането на Scala обаче това не е така. Поради езиковия дизайн абстракцията остава непокътната, без да са необходими гетери и сетери. Да разгледаме например това модифицирано User
клас в Scala, който хвърля NullPointerException
ако се опитате да зададете името на null:
class User { private var _name: String = _ var orders: List[Order] = Nil def name = _name def name_=(name: String) = { if (name == null) { throw new NullPointerException('User.name cannot be null!') } _name = name }
И все още можете да зададете името така:
user.name = 'John Doe'
Имайте предвид, че това премахва изцяло необходимостта от предварително конфигуриране на методи за достъп.
Освен това, тъй като Scala предпочита неизменност, мога да напиша това в Scala още по-кратко с класове case:
case class User(name: String, orders: List[Order]) case class Order(id: Int, products: List[Product]) case class Product(id: Int, category: String)
Доста лудо колко по-малко код трябва да пиша.
Сега помислете за сценарий с горните класове, където искам да добавя елегантен малък метод в User
клас, който връща списък с всички Products
че User
е поръчал:
В многословния свят на Java:
public List getProducts() { List products = new ArrayList(); for (Order order : orders) { products.addAll(order.getProducts()); } return products; }
За щастие, java.util.List
има addAll
метод, или getProducts()
би било още по-дълго в Java.
В Scala, от друга страна, всичко, от което се нуждаем, е:
def products = orders.flatMap(o => o.products)
Можете да видите колко по-малка е реализацията на езика Scala. Да, може да изглежда по-сложно за начинаещия Scala, но след като всъщност разберете напълно концепциите зад него, кодът на Scala ще изглежда далеч по-опростен от Java кода.
Нека да станем дори малко по-сложни тук. Ами ако искаме да получим само Products
в рамките на определен Category
?
В този случай не сме в състояние да се възползваме от addAll
метод в java.util.List
, така че нещата стават по-грозни в Java :
public List getProductsByCategory(String category) { List products = new ArrayList(); for (Order order : orders) { for (Product product : order.getProducts()) { if (category.equals(product.getCategory())) { products.add(product); } } } return products; }
В Скала обаче кодът остава доста ясен. Ние просто използваме flatMap
да комбинирате продуктовите списъци от всеки Order
сплескани в един списък, тогава филтрираме, за да включим само тези, които съответстват на категорията:
def productsByCategory(category: String) = orders.flatMap(o => o.products).filter(p => p.category == category)
През последните няколко години със сигурност не липсваха нови езици, но докато почти всички останали, които наскоро се появиха, са динамични, Scala е статично типизирана.
Като професионален разработчик - макар да знам и използвам много динамични езици - моето мнение е, че проверките по време на компилация са изключително важни за писане на солиден код. На динамичен език никога не можете да сте сигурни, че вашият код е достатъчно без грешки и стабилен, докато действително не го стартирате в широк спектър от сценарии. Това може да доведе до потенциално сериозни дефекти в кода, които никога не се реализират, докато кодът не е в производство.
Надяваме се, че тази статия подрежда Java срещу Scala достатъчно, за да ви даде предварителна представа за силата и възможностите на Scala и да предизвика апетита ви за изучаване на езика. Това не само е чудесен език, който може да направи програмирането по-малко досадно и по-приятно, но и е използвани от някои от най-големите компании в света (LinkedIn, Twitter, FourSquare, The Guardian, за да назовем само няколко).
Популярността и използването на Scala бързо се увеличава, както се вижда от непрекъснато нарастващия брой отворени позиции за Разработчици на Scala . Ако още не сте го направили, сега би било подходящо време да започнете да яздите вълната и да спрете да питате „Защо да научим Скала?“
Scala е мощен език за програмиране на високо ниво, който включва обектно-ориентирано и функционално програмиране. Това е безопасен за типа език, който разчита на изпълнението на JVM.
Много неща, вариращи от машинно обучение до уеб приложения. Като език за общо предназначение на високо ниво, Scala може да се похвали с широка гама от възможни приложения. Scala позволява на разработчиците да използват добре стандартните функции на JVM и библиотеките на Java.
Ако обмисляте да се потопите в Scala, наличието на опит в Java очевидно ще ви помогне и няма да имате проблеми с намирането на учебни ресурси онлайн. Ако обаче нямате опит с Java, ще трябва да научите основите. Познаването с езиците за функционално програмиране също ще помогне.
Според съобщения в медиите и официални изявления Scala се използва от множество технологични компании, включително Netflix, Twitter, LinkedIn, AirBnB, AT&T, eBay и дори Apple. Използва се и във финансите, като Bloomberg и UBS.
През последните години Scala загуби част от своята привлекателност, което накара някои да стигнат до заключението, че е на път да излезе. Това е предмет на не малък дебат. Макар да е вярно, че някои известни компании са го изоставили, Scala все още е силна и запазва голям брой последователи.