Scala - Краткое руководство

Scala, сокращение от Scalable Language, представляет собой гибридный функциональный язык программирования. Его создал Мартин Одерски. Scala плавно интегрирует функции объектно-ориентированных и функциональных языков. Scala скомпилирована для работы на виртуальной машине Java. Многие существующие компании, которые используют Java для критически важных бизнес-приложений, обращаются к Scala, чтобы повысить продуктивность разработки, масштабируемость приложений и общую надежность.

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

Scala объектно-ориентированный

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

Классы расширены subclassing и гибкий mixin-based composition механизм как чистая замена множественному наследованию.

Scala функциональна

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

Scala предоставляет упрощенный синтаксис для определения anonymous functions, он поддерживает higher-order functions, он позволяет функциям быть nested, и поддерживает currying. Эти концепции будут объяснены в следующих главах.

Scala имеет статическую типизацию

Scala, в отличие от некоторых других языков со статической типизацией (C, Pascal, Rust и т. Д.), Не ожидает от вас предоставления избыточной информации о типах. В большинстве случаев вам не нужно указывать тип, и уж точно не нужно его повторять.

Scala работает на JVM

Scala компилируется в байт-код Java, который выполняется виртуальной машиной Java (JVM). Это означает, что Scala и Java имеют общую платформу времени выполнения. Вы можете легко перейти с Java на Scala.

Компилятор Scala компилирует ваш код Scala в байт-код Java, который затем может быть выполнен с помощью 'scalaкоманда. 'scala'команда похожа на java команда, поскольку она выполняет ваш скомпилированный код Scala.

Scala может выполнять код Java

Scala позволяет вам использовать все классы Java SDK, а также ваши собственные классы Java или ваши любимые проекты Java с открытым исходным кодом.

Scala может выполнять параллельную и синхронизирующую обработку

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

Scala против Java

Scala имеет набор функций, которые полностью отличаются от Java. Некоторые из них -

  • Все типы являются объектами
  • Вывод типа
  • Вложенные функции
  • Функции - это объекты
  • Поддержка доменного языка (DSL)
  • Traits
  • Closures
  • Поддержка параллелизма на основе Erlang

Веб-платформы Scala

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

  • Подъемная рама

  • Платформа Play

  • Фреймворк Bowler

Scala может быть установлен в любой системе на базе UNIX или Windows. Перед тем как начать установку Scala на свой компьютер, на вашем компьютере должна быть установлена ​​Java 1.8 или выше.

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

Шаг 1. Проверьте установку Java

Прежде всего, вам необходимо установить Java Software Development Kit (SDK) в вашей системе. Чтобы проверить это, выполните любую из следующих двух команд в зависимости от платформы, на которой вы работаете.

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

Платформа Команда Пример вывода
Windows

Откройте командную консоль и введите -

\>java –version

Версия Java "1.8.0_31"

Java (TM) SE Время выполнения

Среда (сборка 1.8.0_31-b31)

64-разрядный сервер Java Hotspot (TM)

ВМ (сборка 25.31-b07, смешанный режим)

Linux

Откройте командный терминал и введите -

$java –version

Версия Java "1.8.0_31"

Откройте среду выполнения JDK (rhel-2.8.10.4.el6_4-x86_64)

Откройте виртуальную машину 64-разрядного сервера JDK (сборка 25.31-b07, смешанный режим)

Мы предполагаем, что у читателей этого руководства в системе установлен Java SDK версии 1.8.0_31.

Если у вас нет Java SDK, загрузите его текущую версию с http://www.oracle.com/technetwork/java/javase/downloads/index.html и установите его.

Шаг 2. Настройте среду Java

Установите переменную среды JAVA_HOME, чтобы она указывала на расположение базового каталога, в котором установлена ​​Java на вашем компьютере. Например,

Старший Нет Платформа и описание
1

Windows

Установите JAVA_HOME в C: \ ProgramFiles \ java \ jdk1.7.0_60

2

Linux

Экспорт JAVA_HOME = / usr / local / java-current

Добавьте полный путь к расположению компилятора Java в системный путь.

Старший Нет Платформа и описание
1

Windows

Добавьте строку «C: \ Program Files \ Java \ jdk1.7.0_60 \ bin» в конец системной переменной PATH.

2

Linux

Экспорт PATH = $ PATH: $ JAVA_HOME / bin /

Выполнить команду java -version из командной строки, как описано выше.

Шаг 3: установите Scala

Вы можете скачать Scala из http://www.scala-lang.org/downloads. На момент написания этого руководства я загрузил scala-2.11.5-installer.jar. Убедитесь, что у вас есть права администратора, чтобы продолжить. Теперь выполните следующую команду в командной строке -

Платформа Команда и вывод Описание
Windows

\> java –jar scala-2.11.5-installer.jar \>

Эта команда отобразит мастер установки, который поможет вам установить Scala на ваш компьютер с Windows. Во время установки он запросит лицензионное соглашение, просто примите его, а в дальнейшем он спросит путь, по которому будет установлен Scala. Я выбрал заданный по умолчанию путь «C: \ Program Files \ Scala», вы можете выбрать подходящий путь по своему усмотрению.

Linux

Command -

$ java –jar scala-2.9.0.1-installer.jar

Output -

Добро пожаловать на установку Scala 2.9.0.1!

Домашняя страница находится по адресу - http://Scala-lang.org/

нажмите 1 для продолжения, 2 для выхода, 3 для повторного отображения

1 ................................................

[Начало распаковки]

[Пакет обработки: Установка программного пакета (1/1)]

[Распаковка завершена]

[Установка консоли завершена]

Во время установки он запросит лицензионное соглашение, чтобы принять его, введите 1 и запросит путь, по которому будет установлен Scala. Я ввел / usr / local / share, вы можете выбрать подходящий путь по своему усмотрению.

Наконец, откройте новую командную строку и введите Scala -versionи нажмите Enter. Вы должны увидеть следующее -

Платформа Команда Вывод
Windows

\> scala -версия

Средство выполнения кода Scala версии 2.11.5 - Copyright 2002-2013, LAMP / EPFL

Linux

$ scala -version

Средство выполнения кода Scala версии 2.9.0.1 - Авторское право 2002-2013, LAMP / EPFL

Если вы хорошо разбираетесь в Java, вам будет очень легко изучить Scala. Самая большая синтаксическая разница между Scala и Java заключается в том, что ';' символ конца строки не является обязательным.

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

  • Object- У объектов есть состояния и поведение. Объект - это экземпляр класса. Пример. У собаки есть состояния - цвет, имя, порода, а также поведение - виляние, лай и еда.

  • Class - Класс может быть определен как шаблон / план, который описывает поведение / состояния, связанные с классом.

  • Methods- Метод - это в основном поведение. Класс может содержать множество методов. Именно в методах записывается логика, обрабатываются данные и выполняются все действия.

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

  • Closure - А closure - функция, возвращаемое значение которой зависит от значения одной или нескольких переменных, объявленных вне этой функции.

  • Traits- Признак инкапсулирует определения методов и полей, которые затем можно повторно использовать, смешивая их в классы. Черты используются для определения типов объектов путем указания сигнатуры поддерживаемых методов.

Первая программа Scala

Мы можем выполнить программу Scala в двух режимах: один - interactive mode а другой script mode.

Интерактивный режим

Откройте командную строку и используйте следующую команду, чтобы открыть Scala.

\>scala

Если в вашей системе установлен Scala, будет отображаться следующий вывод:

Welcome to Scala version 2.9.0.1
Type in expressions to have them evaluated.
Type :help for more information.

Введите следующий текст справа от командной строки Scala и нажмите клавишу Enter -

scala> println("Hello, Scala!");

Это даст следующий результат -

Hello, Scala!

Режим сценария

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

пример

object HelloWorld {
   /* This is my first java program.  
   * This will print 'Hello World' as the output
   */
   def main(args: Array[String]) {
      println("Hello, world!") // prints Hello World
   }
}

Сохраните файл как - HelloWorld.scala.

Откройте окно командной строки и перейдите в каталог, в котором сохранен файл программы. 'scalac'используется для компиляции программы Scala и сгенерирует несколько файлов классов в текущем каталоге. Один из них будет называтьсяHelloWorld.class. Это байт-код, который будет работать на виртуальной машине Java (JVM) с использованием 'scalaкоманда.

Используйте следующую команду для компиляции и выполнения вашей программы Scala.

\> scalac HelloWorld.scala
\> scala HelloWorld

Вывод

Hello, World!

Базовый синтаксис

Ниже приведены основные синтаксисы и соглашения о кодировании в программировании на Scala.

  • Case Sensitivity - Scala чувствителен к регистру, что означает идентификатор Hello и hello будет иметь другое значение в Scala.

  • Class Names- Для всех названий классов первая буква должна быть в верхнем регистре. Если несколько слов используются для формирования имени класса, первая буква каждого внутреннего слова должна быть в верхнем регистре.

    Example - класс MyFirstScalaClass.

  • Method Names- Все имена методов должны начинаться с строчной буквы. Если для формирования имени метода используется несколько слов, то первая буква каждого внутреннего слова должна быть в верхнем регистре.

    Example - def myMethodName ()

  • Program File Name- Имя файла программы должно точно соответствовать имени объекта. При сохранении файла вы должны сохранить его, используя имя объекта (помните, что Scala чувствителен к регистру) и добавьте '.scala'до конца имени. (Если имя файла и имя объекта не совпадают, ваша программа не будет компилироваться).

    Example- Предположим, что «HelloWorld» - это имя объекта. Затем файл следует сохранить как HelloWorld.scala.

  • def main(args: Array[String]) - Обработка программы Scala начинается с метода main (), который является обязательной частью каждой программы Scala.

Идентификаторы Scala

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

Буквенно-цифровые идентификаторы

Буквенно-цифровой идентификатор начинается с буквы или символа подчеркивания, за которым могут следовать другие буквы, цифры или символы подчеркивания. Символ «$» является зарезервированным ключевым словом в Scala и не должен использоваться в идентификаторах.

Ниже приведены legal alphanumeric identifiers -

