В предыдущем посте о Realaxy Editor мы говорили о языке черт, который позволяет использовать преимущества множественного наследования. Теперь мы переходим к другой заслуживающей внимания возможности: перегрузке операторов.
Realaxy ActionScript Editor (RASE) доступен здесь (для Windows, Macintosh OS X и Linux). Примечание: если вы впервые работаете с редактором, ознакомьтесь с инструкциями по RASE .
презентационное
Одной из основных функций, добавленных в бета-версию 10 RASE, является поддержка перегрузки операторов, позволяющая разработчикам изменять поведение операторов (*, + и т. Д.) В различных обстоятельствах. Эта особенность, как и множественное наследование , является объектом священной войны между ярыми сторонниками двух разных парадигм программирования.
Преимущества операторов перегрузки очевидны:
- Компактный стиль. Ваши программы могут стать короче и более читабельными; например, гораздо проще использовать что-то вроде
a*b*c
чемa.multiply(b).multiply(с).
- Код часто выглядит более естественным. Четко определенный оператор легче понять и запомнить, чем имя функции и имя функции. Например, комбинируя две переменные типа Point, вы бы предпочли видеть что-то вроде
point1 + point2,
но неpoint1.plus(point2)
.
Настоящим аргументом против перегрузки операторов является потеря контроля над вашим кодом. Иногда неясно, где оператор перегружен, а где нет. Добавление перегруженного оператора вызывает изменения в поведении существующего кода, которые могут привести к неожиданным последствиям.
Перегрузка оператора не включена в ActionScript (ECMA3), даже если она предлагается для стандарта ECMA4. Java не поддерживает перегрузку операторов, но есть и в Groovy («Java с синтаксическим сахаром»), и в Scala. Кроме того, операторы C # могут быть перегружены.
Нельзя сказать, хорошо это или плохо. Тем не менее, это также практически уверен, что иногда это виртуальный необходимость. Например, при объединении в цепочку нескольких математических операций перегрузка операторов действительно делает код намного более кратким, что улучшает понимание того, как он работает. Но достаточно теории — давайте обратимся к практике.
Мы говорим о языковом расширении overloadedOperators, которое появилось в RASE начиная с Beta 10 (сборка 8145+).
Простой способ импортировать его (или любой другой язык) в ваш проект — нажать Ctrl + L ( Cmd + L ) в Realaxy Editor.
Кстати, перегруженные операторы в RASE — это просто порт перегруженного языка Operators от платформы Jetbrains MPS. Мы просто решили не изобретать велосипед и, изучив предметную область приложения, пришли к выводу, что решение Jetbrains кажется достаточным и отвечает всем нашим потребностям. Мы добавили несколько небольших бонусов от нас.
Мы считаем, что это правильный путь языкового программирования, который берет лучшее из других языков и настраивает его для собственных нужд. Подробнее об этом читайте позже в наших следующих статьях о создании языковых расширений.
Шаг 1
Создайте новый проект с модулем внутри.
Шаг 2
Назовите новый корень «операторы».
Шаг 3
Добавьте код для тестирования в основной класс.
Здесь мы создали две переменные, p1 и p2 (тип Point). Теперь мы хотим получить третью переменную, p3, которая будет результатом объединения этих двух точек.
Выведите эти три значения: p1, p2, p3. Мы использовали values
выражений из языковой logging
, чтобы реализовать строковое сообщение для вывода на консоль.
Наш код вызывает сообщение об ошибке: «Операция не может быть применена к этим операндам». Компиляция невозможна.
Шаг 4
Давайте объявим перегрузку оператора. Импортируйте com.realaxy.actionScript.overloadedOperators
.
Шаг 5
Добавьте новый корень « OverlodedOperatorsContainer
»: щелкните правой кнопкой мыши узел пакета и выберите во всплывающем меню.
Шаг 6
Назовите это « MyOperators
».
Здесь мы видим два блока объявлений: « overloaded binary operators
» и « custom operators declarations
».
Шаг 7
Перейти к первому блоку и нажать Enter . Добавлено новое объявление оператора.
Шаг 8
Выберите оператор « +
». Выберите тип Point
для обеих сторон. Установите возвращаемое значение Point
(измените его со значения по умолчанию « void
»).
Теперь мы можем добавить код, который будет выполняться при объединении Point
с Point
(используя оператор « +
»).
Это все.
Красная подсветка, указывающая на ошибку в нашем классе, исчезла.
Шаг 9
Начните компиляцию.
Шаг 10
Создайте конфигурацию запуска для нашего модуля.
Шаг 11
Назначьте основной класс (если вы не сделали этого раньше).
Шаг 12
Мы получаем следующее сообщение на консоли:
Шаг 13
Теперь давайте попробуем выполнить чуть более сложную задачу и переопределить операции вычитания, умножения и деления. Для Number
и Point
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
operator + (Point, Point) -> Point
commutative: false
(left, right)->Point {
return new Point(left.x + right.x, left.y + right.y);
}
operator + (Point, Number) -> Point
commutative: false
(left, right)->Point {
return new Point(left.x + right, left.y + right);
}
operator — (Point, Point) -> Point
commutative: false
(left, right)->Point {
return new Point(left.x — right.x, left.y — right.y);
}
operator — (Point, Number) -> Point
commutative: false
(left, right)->Point {
return new Point(left.x — right, left.y — right);
}
operator * (Point, Point) -> Point
commutative: false
(left, right)->Point {
return new Point(left.x * right.x, left.y * right.y);
}
operator * (Point, Number) -> Point
commutative: false
(left, right)->Point {
return new Point(left.x * right, left.y * right);
}
operator / (Point, Point) -> Point
commutative: false
(left, right)->Point {
return new Point(left.x / right.x, left.y / right.y);
}
operator / (Point, Number) -> Point
commutative: false
(left, right)->Point {
return new Point(left.x / right, left.y / right);
}
|
Шаг 14
Представьте, что вам нужно вычислить точку, которая расположена слева и вниз на 50 пикселей от центра расстояния между двумя точками.
Это просто:
Или даже проще:
Но не забывайте, что в реальной жизни Flasher это было бы так:
Сравните эти цифры. Это достаточно веская причина для использования перегрузки операторов в проектах ActionScript.
Шаг 15
Теперь давайте узнаем, как создавать собственные операторы.
Сначала вернитесь к объявлению MyOperators
и перейдите к custom operators declarations
.
Нажмите Enter, чтобы создать новую декларацию. Визуальное представление будет ~=
.
Шаг 16
Наш пользовательский оператор должен проверить строку на соответствие регулярному выражению. Чтобы описать такое поведение оператора, мы добавляем новую перегрузку, как мы это делали 10 минут назад с помощью Point
. Единственное отличие заключается в добавлении ~=
для автозаполнения.
Левый операнд должен взять String
, а правый — RegExp
. Возвращаемое значение должно быть Boolean
.
Затем добавьте некоторый код, который будет выполняться нашим оператором, вызывая метод test
из значения.
Шаг 17
Создайте тестовую операцию в Main ()
чтобы увидеть, как она работает:
Быстро и просто.
Чтобы избежать путаницы во всех этих пользовательских операторах, вы должны запомнить одну комбинацию клавиш, связанную с навигацией: Ctrl-B (или Ctrl + щелчок по оператору) приведет вас к объявлению оператора.
Полезный совет: чтобы отличить перезагруженный оператор от встроенного, наведите на него курсор мыши и нажмите Ctrl .
Конечно, если вы на Mac, используйте Cmd вместо Ctrl.
Шаг 18
Давайте расширим поведение нашего пользовательского оператора с помощью новой функции — коммутативности .
Выберите оператора и нажмите Alt-Enter . Выберите Flip Binary Operation
во всплывающем меню. Это поменяет обе стороны, однако с сообщением об ошибке, потому что оператор ~=
еще не определен для таких операндов.
Перейдите к декларации операторов. Установите commutative = true
. Красная подсветка ошибки должна исчезнуть (иногда вы должны нажать F5, чтобы обновить вид).
Другими словами, эта « commutative
» установка является старым добрым правилом, согласно которому изменение порядка слагаемых не меняет сумму. Теперь наш оператор ~=
будет работать, если мы поместим RegExp перед строкой.
Слово предупреждения
Гуру ООП предостерегают от злоупотребления этим поведением. Иногда это связано с неожиданными последствиями. Давайте поверим в это и запомним это.
Это все, что нужно сделать. У нас есть перегрузка операторов в ActionScript 3.