В скала нет понятия оператор, есть понятие метода. Все операторы сводятся к вызовам методов.
Особенности вызовов методов (в том числе и операторных)
Если метод имеет один параметр, то его можно вызвать:
S.indexOf(“eee”)
А можно вызвать как (упустив точку и скобки вокруг аргументов):
S indexOf “eee”
Если аргументов несколько, то можно упустить точку:
S indexOf (5,“eee”)
Если у метода нет параметров то можно упустить точку и/или скобки:
Вместо 7.toString() написать 7 toString или 7.toString
Унарные операторы
В скала унарными операторами могут быть только: «+», «-», «~» и «!».
При этом они определяются как методы с приставкой «unary_».
Например: unary_- или unary_!
Других унарных методов нет!!!
Ассоциативность методов
Ассоциативность методов (операторов) определяется последним символом в имени метода, если метод заканчивается символом двоеточия «:», то такой метод право ассоциативный (то есть это метод будет вызван для правого аргумента), в противном случае он лево ассоциативный (метод будет вызван для левого аргумента).
Например:
A+B означат (A).+(B) – это метод экземпляра А который называться «+» и имеет аргумент В.
A:::B означат (В).:::(А) – это метод экземпляра В который называться «:::» и имеет аргумент А.
Кроме ассоциативности есть еще момент связанный со сверткой выражений с несколькими операторами. При этом лево ассоциативные операторы сворачиваются слева на право, а вот право ассоциативные справа на лево. Так например:
A+B+С означает что, сначала, для экземпляра А будет вызван метод который называется «+», и ему в качестве аргумента будет передан экземпляр В, а далее к результату будет применен метод «+» с аргументом С. То есть эту запись можно записать так (A.+B).+C
A:::B:::С означает что, сначала, для экземпляра С будет вызван метод который называется «:::», и ему в качестве аргумента будет передан экземпляр В, а далее к результату будет применен метод «+» с аргументом А. То есть эту запись можно записать так (C.:::B).:::A
Нельзя смешивать методы с разной ассоциативность!
A:::B+С – не будет пропущено компилятором.
Приоритет методов
В скала существует следующий приоритет методов по убыванию (определяется по символам с которых начинается методы):
- (все операторы, начинающиеся с других специальных символов)
- «/», «%»
- «+», «-«
- «:»
- «=», «!»
- «<», «>»
- «&»
- «ˆ»
- «|»
- (все операторы, начинающиеся с символов)
- (все операторы присвоения включая те, такие как *=, += и т.п.)
Определение методов
Метод всегда определяется ключевым словом def за которым следует имя метода, за которым следует не обязательный список параметров в скобках, а далее идет не обязательное возвращаемое значение, далее идет равно и тело метода в фигурных скобках. при этом компилятор допускает множество упрощений, а тfкже имеет возможность вывести тип возвращаемого значения. В случае рекурсивных вызовов не происходит автоматическое выведение типов.
Это все эквивалентные записи:
def sqrsum(x: Int, y: Int):Int = { return x*x+y*y;}
def sqrsum(x: Int, y: Int):Int = { return x*x+y*y}
def sqrsum(x: Int, y: Int):Int = { x*x+y*y;}
def sqrsum(x: Int, y: Int):Int = x*x+y*y
def sqrsum(x: Int, y: Int) = x*x+y*y
При этом стоит отметить, что параметры не явно являются НЕ ИЗМЕНЯЕМЫМИ значениями.
def sqrsum(x: Int, y: Int) = {x=x*x; y=y*y; x+y} // не компилируется
def sqrsum(x: Int, y: Int) = {val sqrx=x*x; val sqry=y*y; sqrx+sqry} // компилируется
Допускается наличие вложенных функций:
def sqrsum(x: Int, y: Int) = {
def sqr(t:Int) t*t
sqr(x)+sqr(y)
}
Метод для класса можно определить:
def width(): Int = 100
А можно определить и так:
def width: Int = 100
Первый вызов без параметров называется empty-paren methods, а второй parameterless methods. Если метод объявлен без скобок, то его нельзя вызвать вместе с круглыми скобками, в то время как метод объявленный вместе с пустыми круглыми скобками можно вызывать как с ними так и без них.