Основы
Вы можете запустить Scala в браузере с помощью Scastie.
- Зайдите на Scastie.
- Вставьте println(«Hello, world!») в левую панель.
- Нажмите кнопку “Run”. Вывод отобразится в правой панели.
Это простой способ поэкспериментировать со Scala кодом без всяких настроек.
Большинство примеров кода в этой документации также интегрированы с Scastie, поэтому вы можете поэкспериментировать с ними, просто нажав кнопку Run.
Выражения
Выражения — это вычислимые утверждения.
Вы можете выводить результаты выражений, используя println .
println(1) // 1 println(1 + 1) // 2 println("Hello!") // Hello! println("Hello," + " world!") // Hello, world!
Значения
Результаты выражений можно присваивать именам с помощью ключевого слова val .
Названные результаты, такие как x в примере, называются значениями. Вызов значения не приводит к его повторному вычислению.
Значения не изменяемы и не могут быть переназначены.
Типы значений могут быть выведены автоматически, но можно и явно указать тип, как показано ниже:
Обратите внимание, что объявление типа Int происходит после идентификатора x , следующим за : .
Переменные
Переменные похожи на значения константы, за исключением того, что их можно присваивать заново. Вы можете объявить переменную с помощью ключевого слова var .
var x = 1 + 1 x = 3 // Компилируется потому что "x" объявлен с ключевым словом "var". println(x * x) // 9
Как и в случае со значениями, вы можете явно указать тип, если захотите:
Блоки
Вы можете комбинировать выражения, окружая их <> . Мы называем это блоком.
Результат последнего выражения в блоке будет результатом всего блока в целом.
println( val x = 1 + 1 x + 1 >) // 3
Функции
Функции — это выражения, которые принимают параметры.
Вы можете определить анонимную функцию (т.е. без имени), которая возвращает переданное число, прибавив к нему единицу:
Слева от => находится список параметров. Справа — выражение, связанное с параметрами.
Вы также можете назвать функции.
val addOne = (x: Int) => x + 1 println(addOne(1)) // 2
Функции могут принимать множество параметров.
val add = (x: Int, y: Int) => x + y println(add(1, 2)) // 3
Или вообще не принимать никаких параметров.
val getTheAnswer = () => 42 println(getTheAnswer()) // 42
Методы
Методы выглядят и ведут себя очень похоже на функции, но между ними есть несколько принципиальных различий.
Методы задаются ключевым словом def . За def следует имя, список параметров, возвращаемый тип и тело.
def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3
Обратите внимание, как объявлен возвращаемый тип сразу после списка параметров и двоеточия : Int .
Методы могут принимать несколько списков параметров.
def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1, 2)(3)) // 9
Или вообще ни одного списка параметров.
def name: String = System.getProperty("user.name") println("Hello, " + name + "!")
Есть некоторые отличия от функций, но пока что их можно рассматривать как нечто похожее.
Методы также могут иметь многострочные выражения.
def getSquareString(input: Double): String = val square = input * input square.toString > println(getSquareString(2.5)) // 6.25
def getSquareString(input: Double): String = val square = input * input square.toString println(getSquareString(2.5)) // 6.25
Последнее выражение в теле становится возвращаемым значением метода (у Scala есть ключевое слово return , но оно практически не используется).
Классы
Вы можете объявлять классы используя ключевое слово class , за которым следует его имя и параметры конструктора.
class Greeter(prefix: String, suffix: String) def greet(name: String): Unit = println(prefix + name + suffix) >
class Greeter(prefix: String, suffix: String): def greet(name: String): Unit = println(prefix + name + suffix)
Возвращаемый тип метода greet это Unit , используется тогда, когда не имеет смысла что-либо возвращать. Аналогично void в Java и C. Поскольку каждое выражение Scala должно иметь какое-то значение, то при отсутствии возвращающегося значения возвращается экземпляр типа Unit. Явным образом его можно задать как () , он не несет какой-либо информации.
Вы можете создать экземпляр класса, используя ключевое слово new .
val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer!
val greeter = Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer!
Позже мы рассмотрим классы подробнее.
Классы-образцы (Case Class)
В Scala есть специальный тип класса, который называется классом-образцом (case class). По умолчанию такие классы неизменны и сравниваются по значению из конструктора. Вы можете объявлять классы-образцы с помощью ключевых слов case class .
case class Point(x: Int, y: Int)
Можно создавать экземпляры класса-образца без использования ключевого слова new .
val point = Point(1, 2) val anotherPoint = Point(1, 2) val yetAnotherPoint = Point(2, 2)
Они сравниваются по значению.
if (point == anotherPoint) println(s"$point and $anotherPoint are the same.") > else println(s"$point and $anotherPoint are different.") > // Point(1,2) и Point(1,2) одни и те же. if (point == yetAnotherPoint) println(s"$point and $yetAnotherPoint are the same.") > else println(s"$point and $yetAnotherPoint are different.") > // Point(1,2) и Point(2,2) разные.
if point == anotherPoint then println(s"$point and $anotherPoint are the same.") else println(s"$point and $anotherPoint are different.") // Point(1,2) и Point(1,2) одни и те же. if point == yetAnotherPoint then println(s"$point and $yetAnotherPoint are the same.") else println(s"$point and $yetAnotherPoint are different.") // Point(1,2) и Point(2,2) разные.
Есть еще много деталей, которые мы бы хотели рассказать про классы-образцы; мы уверены, что вы влюбитесь в них! Обязательно рассмотрим их позже.
Объекты
Объекты задаются и существуют в единственном экземпляре. Вы можете думать о них как об одиночках (синглтонах) своего собственного класса.
Вы можете задать объекты при помощи ключевого слова object .
object IdFactory private var counter = 0 def create(): Int = counter += 1 counter > >
object IdFactory: private var counter = 0 def create(): Int = counter += 1 counter
Вы можете сразу получить доступ к объекту, ссылаясь на его имя.
val newId: Int = IdFactory.create() println(newId) // 1 val newerId: Int = IdFactory.create() println(newerId) // 2
Позже мы рассмотрим объекты подробнее.
Трейты
Трейты — как типы описывают характеристики классов, в нем могут объявляться определенные поля и методы. Трейты можно комбинировать.
Объявить трейт можно с помощью ключевого слова trait .
trait Greeter def greet(name: String): Unit >
trait Greeter: def greet(name: String): Unit
Трейты также могут иметь реализации методов и полей, которые предполагается использовать умолчанию.
trait Greeter def greet(name: String): Unit = println("Hello, " + name + "!") >
trait Greeter: def greet(name: String): Unit = println("Hello, " + name + "!")
Вы можете наследовать свойства трейтов, используя ключевое слово extends и переопределять реализацию с помощью ключевого слова override .
class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String, postfix: String) extends Greeter override def greet(name: String): Unit = println(prefix + name + postfix) > > val greeter = new DefaultGreeter() greeter.greet("Scala developer") // Hello, Scala developer! val customGreeter = new CustomizableGreeter("How are you, ", "?") customGreeter.greet("Scala developer") // How are you, Scala developer?
class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String, postfix: String) extends Greeter: override def greet(name: String): Unit = println(prefix + name + postfix) val greeter = DefaultGreeter() greeter.greet("Scala developer") // Hello, Scala developer! val customGreeter = CustomizableGreeter("How are you, ", "?") customGreeter.greet("Scala developer") // How are you, Scala developer?
Здесь DefaultGreeter наследуется только от одного трейта, но можно наследоваться от нескольких.
Позже мы рассмотрим трейты подробнее.
Главный метод
Главный метод является отправной точкой в программе. Для Виртуальной Машины Java требуется, чтобы главный метод назывался main и принимал один аргумент, массив строк.
Используя объект, можно задать главный метод следующим образом:
In Scala 2 you must define a main method manually. Using an object, you can define the main method as follows:
object Main def main(args: Array[String]): Unit = println("Hello, Scala developer!") >
In Scala 3, with the @main annotation, a main method is automatically generated from a method as follows:
@main def hello() = println("Hello, Scala developer!")