age, salary, _value,  __1_value

Ниже приведены illegal identifiers -

$salary, 123abc, -salary

Идентификаторы оператора

Идентификатор оператора состоит из одного или нескольких символов оператора. Символы оператора - это печатаемые символы ASCII, такие как +,:,?, ~ Или #.

Ниже приведены идентификаторы юридических операторов -

+ ++ ::: <?> :>

Компилятор Scala будет внутренне «искажать» идентификаторы операторов, чтобы превратить их в допустимые идентификаторы Java со встроенными символами $. Например, идентификатор: -> будет внутренне представлен как$colon$минус $ больше.

Смешанные идентификаторы

Смешанный идентификатор состоит из буквенно-цифрового идентификатора, за которым следует подчеркивание и идентификатор оператора.

Ниже приведены допустимые смешанные идентификаторы -

unary_+,  myvar_=

Здесь unary_ +, ​​используемый в качестве имени метода, определяет унарный оператор +, а myvar_ =, используемый в качестве имени метода, определяет оператор присваивания (перегрузка оператора).

Буквальные идентификаторы

Литеральный идентификатор - это произвольная строка, заключенная в обратные галочки (`...`).

Ниже приведены юридические буквальные идентификаторы -

`x` `<clinit>` `yield`

Ключевые слова Scala

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

Аннотация дело поймать класс
def делать еще расширяет
ложный окончательный Ну наконец то за
для некоторых если неявный импорт
ленивый соответствие новый Ноль
объект отменять пакет частный
защищенный возвращение запечатанный супер
это бросить черта Пытаться
правда тип вал Вар
в то время как с участием Уступать  
- : знак равно =>
<- <: <% >:
# @

Комментарии в Scala

Scala поддерживает однострочные и многострочные комментарии, очень похожие на Java. Многострочные комментарии могут быть вложенными, но они должны быть правильно вложены. Все символы, доступные внутри любого комментария, игнорируются компилятором Scala.

object HelloWorld {
   /* This is my first java program.  
    * This will print 'Hello World' as the output
    * This is an example of multi-line comments.
    */
   def main(args: Array[String]) {
      // Prints Hello World
      // This is also an example of single line comment.
      println("Hello, world!") 
   }
}

Пустые строки и пробелы

Строка, содержащая только пробелы, возможно с комментарием, называется пустой строкой, и Scala ее полностью игнорирует. Токены могут быть разделены пробелами и / или комментариями.

Символы новой строки

Scala - это строчно-ориентированный язык, в котором операторы могут оканчиваться точкой с запятой (;) или новой строкой. Точка с запятой в конце оператора обычно не обязательна. Вы можете ввести его, если хотите, но это не обязательно, если оператор появляется сам по себе в одной строке. С другой стороны, точка с запятой требуется, если вы пишете несколько операторов в одной строке. Ниже синтаксис используется несколько операторов.

val s = "hello"; println(s)

Пакеты Scala

Пакет - это именованный модуль кода. Например, служебный пакет Lift - это net.liftweb.util. Объявление пакета - это первая строка без комментариев в исходном файле:

package com.liftcode.stuff

Пакеты Scala можно импортировать, чтобы на них можно было ссылаться в текущей области компиляции. Следующий оператор импортирует содержимое пакета scala.xml -

import scala.xml._

Вы можете импортировать один класс и объект, например, HashMap из пакета scala.collection.mutable -

import scala.collection.mutable.HashMap

Вы можете импортировать более одного класса или объекта из одного пакета, например TreeMap и TreeSet из пакета scala.collection.immutable -

import scala.collection.immutable.{TreeMap, TreeSet}

Применить динамический

Маркерная черта, обеспечивающая динамические вызовы. Экземпляры x этого признака позволяют вызывать методы x.meth (args) для произвольных имен методов meth и списков аргументов args, а также обращаться к полю x.field для произвольных имен полей field. Эта функция представлена ​​в Scala-2.10.

Если вызов изначально не поддерживается x (например, если проверка типа не работает), он перезаписывается в соответствии со следующими правилами:

foo.method("blah") ~~> foo.applyDynamic("method")("blah")
foo.method(x = "blah") ~~> foo.applyDynamicNamed("method")(("x", "blah"))
foo.method(x = 1, 2) ~~> foo.applyDynamicNamed("method")(("x", 1), ("", 2))
foo.field ~~> foo.selectDynamic("field")
foo.varia = 10 ~~> foo.updateDynamic("varia")(10)
foo.arr(10) = 13 ~~> foo.selectDynamic("arr").update(10, 13)
foo.arr(10) ~~> foo.applyDynamic("arr")(10)

Scala имеет все те же типы данных, что и Java, с тем же объемом памяти и точностью. Ниже приведена таблица с подробностями обо всех типах данных, доступных в Scala.

Старший Нет Тип данных и описание
1

Byte

8-битное значение со знаком. Диапазон от -128 до 127

2

Short

16-битное значение со знаком. Диапазон от -32768 до 32767

3

Int

32-битное значение со знаком. Диапазон: от -2147483648 до 2147483647

4

Long

64-битное значение со знаком. От -9223372036854775808 до 9223372036854775807

5

Float

32-битное число с плавающей точкой одинарной точности IEEE 754

6

Double

64-битное число с плавающей запятой двойной точности IEEE 754

7

Char

16-битный беззнаковый символ Юникода. Диапазон от U + 0000 до U + FFFF

8

String

Последовательность символов

9

Boolean

Либо буквальная правда, либо буквальная ложь

10

Unit

Соответствует без значения

11

Null

пустая или пустая ссылка

12

Nothing

Подтип любого другого типа; не содержит значений

13

Any

Супертип любого типа; любой объект имеет тип Any

14

AnyRef

Супертип любого ссылочного типа

Все перечисленные выше типы данных являются объектами. Нет примитивных типов, как в Java. Это означает, что вы можете вызывать методы для Int, Long и т. Д.

Базовые литералы Scala

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

Интегральные литералы

Целочисленные литералы обычно имеют тип Int или тип Long, за которым следует суффикс L или l. Вот несколько целочисленных литералов -

0
035
21 
0xFFFFFFFF 
0777L

Литерал с плавающей запятой

Литералы с плавающей запятой имеют тип Float, если за ними следует суффикс типа с плавающей запятой F или f, и имеют тип Double в противном случае. Вот несколько литералов с плавающей запятой -

0.0 
1e30f 
3.14159f 
1.0e100
.1

Логические литералы

Булевы литералы true и false являются членами типа Boolean.

Символьные литералы

Символьный литерал 'x является сокращением выражения scala.Symbol("x"). Символ - это класс case, который определяется следующим образом.

package scala
final case class Symbol private (name: String) {
   override def toString: String = "'" + name
}

Символьные литералы

Символьный литерал - это одиночный символ, заключенный в кавычки. Этот символ является либо печатаемым символом Unicode, либо описывается управляющей последовательностью. Вот несколько символьных литералов -

'a' 
'\u0041'
'\n'
'\t'

Строковые литералы

Строковый литерал - это последовательность символов в двойных кавычках. Эти символы либо печатаемые символы Unicode, либо описываются управляющими последовательностями. Вот несколько строковых литералов -

"Hello,\nWorld!"
"This string contains a \" character."

Многострочные струны

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

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

"""the present string
spans three
lines."""

Нулевые значения

Нулевое значение имеет тип scala.Nullи, таким образом, совместим со всеми ссылочными типами. Он обозначает ссылочное значение, которое относится к специальному «нулевому» объекту.

Последовательности побега

Следующие escape-последовательности распознаются в символьных и строковых литералах.

Последовательности побега Unicode Описание
\ b \ u0008 backspace BS
\ т \ u0009 горизонтальная вкладка HT
\ п \ u000c formfeed FF
\ f \ u000c formfeed FF
\ u000d возврат каретки CR
\ " \ u0022 двойная кавычка "
\ ' \ u0027 одинарная кавычка.
\\ \ u005c обратная косая черта \

Символ с Unicode от 0 до 255 также может быть представлен восьмеричным escape-символом, т. Е. Обратной косой чертой '\', за которой следует последовательность до трех восьмеричных символов. Ниже приведен пример, показывающий несколько символов escape-последовательности.

пример

object Test {
   def main(args: Array[String]) {
      println("Hello\tWorld\n\n" );
   }
}

Когда приведенный выше код компилируется и выполняется, он дает следующий результат:

Вывод

Hello   World

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

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

Объявление переменной

Scala имеет другой синтаксис для объявления переменных. Они могут быть определены как значения, т. Е. Постоянные или переменные. Здесь myVar объявлен с использованием ключевого слова var. Это переменная, которая может изменять значение, и это называетсяmutable variable. Ниже приводится синтаксис для определения переменной с использованиемvar ключевое слово -

Синтаксис

var myVar : String = "Foo"

Здесь myVal объявлен с использованием ключевого слова val. Это означает, что это переменная, которую нельзя изменить, и это называетсяimmutable variable. Ниже приведен синтаксис для определения переменной с использованием ключевого слова val -

Синтаксис

val myVal : String = "Foo"

Типы переменных данных

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

Синтаксис

val or val VariableName : DataType = [Initial Value]

Если вы не присваиваете какое-либо начальное значение переменной, то оно действует следующим образом:

Синтаксис

var myVar :Int;
val myVal :String;

Вывод типа переменной

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

Синтаксис

var myVar = 10;
val myVal = "Hello, Scala!";

Здесь по умолчанию myVar будет иметь тип Int, а myVal станет переменной типа String.

Множественные задания

Scala поддерживает несколько назначений. Если блок кода или метод возвращает Tuple (Tuple- Содержит коллекцию объектов разных типов), кортеж может быть назначен переменной val. [Note - Мы изучим кортежи в следующих главах.]

Синтаксис

val (myVar1: Int, myVar2: String) = Pair(40, "Foo")

И вывод типа делает это правильно -

Синтаксис

val (myVar1, myVar2) = Pair(40, "Foo")

Пример программы

Ниже приведен пример программы, объясняющей процесс объявления переменных в Scala. Эта программа объявляет четыре переменные - две переменные определены с объявлением типа, а остальные две - без объявления типа.

пример

object Demo {
   def main(args: Array[String]) {
      var myVar :Int = 10;
      val myVal :String = "Hello Scala with datatype declaration.";
      var myVar1 = 20;
      val myVal1 = "Hello Scala new without datatype declaration.";
      
      println(myVar); println(myVal); println(myVar1); 
      println(myVal1);
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

10
Hello Scala with datatype declaration.
20
Hello Scala without datatype declaration.

Переменная область

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

Поля

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

Параметры метода

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

Локальные переменные

Локальные переменные - это переменные, объявленные внутри метода. Локальные переменные доступны только изнутри метода, но создаваемые вами объекты могут ускользнуть от метода, если вы вернете их из метода. Локальные переменные могут быть как изменяемыми, так и неизменяемыми типами и могут быть определены с использованием либоvar или же val.

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

Следующая диаграмма демонстрирует класс и объект на примере класса student, который содержит переменные-члены (имя и номер списка) и методы-члены (setName () и setRollNo ()). Наконец, все являются членами класса. Класс - это чертеж, а предметы здесь настоящие. На следующей диаграмме Студент - это класс, а Харини, Джон и Мария - это объекты класса Студент, у которых есть имя и номер списка.

Базовый класс

Ниже приводится простой синтаксис для определения базового класса в Scala. Этот класс определяет две переменныеx и y и метод: move, который не возвращает значения. Вызываются переменные класса, поля класса и методы называются методами класса.

Имя класса работает как конструктор класса, который может принимать ряд параметров. Приведенный выше код определяет два аргумента конструктора,xc и yc; они оба видны во всем теле класса.

Синтаксис

class Point(xc: Int, yc: Int) {
   var x: Int = xc
   var y: Int = yc

   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
      println ("Point x location : " + x);
      println ("Point y location : " + y);
   }
}

Как упоминалось ранее в этой главе, вы можете создавать объекты, используя ключевое слово new а затем вы можете получить доступ к полям и методам класса, как показано ниже в примере -

пример

import java.io._

class Point(val xc: Int, val yc: Int) {
   var x: Int = xc
   var y: Int = yc
   
   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
      println ("Point x location : " + x);
      println ("Point y location : " + y);
   }
}

object Demo {
   def main(args: Array[String]) {
      val pt = new Point(10, 20);

      // Move to a new location
      pt.move(10, 10);
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Point x location : 20
Point y location : 30

Расширение класса

Вы можете расширить базовый класс Scala и разработать унаследованный класс так же, как и в Java (используйте extends ключевое слово), но есть два ограничения: переопределение метода требует override ключевое слово, и только primaryконструктор может передавать параметры базовому конструктору. Давайте расширим наш вышеупомянутый класс и добавим еще один метод класса.

пример

Давайте возьмем пример двух классов Point class (в том же примере, что и выше) и Location класс наследуется с использованием ключевого слова extends. Такой 'extendsПредложение 'имеет два эффекта: оно заставляет класс Location наследовать все не закрытые члены от класса Point и делает тип Location подтипом класса Point типа . Итак, здесь класс Point называетсяsuperclassа класс Location называетсяsubclass. Расширение класса и наследование всех функций родительского класса называетсяinheritance но Scala допускает наследование только от одного класса.

Note - методы move () в классе Point и move() method in Location class не отменяют соответствующие определения move, поскольку они являются разными определениями (например, первые принимают два аргумента, а вторые - три аргумента).

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

import java.io._

class Point(val xc: Int, val yc: Int) {
   var x: Int = xc
   var y: Int = yc
   
   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
      println ("Point x location : " + x);
      println ("Point y location : " + y);
   }
}

class Location(override val xc: Int, override val yc: Int,
   val zc :Int) extends Point(xc, yc){
   var z: Int = zc

   def move(dx: Int, dy: Int, dz: Int) {
      x = x + dx
      y = y + dy
      z = z + dz
      println ("Point x location : " + x);
      println ("Point y location : " + y);
      println ("Point z location : " + z);
   }
}

object Demo {
   def main(args: Array[String]) {
      val loc = new Location(10, 20, 15);

      // Move to a new location
      loc.move(10, 10, 5);
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Point x location : 20
Point y location : 30
Point z location : 20

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

Неявные классы позволяют неявные диалоги с основным конструктором класса, когда класс находится в области видимости. Неявный класс - это класс, помеченный ключевым словом «неявный». Эта функция представлена ​​в Scala 2.10.

Syntax- Ниже приводится синтаксис неявных классов. Здесь неявный класс всегда находится в области объекта, где разрешены все определения методов, поскольку неявный класс не может быть классом верхнего уровня.

Синтаксис

object <object name> {
   implicit class <class name>(<Variable>: Data type) {
      def <method>(): Unit =
   }
}

пример

Давайте возьмем пример неявного класса с именем IntTimesс помощью метода times (). Это означает, что times () содержит транзакцию цикла, которая выполнит данный оператор указанное нами количество раз. Предположим, что данный оператор - «4 раза println (« Привет »)» означает, что оператор println («« Привет ») будет выполнен 4 раза.

Ниже приводится программа для данного примера. В этом примере используются два класса объектов (Run и Demo), поэтому мы должны сохранить эти два класса в разных файлах с соответствующими именами, как показано ниже.

Run.scala - Сохраните следующую программу в Run.scala.

object Run {
   implicit class IntTimes(x: Int) {
      def times [A](f: =>A): Unit = {
         def loop(current: Int): Unit =
         
         if(current > 0){
            f
            loop(current - 1)
         }
         loop(x)
      }
   }
}

Demo.scala - Сохраните следующую программу в Demo.scala.

import Run._

object Demo {
   def main(args: Array[String]) {
      4 times println("hello")
   }
}

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

Команда

\>scalac Run.scala
\>scalac Demo.scala
\>scala Demo

Вывод

Hello
Hello
Hello
Hello

Note -

  • Неявные классы должны быть определены внутри другого класса / объекта / признака (не на верхнем уровне).

  • Неявные классы могут принимать только один неявный аргумент в своем конструкторе.

  • Неявные классы не могут быть какими-либо методами, членами или объектами в области с тем же именем, что и неявный класс.

Одноэлементные объекты

Scala более объектно-ориентирована, чем Java, потому что в Scala у нас не может быть статических членов. Вместо этого в Scalasingleton objects. Синглтон - это класс, который может иметь только один экземпляр, то есть Object. Вы создаете синглтон, используя ключевое словоobjectвместо ключевого слова class. Поскольку вы не можете создать экземпляр одноэлементного объекта, вы не можете передавать параметры в основной конструктор. Вы уже видели все примеры с использованием одноэлементных объектов, в которых вы вызывали основной метод Scala.

Ниже приведен тот же пример программы для реализации синглтона.

пример

import java.io._

class Point(val xc: Int, val yc: Int) {
   var x: Int = xc
   var y: Int = yc
   
   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
   }
}

object Demo {
   def main(args: Array[String]) {
      val point = new Point(10, 20)
      printPoint

      def printPoint{
         println ("Point x location : " + point.x);
         println ("Point y location : " + point.y);
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Point x location : 10
Point y location : 20

В этой главе вы познакомитесь с модификаторами доступа Scala. Члены пакетов, классов или объектов могут быть помечены модификаторами доступа как private и protected, и если мы не используем ни одно из этих двух ключевых слов, то доступ будет считаться общедоступным. Эти модификаторы ограничивают доступ членов к определенным областям кода. Чтобы использовать модификатор доступа, вы включаете его ключевое слово в определение членов пакета, класса или объекта, как мы увидим в следующем разделе.

Частные члены

Частный член виден только внутри класса или объекта, содержащего определение члена.

Ниже приведен пример фрагмента кода для объяснения частного члена -

пример

class Outer {
   class Inner {
      private def f() { println("f") }
      
      class InnerMost {
         f() // OK
      }
   }
   (new Inner).f() // Error: f is not accessible
}

В Scala доступ (новый Inner). f () является незаконным, потому что f объявлен закрытым во Inner, и доступ осуществляется не из класса Inner. Напротив, первый доступ к f в классе Innermost нормален, потому что этот доступ содержится в теле класса Inner. Java разрешает оба доступа, поскольку позволяет внешнему классу получать доступ к частным членам своих внутренних классов.

Защищенные члены

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

Ниже приведен пример фрагмента кода для объяснения защищенного члена.

пример

package p {
   class Super {
      protected def f() { println("f") }
   }
   
   class Sub extends Super {
      f()
   }
   
   class Other {
      (new Super).f() // Error: f is not accessible
   }
}

Доступ к f в классе Sub в порядке, потому что f объявлен защищенным в классе «Super», а класс «Sub» является подклассом Super. Напротив, доступ к f в классе «Other» не разрешен, потому что класс «Other» не наследуется от класса «Super». В Java последний доступ по-прежнему будет разрешен, потому что класс «Другой» находится в том же пакете, что и класс «Подкатегория».

Публичные члены

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

Ниже приведен пример фрагмента кода для объяснения публичного члена -

пример

class Outer {
   class Inner {
      def f() { println("f") }
      
      class InnerMost {
         f() // OK
      }
   }
   (new Inner).f() // OK because now f() is public
}

Объем защиты

Модификаторы доступа в Scala могут быть дополнены квалификаторами. Модификатор формы private [X] или protected [X] означает, что доступ является частным или защищенным "до" X, где X обозначает некоторый включающий пакет, класс или одноэлементный объект.

Рассмотрим следующий пример -

пример

package society {
   package professional {
      class Executive {
         private[professional] var workDetails = null
         private[society] var friends = null
         private[this] var secrets = null

         def help(another : Executive) {
            println(another.workDetails)
            println(another.secrets) //ERROR
         }
      }
   }
}

Note - следующие пункты из приведенного выше примера -

  • Переменная workDetails будет доступна любому классу в прилагаемом пакете professional.

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

  • Секреты переменных будут доступны только для неявного объекта в методах экземпляра (this).

Оператор - это символ, который сообщает компилятору о необходимости выполнения определенных математических или логических операций. Scala богата встроенными операторами и предоставляет следующие типы операторов:

  • Арифметические операторы
  • Операторы отношения
  • Логические операторы
  • Побитовые операторы
  • Операторы присваивания

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

Арифметические операторы

Следующие арифметические операторы поддерживаются языком Scala. Например, предположим, что переменная A содержит 10, а переменная B содержит 20, тогда -

Показать примеры

Оператор Описание пример
+ Добавляет два операнда A + B даст 30
- Вычитает второй операнд из первого A - B даст -10
* Умножает оба операнда A * B даст 200
/ Делит числитель на де-числитель Б / А даст 2
% Оператор модуля находит остаток от деления одного числа на другое B% A даст 0

Операторы отношения

Следующие операторы отношения поддерживаются языком Scala. Например, предположим, что переменная A содержит 10, а переменная B содержит 20, тогда -

Показать примеры

Оператор Описание пример
== Проверяет, равны ли значения двух операндов или нет, если да, то условие становится истинным. (A == B) неверно.
знак равно Проверяет, равны ли значения двух операндов или нет, если значения не равны, условие становится истинным. (A! = B) верно.
> Проверяет, больше ли значение левого операнда, чем значение правого операнда, если да, то условие становится истинным. (A> B) неверно.
< Проверяет, меньше ли значение левого операнда, чем значение правого операнда, если да, то условие становится истинным. (A <B) верно.
> = Проверяет, больше ли значение левого операнда или равно значению правого операнда, если да, то условие становится истинным. (A> = B) неверно.
<= Проверяет, меньше ли значение левого операнда или равно значению правого операнда, если да, то условие становится истинным. (A <= B) верно.

Логические операторы

Следующие логические операторы поддерживаются языком Scala. Например, предположим, что переменная A содержит 1, а переменная B содержит 0, тогда -

Показать примеры

Оператор Описание пример
&& Это называется логическим оператором И. Если оба операнда не равны нулю, условие становится истинным. (A && B) ложно.
|| Он называется логическим оператором ИЛИ. Если любой из двух операндов не равен нулю, условие становится истинным. (A || B) верно.
! Он называется оператором логического НЕ. Используется для изменения логического состояния операнда на обратное. Если условие истинно, то оператор логического НЕ сделает ложным. ! (A && B) верно.

Побитовые операторы

Побитовый оператор работает с битами и выполняет побитовую операцию. Таблицы истинности для &, | и ^ следующие:

п q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

Допустим, если A = 60; и B = 13; теперь в двоичном формате они будут такими -

A = 0011 1100
B = 0000 1101
-----------------------
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A = 1100 0011

Побитовые операторы, поддерживаемые языком Scala, перечислены в следующей таблице. Предположим, что переменная A содержит 60, а переменная B содержит 13, тогда -

Показать примеры

Оператор Описание пример
& Двоичный оператор И копирует бит в результат, если он существует в обоих операндах. (A и B) даст 12, что составляет 0000 1100
| Оператор двоичного ИЛИ копирует бит, если он существует в любом из операндов. (A | B) даст 61, то есть 0011 1101
^ Двоичный оператор XOR копирует бит, если он установлен в одном операнде, но не в обоих. (A ^ B) даст 49, что составляет 0011 0001
~ Оператор дополнения двоичных единиц является унарным и имеет эффект «переворачивания» битов. (~ A) даст -61, что составляет 1100 0011 в форме дополнения до 2 из-за двоичного числа со знаком.
<< Оператор двоичного сдвига влево. Позиции битов значения левого операнда сдвигаются влево на количество битов, указанное правым операндом. << 2 даст 240, что составляет 1111 0000.
>> Оператор двоичного сдвига вправо. Позиции битов значения левого операнда перемещаются вправо на количество битов, заданное правым операндом. A >> 2 даст 15, что составляет 1111
>>> Сдвиг вправо оператор заполнения нуля. Значение левого операнда перемещается вправо на количество битов, указанное правым операндом, а сдвинутые значения заполняются нулями. A >>> 2 даст 15, что равно 0000 1111

Операторы присваивания

Язык Scala поддерживает следующие операторы присваивания:

Показать примеры

Оператор Описание пример
знак равно Простой оператор присваивания, присваивает значения из правых операндов левому операнду C = A + B присвоит значение A + B в C
+ = Добавить оператор присваивания И, он добавляет правый операнд к левому операнду и присваивает результат левому операнду C + = A эквивалентно C = C + A
знак равно Оператор вычитания И присваивания, он вычитает правый операнд из левого операнда и присваивает результат левому операнду C - = A эквивалентно C = C - A
знак равно Оператор умножения И присваивания, он умножает правый операнд на левый операнд и присваивает результат левому операнду C * = A эквивалентно C = C * A
знак равно Оператор деления И присваивания, он делит левый операнд на правый операнд и присваивает результат левому операнду C / = A эквивалентно C = C / A
знак равно Оператор модуля И присваивания, принимает модуль с использованием двух операндов и присваивает результат левому операнду C% = A эквивалентно C = C% A
<< = Левый сдвиг И оператор присваивания C << = 2 совпадает с C = C << 2
>> = Оператор сдвига вправо И присваивания C >> = 2 совпадает с C = C >> 2
знак равно Побитовый оператор присваивания И C & = 2 совпадает с C = C & 2
^ = побитовое исключающее ИЛИ и оператор присваивания C ^ = 2 совпадает с C = C ^ 2
| = побитовое включающее ИЛИ и оператор присваивания C | = 2 совпадает с C = C | 2

Приоритет операторов в Scala

Приоритет оператора определяет группировку терминов в выражении. Это влияет на то, как оценивается выражение. Некоторые операторы имеют более высокий приоритет, чем другие; например, оператор умножения имеет более высокий приоритет, чем оператор сложения -

Например, x = 7 + 3 * 2; здесь x присваивается 13, а не 20, потому что оператор * имеет более высокий приоритет, чем +, поэтому он сначала умножается на 3 * 2, а затем складывается в 7.

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

Категория Оператор Ассоциативность
Постфикс () [] Слева направо
Унарный ! ~ Справа налево
Мультипликативный * /% Слева направо
Добавка + - Слева направо
сдвиг >> >>> << Слева направо
Реляционный >> = <<= Слева направо
Равенство ==! = Слева направо
Побитовое И & Слева направо
Побитовое исключающее ИЛИ ^ Слева направо
Побитовое ИЛИ | Слева направо
Логическое И && Слева направо
Логическое ИЛИ || Слева направо
Назначение = + = - = * = / =% = >> = << = & = ^ = | = Справа налево
Запятая , Слева направо

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

Блок-схема

Ниже представлена ​​блок-схема условного оператора.

если заявление

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

Синтаксис

Синтаксис оператора if следующий.

if(Boolean_expression) {
   // Statements will execute if the Boolean expression is true
}

Если логическое выражение истинно, то будет выполнен блок кода внутри выражения if. Если нет, то будет выполнен первый набор кода после конца выражения if (после закрывающей фигурной скобки).

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

пример

object Demo {
   def main(args: Array[String]) {
      var x = 10;

      if( x < 20 ){
         println("This is if statement");
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

This is if statement

Заявление If-else

За оператором if может следовать необязательный оператор else , который выполняется, когда логическое выражение ложно.

Синтаксис

Синтаксис if ... else -

if(Boolean_expression){
   //Executes when the Boolean expression is true
} else{
   //Executes when the Boolean expression is false
}

Попробуйте использовать следующий пример программы, чтобы понять условные операторы (оператор if- else) на языке программирования Scala.

пример

object Demo {
   def main(args: Array[String]) {
      var x = 30;

      if( x < 20 ){
         println("This is if statement");
      } else {
         println("This is else statement");
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

This is else statement

Оператор If-else-if-else

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

При использовании операторов if, else if, else следует иметь в виду несколько моментов.

  • «Если» может иметь ноль или еще один, и оно должно стоять после любых других «если».

  • «Если» может иметь от нуля до многих «если», и они должны стоять перед else.

  • После того, как else if преуспевает, ни одно из оставшихся if или else не будет проверено.

Синтаксис

Ниже приведен синтаксис оператора if ... else if ... else:

if(Boolean_expression 1){
   //Executes when the Boolean expression 1 is true
} else if(Boolean_expression 2){
   //Executes when the Boolean expression 2 is true
} else if(Boolean_expression 3){
   //Executes when the Boolean expression 3 is true
} else {
   //Executes when the none of the above condition is true.
}

Попробуйте следующий пример программы, чтобы понять условные операторы (оператор if-else-if-else) на языке программирования Scala.

пример

object Demo {
   def main(args: Array[String]) {
      var x = 30;

      if( x == 10 ){
         println("Value of X is 10");
      } else if( x == 20 ){
         println("Value of X is 20");
      } else if( x == 30 ){
         println("Value of X is 30");
      } else{
         println("This is else statement");
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Value of X is 30

Вложенный оператор if-else

Гнездо всегда законно if-else операторы, что означает, что вы можете использовать один if или же else-if заявление внутри другого if или же else-if заявление.

Синтаксис

Синтаксис вложенного if-else следующий:

if(Boolean_expression 1){
   //Executes when the Boolean expression 1 is true
   
   if(Boolean_expression 2){
      //Executes when the Boolean expression 2 is true
   }
}

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

пример

object Demo {
   def main(args: Array[String]) {
      var x = 30;
      var y = 10;
      
      if( x == 30 ){
         if( y == 10 ){
            println("X = 30 and Y = 10");
         }
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

X = 30 and Y = 10

В этой главе вы познакомитесь со структурами управления циклами в языках программирования Scala.

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

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

Оператор цикла позволяет нам выполнять оператор или группу операторов несколько раз, и ниже приводится общая форма оператора цикла на большинстве языков программирования:

Блок-схема

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

Старший Нет Тип и описание петли
1

while loop

Повторяет утверждение или группу утверждений, пока выполняется заданное условие. Он проверяет условие перед выполнением тела цикла.

2

do-while loop

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

3

for loop

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

Заявления контроля цикла

Операторы управления циклом изменяют выполнение обычной последовательности. Когда выполнение покидает область действия, все автоматические объекты, созданные в этой области, уничтожаются. Таким образом, Scala не поддерживаетbreak или же continueкак это делает Java, но начиная с версии Scala 2.8, есть способ разорвать циклы. Щелкните следующие ссылки, чтобы проверить подробности.

Старший Нет Положение и описание управления
1

break statement

Прекращает loop оператор и передает выполнение оператору сразу после цикла.

Бесконечный цикл

Цикл становится бесконечным, если условие никогда не становится ложным. Если вы используете Scala,while цикл - лучший способ реализовать бесконечный цикл.

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

пример

object Demo {
   def main(args: Array[String]) {
      var a = 10;
      
      // An infinite loop.
      while( true ){
         println( "Value of a: " + a );
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Если вы выполните приведенный выше код, он войдет в бесконечный цикл, который вы можете завершить, нажав клавиши Ctrl + C.

Value of a: 10
Value of a: 10
Value of a: 10
Value of a: 10
…………….

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

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

Определение функции может появиться где угодно в исходном файле, и Scala допускает определения вложенных функций, то есть определения функций внутри других определений функций. Важно отметить, что имя функции Scala может содержать такие символы, как +, ++, ~, &, -, -, \, /,: и т. Д.

Объявления функций

Объявление функции Scala имеет следующую форму -

def functionName ([list of parameters]) : [return type]

Если вы не используете знак равенства и тело метода, методы неявно объявляются абстрактными .

Определения функций

Определение функции Scala имеет следующую форму -

Синтаксис

def functionName ([list of parameters]) : [return type] = {
   function body
   return [expr]
}

Вот, return type может быть любым допустимым типом данных Scala и list of parametersбудет список переменных, разделенных запятыми, а список параметров и тип возвращаемого значения необязательны. Очень похоже на Java,returnоператор может использоваться вместе с выражением, если функция возвращает значение. Ниже приведена функция, которая складывает два целых числа и возвращает их сумму.

Синтаксис

object add {
   def addInt( a:Int, b:Int ) : Int = {
      var sum:Int = 0
      sum = a + b
      return sum
   }
}

Функция, которая ничего не возвращает, может вернуть Unit что эквивалентно voidв Java и указывает, что функция ничего не возвращает. Функции, которые ничего не возвращают в Scala, называются процедурами.

Синтаксис

Вот синтаксис -

object Hello{
   def printMe( ) : Unit = {
      println("Hello, Scala!")
   }
}

Вызов функций

Scala предоставляет ряд синтаксических вариаций для вызова методов. Ниже приведен стандартный способ вызова метода -

functionName( list of parameters )

Если функция вызывается с использованием экземпляра объекта, мы должны использовать точечную нотацию, аналогичную Java, следующим образом:

[instance.]functionName( list of parameters )

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

пример

object Demo {
   def main(args: Array[String]) {
      println( "Returned Value : " + addInt(5,7) );
   }
   
   def addInt( a:Int, b:Int ) : Int = {
      var sum:Int = 0
      sum = a + b

      return sum
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Returned Value : 12

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

Функции вызова по имени Функции с именованными аргументами
Функция с переменными аргументами Рекурсионные функции
Значения параметров по умолчанию Функции высшего порядка
Вложенные функции Анонимные функции
Частично применяемые функции Функции каррирования

А closure - функция, возвращаемое значение которой зависит от значения одной или нескольких переменных, объявленных вне этой функции.

Следующий фрагмент кода с анонимной функцией.

val multiplier = (i:Int) => i * 10

Здесь единственная переменная, используемая в теле функции, i * 10, - это i, которая определена как параметр функции. Попробуйте следующий код -

val multiplier = (i:Int) => i * factor

В множителе есть две свободные переменные: i и factor. Один из них, i, является формальным параметром функции. Следовательно, он привязывается к новому значению при каждом вызове множителя. Тем не мение,factorэто не формальный параметр, тогда что это? Добавим еще одну строчку кода.

var factor = 3
val multiplier = (i:Int) => i * factor

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

Попробуйте следующий пример программы.

пример

object Demo {
   def main(args: Array[String]) {
      println( "multiplier(1) value = " +  multiplier(1) )
      println( "multiplier(2) value = " +  multiplier(2) )
   }
   var factor = 3
   val multiplier = (i:Int) => i * factor
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

multiplier(1) value = 3
multiplier(2) value = 6

В этой главе вы познакомитесь со строками Scala. В Scala, как и в Java, строка - это неизменяемый объект, то есть объект, который нельзя изменить. С другой стороны, объекты, которые можно изменять, например массивы, называются изменяемыми объектами. Строки - очень полезные объекты, в оставшейся части этого раздела мы представляем важные методыjava.lang.String класс.

Создание строки

Следующий код можно использовать для создания строки -

var greeting = "Hello world!";

or

var greeting:String = "Hello world!";

Каждый раз, когда компилятор встречает строковый литерал в коде, он создает объект String со своим значением, в данном случае «Hello world!». Ключевое слово String также может быть указано в альтернативном объявлении, как показано выше.

Попробуйте следующий пример программы.

пример

object Demo {
   val greeting: String = "Hello, world!"

   def main(args: Array[String]) {
      println( greeting )
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Hello, world!

Как упоминалось ранее, класс String неизменяем. Созданный объект String нельзя изменить. Если есть необходимость внести много изменений в строки символов, используйте класс String Builder, доступный в Scala !.

Длина строки

Методы, используемые для получения информации об объекте, известны как методы доступа. Одним из методов доступа, который можно использовать со строками, является метод length (), который возвращает количество символов, содержащихся в строковом объекте.

Используйте следующий сегмент кода, чтобы найти длину строки -

пример

object Demo {
   def main(args: Array[String]) {
      var palindrome = "Dot saw I was Tod";
      var len = palindrome.length();
      
      println( "String Length is : " + len );
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

String Length is : 17

Объединение строк

Класс String включает в себя метод объединения двух строк -

string1.concat(string2);

Это возвращает новую строку, которая является строкой1 с добавленной к ней строкой2 в конце. Вы также можете использовать метод concat () со строковыми литералами, например:

"My name is ".concat("Zara");

Строки чаще объединяются оператором +, например -

"Hello," + " world" + "!"

В результате -

"Hello, world!"

Следующие строки кода для определения длины строки.

пример

object Demo {
   def main(args: Array[String]) {
      var str1 = "Dot saw I was ";
      var str2 =  "Tod";
      
      println("Dot " + str1 + str2);
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Dot Dot saw I was Tod

Создание строк формата

У вас есть методы printf () и format () для печати вывода с форматированными числами. Класс String имеет эквивалентный метод класса format (), который возвращает объект String, а не объект PrintStream.

Попробуйте следующий пример программы, в которой используется метод printf () -

пример

object Demo {
   def main(args: Array[String]) {
      var floatVar = 12.456
      var intVar = 2000
      var stringVar = "Hello, Scala!"
      
      var fs = printf("The value of the float variable is " + "%f, while the value of the integer " + "variable is %d, and the string" + "is %s", floatVar, intVar, stringVar);
      
      println(fs)
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

команда

\>scalac Demo.scala
\>scala Demo

Вывод

The value of the float variable is 12.456000, 
while the value of the integer variable is 2000, 
and the string is Hello, Scala!()

Строчная интерполяция

Интерполяция строк - это новый способ создания строк в языке программирования Scala. Эта функция поддерживает версии Scala-2.10 и новее. Строковая интерполяция: механизм встраивания ссылок на переменные непосредственно в строковый литерал процесса.

В String Interpolation есть три типа (интерполяторы) реализаций.

Строковый интерполятор 's'

Литерал "s" позволяет использовать переменную непосредственно при обработке строки, когда вы добавляете к ней "s". Любая переменная String в области видимости, которую можно использовать в String. Ниже приведены различные варианты использования интерполятора String.

Следующий пример фрагмента кода для реализации интерполятора 's' в добавлении строковой переменной ($ name) к обычной строке (Hello) в инструкции println.

val name = “James”
println(s “Hello, $name”) //output: Hello, James

Средство интерполяции строк также может обрабатывать произвольные выражения. Следующий фрагмент кода для обработки строки (1 + 1) с произвольным выражением ($ {1 + 1}) с использованием интерполятора строки 's'. Любое произвольное выражение может быть встроено в '$ {}'.

println(s “1 + 1 = ${1 + 1}”) //output: 1 + 1 = 2

Попробуйте следующий пример программы реализации интерполятора 's'.

пример

object Demo {
   def main(args: Array[String]) {
      val name = "James"
      
      println(s"Hello, $name") println(s"1 + 1 = ${1 + 1}")
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Hello, James
1 + 1 = 2

Интерполятор 'f'

Литеральный интерполятор 'f' позволяет создать отформатированную строку, аналогичную printf в языке C. При использовании интерполятора 'f' все ссылки на переменные должны сопровождатьсяprintf спецификаторы формата стиля, такие как% d,% i,% f и т. д.

Давайте рассмотрим пример добавления значения с плавающей запятой (высота = 1.9d) и строковой переменной (name = «James») с обычной строкой. Следующий фрагмент кода реализации Интерполатора "f". Вот$name%s to print (String variable) James and $height% 2.2f для печати (значение с плавающей запятой) 1.90.

val height = 1.9d
val name = "James"
println(f"$name%s is $height%2.2f meters tall") //James is 1.90 meters tall

Это типобезопасный (т.е.) ссылка на переменную и следующий спецификатор формата должны совпадать, в противном случае отображается ошибка. Интерполятор 'f' использует утилиты формата String (спецификаторы формата), доступные в Java. По умолчанию означает, что после ссылки на переменную нет символа%. Он будет принят как% s (String).

"сырой" интерполятор

«Необработанный» интерполятор похож на интерполятор «s» за исключением того, что он не выполняет экранирование литералов внутри строки. Следующие ниже фрагменты кода в таблице будут отличаться использованием интерполяторов 's' и 'raw'. В выходных данных использования '\ n' в виде новой строки и в выходных данных 'сырого' использования '\ n' не будет действовать. Он напечатает всю строку с escape-буквами.

Использование интерполятора 's' использование "сырого" интерполятора

Program -

object Demo {
   def main(args: Array[String]) {
      println(s"Result = \n a \n b")
   }
}

Program -

object Demo {
   def main(args: Array[String]) {
      println(raw"Result = \n a \n b")
   }
}

Output -

Result =
a
b

Output -

Result = \n a \n b

Строковые методы

Ниже приводится список методов, определенных java.lang.String class и может использоваться непосредственно в ваших программах Scala -

Старший Нет Методы с описанием
1

char charAt(int index)

Возвращает символ по указанному индексу.

2

int compareTo(Object o)

Сравнивает эту строку с другим объектом.

3

int compareTo(String anotherString)

Лексикографически сравнивает две строки.

4

int compareToIgnoreCase(String str)

Сравнивает две строки лексикографически, игнорируя регистр символов.

5

String concat(String str)

Объединяет указанную строку в конец этой строки.

6

boolean contentEquals(StringBuffer sb)

Возвращает true тогда и только тогда, когда эта String представляет ту же последовательность символов, что и указанный StringBuffer.

7

static String copyValueOf(char[] data)

Возвращает строку, представляющую последовательность символов в указанном массиве.

8

static String copyValueOf(char[] data, int offset, int count)

Возвращает строку, представляющую последовательность символов в указанном массиве.

9

boolean endsWith(String suffix)

Проверяет, заканчивается ли эта строка указанным суффиксом.

10

boolean equals(Object anObject)

Сравнивает эту строку с указанным объектом.

11

boolean equalsIgnoreCase(String anotherString)

Сравнивает эту строку с другой строкой, игнорируя регистр.

12

byte getBytes()

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

13

byte[] getBytes(String charsetName)

Кодирует эту строку в последовательность байтов с использованием именованного набора символов, сохраняя результат в новом массиве байтов.

14

void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)

Копирует символы из этой строки в целевой массив символов.

15

int hashCode()

Возвращает хэш-код для этой строки.

16

int indexOf(int ch)

Возвращает индекс в этой строке первого вхождения указанного символа.

17

int indexOf(int ch, int fromIndex)

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

18

int indexOf(String str)

Возвращает индекс в этой строке первого вхождения указанной подстроки.

19

int indexOf(String str, int fromIndex)

Возвращает индекс в этой строке первого вхождения указанной подстроки, начиная с указанного индекса.

20

String intern()

Возвращает каноническое представление строкового объекта.

21 год

int lastIndexOf(int ch)

Возвращает индекс в этой строке последнего вхождения указанного символа.

22

int lastIndexOf(int ch, int fromIndex)

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

23

int lastIndexOf(String str)

Возвращает индекс в этой строке самого правого вхождения указанной подстроки.

24

int lastIndexOf(String str, int fromIndex)

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

25

int length()

Возвращает длину этой строки.

26

boolean matches(String regex)

Сообщает, соответствует ли эта строка заданному регулярному выражению.

27

boolean regionMatches(boolean ignoreCase, int toffset, String other, int offset, int len)

Проверяет, равны ли две строковые области.

28

boolean regionMatches(int toffset, String other, int offset, int len)

Проверяет, равны ли две строковые области.

29

String replace(char oldChar, char newChar)

Возвращает новую строку, полученную в результате замены всех вхождений oldChar в этой строке на newChar.

30

String replaceAll(String regex, String replacement

Заменяет каждую подстроку этой строки, которая соответствует заданному регулярному выражению с заданной заменой.

31 год

String replaceFirst(String regex, String replacement)

Заменяет первую подстроку этой строки, которая соответствует заданному регулярному выражению с заданной заменой.

32

String[] split(String regex)

Разбивает эту строку вокруг совпадений с заданным регулярным выражением.

33

String[] split(String regex, int limit)

Разбивает эту строку вокруг совпадений с заданным регулярным выражением.

34

boolean startsWith(String prefix)

Проверяет, начинается ли эта строка с указанного префикса.

35 год

boolean startsWith(String prefix, int toffset)

Проверяет, начинается ли эта строка с указанного префикса, начиная с указанного индекса.

36

CharSequence subSequence(int beginIndex, int endIndex)

Возвращает новую последовательность символов, которая является подпоследовательностью этой последовательности.

37

String substring(int beginIndex)

Возвращает новую строку, которая является подстрокой этой строки.

38

String substring(int beginIndex, int endIndex)

Возвращает новую строку, которая является подстрокой этой строки.

39

char[] toCharArray()

Преобразует эту строку в новый массив символов.

40

String toLowerCase()

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

41 год

String toLowerCase(Locale locale)

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

42

String toString()

Этот объект (который уже является строкой!) Возвращается сам.

43 год

String toUpperCase()

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

44

String toUpperCase(Locale locale)

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

45

String trim()

Возвращает копию строки без начальных и конечных пробелов.

46

static String valueOf(primitive data type x)

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

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

Вместо объявления отдельных переменных, таких как число0, число1, ... и число99, вы объявляете одну переменную массива, например числа, и используете числа [0], числа [1] и ..., числа [99] для представления отдельные переменные. В этом руководстве рассказывается, как объявлять переменные массива, создавать массивы и обрабатывать массивы с помощью индексированных переменных. Индекс первого элемента массива равен нулю, а индекс последнего элемента - это общее количество элементов минус один.

Объявление переменных массива

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

Ниже приводится синтаксис объявления переменной массива.

Синтаксис

var z:Array[String] = new Array[String](3)

or

var z = new Array[String](3)

Здесь z объявлен как массив строк, который может содержать до трех элементов. Значения могут быть присвоены отдельным элементам или получить доступ к отдельным элементам, это можно сделать с помощью таких команд, как следующие:

Команда

z(0) = "Zara"; z(1) = "Nuha"; z(4/2) = "Ayan"

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

var z = Array("Zara", "Nuha", "Ayan")

На следующем рисунке представлен массив myList. Вот,myList содержит десять двойных значений и индексы от 0 до 9.

Обработка массивов

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

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

пример

object Demo {
   def main(args: Array[String]) {
      var myList = Array(1.9, 2.9, 3.4, 3.5)
      
      // Print all the array elements
      for ( x <- myList ) {
         println( x )
      }

      // Summing all elements
      var total = 0.0;
      
      for ( i <- 0 to (myList.length - 1)) {
         total += myList(i);
      }
      println("Total is " + total);

      // Finding the largest element
      var max = myList(0);
      
      for ( i <- 1 to (myList.length - 1) ) {
         if (myList(i) > max) max = myList(i);
      }
      
      println("Max is " + max);
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

1.9
2.9
3.4
3.5
Total is 11.7
Max is 3.5

Scala не поддерживает напрямую различные операции с массивами и предоставляет различные методы для обработки массивов в любом измерении. Если вы хотите использовать разные методы, необходимо импортироватьArray._ пакет.

Многомерные массивы

Есть много ситуаций, когда вам нужно определять и использовать многомерные массивы (т. Е. Массивы, элементы которых являются массивами). Например, матрицы и таблицы являются примерами структур, которые могут быть реализованы в виде двумерных массивов.

Ниже приведен пример определения двумерного массива -

var myMatrix = ofDim[Int](3,3)

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

Попробуйте следующий пример программы для обработки многомерного массива -

пример

import Array._

object Demo {
   def main(args: Array[String]) {
      var myMatrix = ofDim[Int](3,3)
      
      // build a matrix
      for (i <- 0 to 2) {
         for ( j <- 0 to 2) {
            myMatrix(i)(j) = j;
         }
      }
      
      // Print two dimensional array
      for (i <- 0 to 2) {
         for ( j <- 0 to 2) {
            print(" " + myMatrix(i)(j));
         }
         println();
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

0 1 2
0 1 2
0 1 2

Объединить массивы

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

пример

import Array._

object Demo {
   def main(args: Array[String]) {
      var myList1 = Array(1.9, 2.9, 3.4, 3.5)
      var myList2 = Array(8.9, 7.9, 0.4, 1.5)

      var myList3 =  concat( myList1, myList2)
      
      // Print all the array elements
      for ( x <- myList3 ) {
         println( x )
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

1.9
2.9
3.4
3.5
8.9
7.9
0.4
1.5

Создать массив с диапазоном

Использование метода range () для создания массива, содержащего последовательность возрастающих целых чисел в заданном диапазоне. Вы можете использовать последний аргумент как шаг для создания последовательности; если вы не используете последний аргумент, тогда step будет принят как 1.

Давайте рассмотрим пример создания массива диапазона (10, 20, 2): это означает создание массива с элементами между 10 и 20 и разницей диапазона 2. Элементы в массиве - 10, 12, 14, 16 и 18. .

Другой пример: диапазон (10, 20). Здесь разница в диапазоне не указана, поэтому по умолчанию предполагается 1 элемент. Он создает массив с элементами от 10 до 20 с разницей диапазона 1. Элементы в массиве - 10, 11, 12, 13,… и 19.

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

пример

import Array._

object Demo {
   def main(args: Array[String]) {
      var myList1 = range(10, 20, 2)
      var myList2 = range(10,20)

      // Print all the array elements
      for ( x <- myList1 ) {
         print( " " + x )
      }
      
      println()
      for ( x <- myList2 ) {
         print( " " + x )
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

10 12 14 16 18
10 11 12 13 14 15 16 17 18 19

Методы массива Scala

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

Старший Нет Методы с описанием
1

def apply( x: T, xs: T* ): Array[T]

Создает массив объектов T, где T может быть Unit, Double, Float, Long, Int, Char, Short, Byte, Boolean.

2

def concat[T]( xss: Array[T]* ): Array[T]

Объединяет все массивы в один массив.

3

def copy( src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int ): Unit

Скопируйте один массив в другой. Эквивалентно Java System.arraycopy (src, srcPos, dest, destPos, length).

4

def empty[T]: Array[T]

Возвращает массив длиной 0

5

def iterate[T]( start: T, len: Int )( f: (T) => T ): Array[T]

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

6

def fill[T]( n: Int )(elem: => T): Array[T]

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

7

def fill[T]( n1: Int, n2: Int )( elem: => T ): Array[Array[T]]

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

8

def iterate[T]( start: T, len: Int)( f: (T) => T ): Array[T]

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

9

def ofDim[T]( n1: Int ): Array[T]

Создает массив с заданными размерами.

10

def ofDim[T]( n1: Int, n2: Int ): Array[Array[T]]

Создает двумерный массив

11

def ofDim[T]( n1: Int, n2: Int, n3: Int ): Array[Array[Array[T]]]

Создает 3-мерный массив

12

def range( start: Int, end: Int, step: Int ): Array[Int]

Возвращает массив, содержащий одинаковые значения в некотором целочисленном интервале.

13

def range( start: Int, end: Int ): Array[Int]

Возвращает массив, содержащий последовательность возрастающих целых чисел в диапазоне.

14

def tabulate[T]( n: Int )(f: (Int)=> T): Array[T]

Возвращает массив, содержащий значения заданной функции в диапазоне целочисленных значений, начиная с 0.

15

def tabulate[T]( n1: Int, n2: Int )( f: (Int, Int ) => T): Array[Array[T]]

Возвращает двумерный массив, содержащий значения заданной функции в диапазонах целочисленных значений, начиная с 0.

Scala имеет богатый набор библиотек коллекций. Коллекции - это вместилища вещей. Эти контейнеры могут быть упорядоченными, линейными наборами элементов, такими как List, Tuple, Option, Map и т. Д. Коллекции могут иметь произвольное количество элементов или быть ограниченными до нуля или одного элемента (например, Option).

Коллекции могут быть strict или же lazy. В ленивых коллекциях есть элементы, которые могут не потреблять память до тех пор, пока к ним не поступит доступ, напримерRanges. Дополнительно коллекции могут бытьmutable (содержание ссылки может измениться) или immutable(то, на что ссылается ссылка, никогда не изменяется). Обратите внимание, что неизменяемые коллекции могут содержать изменяемые элементы.

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

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

Старший Нет Коллекции с описанием
1

Scala Lists

Список Scala [T] - это связанный список типа T.

2

Scala Sets

Набор - это совокупность попарно различных элементов одного типа.

3

Scala Maps

Карта - это набор пар ключ / значение. Любое значение может быть получено на основе его ключа.

4

Scala Tuples

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

5

Scala Options

Опция [T] предоставляет контейнер для нуля или одного элемента данного типа.

6

Scala Iterators

Итератор - это не коллекция, а способ доступа к элементам коллекции один за другим.

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

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

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

Синтаксис

trait Equal {
   def isEqual(x: Any): Boolean
   def isNotEqual(x: Any): Boolean = !isEqual(x)
}

Эта черта состоит из двух методов isEqual и isNotEqual. Здесь мы не приводим никакой реализации для isEqual, поскольку другой метод имеет свою реализацию. Дочерние классы, расширяющие признак, могут предоставить реализацию для нереализованных методов. Так что черта очень похожа на то, что у нас естьabstract classes в Java.

Допустим, пример признака Equal содержат два метода isEqual() и isNotEqual(). ЧертаEqual содержат один реализованный метод, который isEqual() поэтому, когда пользовательский класс Point расширяет черту Equal, внедрение в isEqual() метод в Point класс должен быть предоставлен.

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

  • obj.isInstanceOf [Point] Чтобы проверить Тип объекта и точки, они не совпадают.

  • obj.asInstanceOf [Point] означает точное приведение типа объекта obj и возвращает тот же объект, что и тип Point.

Попробуйте использовать следующий пример программы, чтобы реализовать черты.

пример

trait Equal {
   def isEqual(x: Any): Boolean
   def isNotEqual(x: Any): Boolean = !isEqual(x)
}

class Point(xc: Int, yc: Int) extends Equal {
   var x: Int = xc
   var y: Int = yc
   
   def isEqual(obj: Any) = obj.isInstanceOf[Point] && obj.asInstanceOf[Point].x == y
}

object Demo {
   def main(args: Array[String]) {
      val p1 = new Point(2, 3)
      val p2 = new Point(2, 4)
      val p3 = new Point(3, 3)

      println(p1.isNotEqual(p2))
      println(p1.isNotEqual(p3))
      println(p1.isNotEqual(2))
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

true
false
true

Классы ценностей и универсальные черты

Классы значений - это новый механизм в Scala, позволяющий избежать выделения объектов времени выполнения. Он содержит основной конструктор ровно с однимvalпараметр. Он содержит только методы (def), которые не разрешены var, val, вложенные классы, характеристики или объекты. Класс значения не может быть расширен другим классом. Это можно сделать, расширив ваш класс значений с помощью AnyVal. Типовая безопасность пользовательских типов данных без дополнительных затрат времени выполнения.

Давайте возьмем примеры классов значений Weight, Height, Email, Age и т.д. Для всех этих примеров не требуется выделять память в приложении.

Класс значений, которому не разрешено расширять черты. Чтобы разрешить классам значений расширять черты,universal traits вводятся, что распространяется на Any.

пример

trait Printable extends Any {
   def print(): Unit = println(this)
}
class Wrapper(val underlying: Int) extends AnyVal with Printable

object Demo {
   def main(args: Array[String]) {
      val w = new Wrapper(3)
      w.print() // actually requires instantiating a Wrapper instance
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Это даст вам хэш-код класса Wrapper.

Wrapper@13

Когда использовать черты характера?

Не существует твердого правила, но вот несколько рекомендаций, которые следует учитывать:

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

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

  • Если ты хочешь inherit из него в коде Java используйте абстрактный класс.

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

  • Если эффективность очень важна, склоняйтесь к использованию класса.

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

Соответствие шаблону включает последовательность альтернатив, каждая из которых начинается с ключевого слова. case. Каждая альтернатива включаетpattern и один или несколько expressions, который будет оцениваться, если шаблон соответствует. Символ стрелки => отделяет образец от выражений.

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

пример

object Demo {
   def main(args: Array[String]) {
      println(matchTest(3))
   }
   
   def matchTest(x: Int): String = x match {
      case 1 => "one"
      case 2 => "two"
      case _ => "many"
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

many

Блок с операторами case определяет функцию, которая отображает целые числа в строки. Ключевое слово match обеспечивает удобный способ применения функции (например, функции сопоставления с образцом выше) к объекту.

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

пример

object Demo {
   def main(args: Array[String]) {
      println(matchTest("two"))
      println(matchTest("test"))
      println(matchTest(1))
   }
   
   def matchTest(x: Any): Any = x match {
      case 1 => "one"
      case "two" => 2
      case y: Int => "scala.Int"
      case _ => "many"
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

2
many
one

Сопоставление с использованием классов регистра

В case classes- это специальные классы, которые используются при сопоставлении с образцом с помощью case-выражений. Синтаксически это стандартные классы со специальным модификатором:case.

Попробуйте следующее, это простой пример сопоставления с образцом с использованием класса case.

пример

object Demo {
   def main(args: Array[String]) {
      val alice = new Person("Alice", 25)
      val bob = new Person("Bob", 32)
      val charlie = new Person("Charlie", 32)
   
      for (person <- List(alice, bob, charlie)) {
         person match {
            case Person("Alice", 25) => println("Hi Alice!")
            case Person("Bob", 32) => println("Hi Bob!")
            case Person(name, age) => println(
               "Age: " + age + " year, name: " + name + "?")
         }
      }
   }
   case class Person(name: String, age: Int)
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Hi Alice!
Hi Bob!
Age: 32 year, name: Charlie?

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

Во-первых, компилятор автоматически преобразует аргументы конструктора в неизменяемые поля (vals). Ключевое слово val необязательно. Если вам нужны изменяемые поля, используйте ключевое слово var. Итак, наши списки аргументов конструктора стали короче.

Во-вторых, компилятор автоматически реализует equals, hashCode, и toStringметоды класса, которые используют поля, указанные в качестве аргументов конструктора. Итак, нам больше не нужны собственные методы toString ().

Наконец, также, тело Person class становится пустым, потому что нам не нужно определять никаких методов!

В этой главе объясняется, как Scala поддерживает регулярные выражения через Regex класс, доступный в пакете scala.util.matching.

Попробуйте следующий пример программы, в которой мы попытаемся найти слово Scala из заявления.

пример

import scala.util.matching.Regex

object Demo {
   def main(args: Array[String]) {
      val pattern = "Scala".r
      val str = "Scala is Scalable and cool"
      
      println(pattern findFirstIn str)
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Some(Scala)

Мы создаем String и вызываем r( )метод на нем. Scala неявно преобразует String в RichString и вызывает этот метод для получения экземпляра Regex. Чтобы найти первое совпадение регулярного выражения, просто вызовитеfindFirstIn()метод. Если вместо поиска только первого вхождения мы хотели бы найти все вхождения совпадающего слова, мы можем использоватьfindAllIn( ) , и в случае, если в целевой строке доступно несколько слов Scala, он вернет коллекцию всех совпадающих слов.

Вы можете использовать метод mkString () для конкатенации результирующего списка, и вы можете использовать вертикальную черту (|) для поиска маленького и заглавного варианта Scala, и вы можете использовать Regex конструктор вместо или r() метод создания выкройки.

Попробуйте следующий пример программы.

пример

import scala.util.matching.Regex

object Demo {
   def main(args: Array[String]) {
      val pattern = new Regex("(S|s)cala")
      val str = "Scala is scalable and cool"
      
      println((pattern findAllIn str).mkString(","))
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Scala,scala

Если вы хотите заменить совпадающий текст, мы можем использовать replaceFirstIn( ) заменить первое совпадение или replaceAllIn( ) заменить все вхождения.

пример

object Demo {
   def main(args: Array[String]) {
      val pattern = "(S|s)cala".r
      val str = "Scala is scalable and cool"
      
      println(pattern replaceFirstIn(str, "Java"))
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Java is scalable and cool

Формирование регулярных выражений

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

Ниже приводится таблица, в которой перечислены все синтаксисы метасимволов регулярных выражений, доступные в Java.

Подвыражение Матчи
^ Соответствует началу строки.
$ Соответствует концу строки.
. Соответствует любому одиночному символу, кроме новой строки. Использование опции m также позволяет сопоставить новую строку.
[...] Соответствует любому одиночному символу в скобках.
[^ ...] Соответствует любому одиночному символу не в скобках
\\ А Начало всей строки
\\ z Конец всей строки
\\ Z Конец всей строки, кроме допустимого символа конца строки.
re * Соответствует 0 или более вхождениям предыдущего выражения.
re + Соответствует 1 или более из предыдущего
ре? Соответствует 0 или 1 вхождению предыдущего выражения.
re {n} Соответствует ровно n повторениям предыдущего выражения.
re {n,} Соответствует n или нескольким вхождениям предыдущего выражения.
re {n, m} Соответствует как минимум n и максимум m вхождениям предыдущего выражения.
а | б Соответствует либо a, либо b.
(повторно) Группирует регулярные выражения и запоминает совпадающий текст.
(?: ре) Группирует регулярные выражения без запоминания совпадающего текста.
(?> ре) Соответствует независимому шаблону без возврата.
\\ w Соответствует символам слова.
\\ W Соответствует несловесным символам.
\\ с Соответствует пробелу. Эквивалентно [\ t \ n \ r \ f].
\\ S Соответствует пробелам.
\\ d Соответствует цифрам. Эквивалентно [0-9].
\\ D Соответствует нецифровым значениям.
\\ А Соответствует началу строки.
\\ Z Соответствует концу строки. Если новая строка существует, она соответствует непосредственно перед новой строкой.
\\ z Соответствует концу строки.
\\Г Место, где закончился последний матч.
\\ п Обратная ссылка на группу захвата номер "n"
\\ б Соответствует границам слова вне скобок. Соответствует пробелу (0x08) внутри скобок.
\\ B Соответствует границам без слов.
\\ n, \\ t и т. д. Соответствует символам новой строки, возврата каретки, табуляции и т. Д.
\\ Q Escape (кавычка) все символы до \\ E
\\ E Заканчивает котирование, начатое с \\ Q

Примеры регулярных выражений

пример Описание
. Соответствует любому символу, кроме новой строки
[Rr] уби Матч «Рубин» или «Рубин»
руб [ye] Матч «рубин» или «рубин»
[aeiou] Соответствует любой гласной в нижнем регистре
[0-9] Соответствует любой цифре; то же, что и [0123456789]
[аз] Соответствует любой строчной букве ASCII
[AZ] Соответствует любой заглавной букве ASCII
[a-zA-Z0-9] Соответствует любому из вышеперечисленных
[^ aeiou] Сопоставьте все, кроме гласной строчной буквы
[^ 0-9] Сопоставьте все, кроме цифры
\\ d Соответствует цифре: [0-9]
\\ D Соответствует нецифровой: [^ 0-9]
\\ с Соответствует пробелу: [\ t \ r \ n \ f]
\\ S Сопоставить без пробелов: [^ \ t \ r \ n \ f]
\\ w Соответствует символу из одного слова: [A-Za-z0-9_]
\\ W Соответствует символу, не являющемуся словом: [^ A-Za-z0-9_]
Рубин? Сопоставьте "rub" или "ruby": y необязательно
Рубин* Матч "руб" плюс 0 или более лет
рубин + Матч "руб" плюс 1 или более лет
\\ d {3} Соответствует ровно 3 цифрам
\\ d {3,} Соответствие 3 или более цифрам
\\ d {3,5} Соответствие 3, 4 или 5 цифрам
\\ D \\ d + Нет группы: + повторяет \\ d
(\\ D \\ d) + / Сгруппировано: + повторяет пару \\ D \ d
([Rr] uby (,)?) + Матч «Рубин», «Рубин, рубин, рубин» и др.

Note- что каждая обратная косая черта появляется дважды в строке выше. Это связано с тем, что в Java и Scala одиночная обратная косая черта является escape-символом в строковом литерале, а не обычным символом, который появляется в строке. Поэтому вместо '\' вам нужно написать '\\', чтобы получить одну обратную косую черту в строке.

Попробуйте следующий пример программы.

пример

import scala.util.matching.Regex

object Demo {
   def main(args: Array[String]) {
      val pattern = new Regex("abl[ae]\\d+")
      val str = "ablaw is able1 and cool"
      
      println((pattern findAllIn str).mkString(","))
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

able1

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

Когда вы хотите обрабатывать исключения, вы используете блок try {...} catch {...}, как и в Java, за исключением того, что блок catch использует сопоставление для идентификации и обработки исключений.

Выбрасывание исключений

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

throw new IllegalArgumentException

Выявление исключений

Scala позволяет try/catch любое исключение в одном блоке, а затем выполнить сопоставление с ним с шаблоном, используя caseблоки. Попробуйте следующий пример программы для обработки исключения.

пример

import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException

object Demo {
   def main(args: Array[String]) {
      try {
         val f = new FileReader("input.txt")
      } catch {
         case ex: FileNotFoundException =>{
            println("Missing file exception")
         }
         
         case ex: IOException => {
            println("IO Exception")
         }
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Missing file exception

Поведение этого try-catchвыражение такое же, как и в других языках, за исключением. Тело выполняется, и если оно вызывает исключение, каждыйcatch пункт рассматривается по очереди.

Окончательная статья

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

пример

import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException

object Demo {
   def main(args: Array[String]) {
      try {
         val f = new FileReader("input.txt")
      } catch {
         case ex: FileNotFoundException => {
            println("Missing file exception")
         }
         
         case ex: IOException => {
            println("IO Exception")
         }
      } finally {
         println("Exiting finally...")
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Missing file exception
Exiting finally...

Экстрактор в Scala - это объект, у которого есть метод, называемый unapplyкак один из ее членов. Цель этого неприменимого метода - сопоставить значение и разобрать его. Часто объект экстрактора также определяет двойной методapply для построения ценностей, но это не обязательно.

пример

Давайте возьмем пример объекта, который определяет как apply и unapplyметоды. Метод apply имеет то же значение, что и всегда: он превращает Test в объект, который может применяться к аргументам в круглых скобках так же, как применяется метод. Таким образом, вы можете написать Test («Zara», «gmail.com»), чтобы построить строку «[email protected]».

В unapply метод превращает тестовый класс в extractor и он меняет процесс строительства apply. Если apply принимает две строки и формирует из них строку адреса электронной почты, unapply принимает адрес электронной почты и потенциально возвращает две строки:user и domain адреса.

В unapplyтакже должен обрабатывать случай, когда данная строка не является адресом электронной почты. Вот почему unapply возвращает тип Option для пар строк. Его результат либоSome (user, domain)если строка str является адресом электронной почты с указанными частями пользователя и домена, или None, если str не является адресом электронной почты. Вот несколько примеров.

Синтаксис

unapply("[email protected]") equals Some("Zara", "gmail.com")
unapply("Zara Ali") equals None

В следующем примере программы показан объект экстрактора для адресов электронной почты.

пример

object Demo {
   def main(args: Array[String]) {
      println ("Apply method : " + apply("Zara", "gmail.com"));
      println ("Unapply method : " + unapply("[email protected]"));
      println ("Unapply method : " + unapply("Zara Ali"));
   }
   
   // The injection method (optional)
   def apply(user: String, domain: String) = {
      user +"@"+ domain
   }

   // The extraction method (mandatory)
   def unapply(str: String): Option[(String, String)] = {
      val parts = str split "@"
      
      if (parts.length == 2){
         Some(parts(0), parts(1)) 
      } else {
         None
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Apply method : [email protected]
Unapply method : Some((Zara,gmail.com))
Unapply method : None

Сопоставление с образцом с помощью экстракторов

Когда за экземпляром класса следуют круглые скобки со списком из нуля или более параметров, компилятор вызывает applyв этом экземпляре. Мы можем определять apply как в объектах, так и в классах.

Как упоминалось выше, цель unapplyМетод заключается в извлечении определенного значения, которое мы ищем. Он выполняет обратную операциюapplyделает. При сравнении объекта экстрактора с помощьюmatch заявить unapply метод будет автоматически выполнен.

Попробуйте следующий пример программы.

пример

object Demo {
   def main(args: Array[String]) {
      val x = Demo(5)
      println(x)

      x match {
         case Demo(num) => println(x+" is bigger two times than "+num)
         
         //unapply is invoked
         case _ => println("i cannot calculate")
      }
   }
   def apply(x: Int) = x*2
   def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

10
10 is bigger two times than 5

Scala открыта для использования любых объектов Java и java.io.File является одним из объектов, которые можно использовать в программировании на Scala для чтения и записи файлов.

Ниже приведен пример программы записи в файл.

пример

import java.io._

object Demo {
   def main(args: Array[String]) {
      val writer = new PrintWriter(new File("test.txt" ))

      writer.write("Hello Scala")
      writer.close()
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Будет создан файл с именем Demo.txtв текущем каталоге, в котором размещена программа. Ниже приводится содержание этого файла.

Вывод

Hello Scala

Чтение строки из командной строки

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

пример

object Demo {
   def main(args: Array[String]) {
      print("Please enter your input : " )
      val line = Console.readLine
      
      println("Thanks, you just typed: " + line)
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Please enter your input : Scala is great
Thanks, you just typed: Scala is great

Чтение содержимого файла

Чтение из файлов действительно просто. Вы можете использовать ScalaSourceкласс и сопутствующий ему объект для чтения файлов. Ниже приведен пример, показывающий, как читать из"Demo.txt" файл, который мы создали ранее.

пример

import scala.io.Source

object Demo {
   def main(args: Array[String]) {
      println("Following is the content read:" )

      Source.fromFile("Demo.txt" ).foreach { 
         print 
      }
   }
}

Сохраните указанную выше программу в Demo.scala. Следующие команды используются для компиляции и выполнения этой программы.

Команда

\>scalac Demo.scala
\>scala Demo

Вывод

Following is the content read:
Hello Scala