Oxygene (язык программирования)
![]() | |
Разработчик | Программное обеспечение RemObjects |
---|---|
Впервые появился | 2005 г [1] |
Платформа | Общеязыковая инфраструктура , Java , Cocoa , CPU-Native, Windows 32/64-разрядная, Linux 32/64-разрядная, WebAssembly |
Лицензия | Пробная версия |
Веб-сайт | компилятор элементов |
Под влиянием | |
Delphi в Object Pascal , C# |
Oxygene (ранее известный как Chrome ) — язык программирования , разработанный RemObjects Software для Microsoft Common Language Infrastructure , платформы Java и Cocoa . Oxygene основан на Delphi , Object Pascal но также имеет влияние C# , Eiffel , Java , F# и других языков.
По сравнению с ныне устаревшим Delphi.NET , Oxygene не делает упор на полную обратную совместимость, но предназначен для «переосмысления» языка, добросовестного использования управляемых платформ разработки и использования всех функций и технологий, предоставляемых Среды выполнения .NET и Java.
Oxygene является коммерческим продуктом и предлагает полную интеграцию с Microsoft IDE Visual Studio для Windows, а также с собственной IDE под названием Fire для использования на macOS . Oxygene — один из шести языков, поддерживаемых базовым набором инструментов Elements Compiler, наряду с C# , Swift , Java , Go и Mercury (на основе Visual Basic.NET ).
лицензию на свой компилятор и технологию IDE С 2008 по 2012 год RemObjects Software передала Embarcadero для использования в их Embarcadero Prism . продукте [2] Начиная с осени 2011 года, Oxygene стал доступен в двух отдельных редакциях, причем во вторую версию была добавлена поддержка сред выполнения Java и Android. Начиная с выпуска XE4, Embarcadero Prism больше не является частью SKU RAD Studio. Для клиентов Prism существует множество способов поддержки и обновления для перехода на Oxygene. [3] По состоянию на 2016 год существует только одна редакция Oxygene, которая позволяет разработку для Windows или macOS и позволяет создавать исполняемые файлы для Windows, Linux, WebAssembly .NET, iOS, Android, Java и macOS.
Язык
[ редактировать ]Язык Oxygene берет свое начало от Object Pascal в целом и Delphi в частности, но был разработан с учетом принципов программирования .NET и создания полностью совместимых с CLR сборок. Поэтому некоторые второстепенные функции языка, известные из Object Pascal/Delphi, были исключены или пересмотрены, в то время как в язык было добавлено множество новых и более современных функций, таких как универсальные функции или последовательности и запросы.
Oxygene — это объектно-ориентированный язык, что означает, что для разработки программ он использует классы, которые могут хранить данные и выполнять код. [ нужны разъяснения ] Классы являются «прототипами» объектов, подобно тому как идея яблока является прототипом яблока, которое можно купить в магазине. Известно, что яблоко имеет цвет и что его можно очистить: это данные и исполняемый «код» класса яблок.
Oxygene обеспечивает поддержку некоторых функций параллельного программирования на уровне языка. Цель состоит в том, чтобы использовать все ядра или процессоры компьютера для повышения производительности. Для достижения этой цели задачи необходимо распределить между несколькими потоками. Framework .NET ThreadPool
class предлагал способ эффективной работы с несколькими потоками. Библиотека параллельных задач (TPL) была представлена в .NET 4.0, чтобы предоставить больше возможностей для параллельного программирования.
Операторов можно перегрузить в Oxygene с помощью class operator
синтаксис:
class operator implicit(i : Integer) : MyClass;
Обратите внимание, что для перегрузки операторов каждый оператор имеет имя, которое необходимо использовать в синтаксисе перегрузки операторов, поскольку, например, «+» не будет допустимым именем метода в Oxygene. [4]
Структура программы
[ редактировать ]Oxygene не использует «единицы измерения», как Delphi, а использует пространства имен .NET для организации и группировки типов. Пространство имен может охватывать несколько файлов (и сборок), но один файл может содержать типы только одного пространства имен. Это пространство имен определено в самом верху файла:
namespace ConsoleApplication1;
Файлы Oxygene разделены на раздел интерфейса и раздел реализации, который представляет собой структуру, известную из Delphi. Раздел интерфейса следует за объявлением пространства имен. Он содержит uses
предложение, которое в Oxygene импортирует типы из других пространств имен:
uses
System.Linq;
Импортированные пространства имен должны находиться в самом проекте или в сборках, на которые имеются ссылки. В отличие от C#, в Oxygene имена псевдонимов не могут быть определены для пространств имен, а только для имен одного типа (см. ниже).
После uses
В предложении файл содержит объявления типов, известные из Delphi:
interface
type
ConsoleApp = class
public
class method Main;
end;
Как и в C#, метод Main является точкой входа для каждой программы. Он может иметь параметр args : Array of String
для передачи аргументов командной строки в программу.
Можно объявить больше типов, не повторяя type
ключевое слово.
Реализация заявленных методов вынесена в раздел реализации:
implementation
class method ConsoleApp.Main;
begin
// add your own code here
Console.WriteLine('Hello World.');
end;
end.
Файлы всегда заканчиваются на end.
Типы
[ редактировать ]В качестве языка .NET Oxygene использует систему типов .NET: существуют типы значений (например, структуры) и ссылочные типы (например, массивы или классы).
Хотя Oxygene не вводит собственные «предопределенные» типы, для некоторых из них он предлагает более «паскальские» общие имена. [5] так что, например, System.Int32
может использоваться как Integer
и Boolean
( System.Boolean
), Char
( System.Char
), Real
( System.Double
) тоже присоединяется к семейству имен типов Pascal. Структурный характер этих типов, являющийся частью .NET, полностью сохраняется.
Как и во всех языках .NET, типы в Oxygene имеют видимость. В Oxygene видимость по умолчанию assembly
, что эквивалентно internal
видимость в C#. Другой возможный тип видимости: public
.
type
MyClass = public class
end;
Видимость может быть установлена для каждого определенного типа (классы, интерфейсы, записи и т. д.).
Для типов можно определить псевдоним, который можно использовать локально или в других сборках Oxygene.
type
IntList = public List<Integer>; //visible in other Oxygene-assemblies
SecretEnumerable = IEnumerable<String>; //not visible in other assemblies
Псевдонимы общедоступного типа не будут видны для других языков.
Рекорды
[ редактировать ]Записи — это то, что структуры .NET называются в Oxygene. Они объявляются так же, как классы, но с record
ключевое слово:
type
MyRecord = record
method Foo;
end;
Поскольку это всего лишь структуры .NET, записи могут иметь поля, методы и свойства, но не имеют наследования и не могут реализовывать интерфейсы .
Интерфейсы
[ редактировать ]Интерфейсы — очень важная концепция в мире .NET, сама платформа активно их использует. Интерфейсы — это спецификация небольшого набора методов, свойств и событий, которые класс должен реализовать при реализации интерфейса. Например, интерфейс IEnumerable<T>
указывает GetEnumerator
метод, который используется для перебора последовательностей.
Интерфейсы объявляются так же, как классы:
type
MyInterface = public interface
method MakeItSo : IEnumerable;
property Bar : String read write;
end;
Обратите внимание, что для свойств методы получения и установки явно не указаны.
Делегаты
[ редактировать ]Делегаты определяют сигнатуры методов, так что эти методы можно передавать в параметрах (например, обратные вызовы) или сохранять в переменных и т. д. Они являются типобезопасным NET-эквивалентом указателей на функции. Они также используются на мероприятиях. При назначении метода делегату необходимо использовать @
оператор, чтобы компилятор знал, что метод нужно не вызывать, а просто назначить его.
Oxygene может создавать анонимных делегатов; например, методы могут быть переданы в Invoke
метод элемента управления без объявления делегата:
method MainForm.MainForm_Load(sender: System.Object; e: System.EventArgs);
begin
Invoke(@DoSomething);
end;
Анонимный делегат с подписью метода DoSomething
будет создан компилятором.
Oxygene поддерживает полиморфные делегаты, что означает, что делегаты, имеющие параметры нисходящих типов, совместимы по назначению. Предположим, два класса MyClass
и MyClassEx = class(MyClass)
, то в следующем коде BlubbEx
совместимо ли назначение с Blubb
.
type
delegate Blubb(sender : Object; m : MyClass);
delegate BlubbEx(sender : Object; mx : MyClassEx);
Поля можно использовать для делегирования реализации интерфейса, если тип, к которому они относятся, реализует этот интерфейс:
Implementor = public class(IMyInterface)
// ... implement interface ...
end;
MyClass = public class(IMyInterface)
fSomeImplementor : Implementor; public implements IMyInterface; //takes care of implementing the interface
end;
В этом примере компилятор создаст общедоступные методы и свойства в MyClass
, которые вызывают методы/свойства fSomeImplementor
, чтобы реализовать члены IMyInterface. Это можно использовать для обеспечения функциональности, подобной миксину. [6]
Анонимные методы
[ редактировать ]Анонимные методы реализуются внутри других методов. Они недоступны вне метода, если не сохранены внутри поля делегата. Анонимные методы могут использовать локальные переменные метода, в котором они реализованы, и поля класса, к которому они принадлежат.
Анонимные методы особенно полезны при работе с кодом, который должен выполняться в потоке графического интерфейса, что в .NET выполняется путем передачи метода do Invoke
метод ( Control.Invoke
в WinForms, Dispatcher.Invoke
в WPF):
method Window1.PredictNearFuture; //declared as async in the interface
begin
// ... Calculate result here, store in variable "theFuture"
Dispatcher.Invoke(DispatcherPriority.ApplicationIdle, method; begin
theFutureTextBox.Text := theFuture;
end);
end;
Анонимные методы также могут иметь параметры:
method Window1.PredictNearFuture; //declared as async in the interface
begin
// ... Calculate result here, store in variable "theFuture"
Dispatcher.Invoke(DispatcherPriority.ApplicationIdle, method(aFuture : String); begin
theFutureTextBox.Text := aFuture ;
end, theFuture);
end;
Оба исходных кода используют анонимные делегаты .
Уведомление о собственности
[ редактировать ]Уведомление о свойстве используется в основном для привязки данных, когда графический интерфейс должен знать, когда изменяется значение свойства. Платформа .NET предоставляет интерфейсы INotifyPropertyChanged
и INotifyPropertyChanging
(в .NET 3.5) для этой цели. Эти интерфейсы определяют события, которые должны запускаться при изменении/изменении свойства.
Кислород обеспечивает notify
модификатор, который можно использовать в свойствах. Если используется этот модификатор, компилятор добавит интерфейсы в класс, реализует их и создаст код для вызова событий при изменении/изменении свойства.
property Foo : String read fFoo write SetFoo; notify;
property Bar : String; notify 'Blubb'; //will notify that property "Blubb" was changed instead of "Bar"
Модификатор можно использовать для свойств, имеющих метод установки. Код для вызова событий будет добавлен к этому методу во время компиляции.
Примеры кода
[ редактировать ]Привет, мир
[ редактировать ]namespace HelloWorld;
interface
type
HelloClass = class
public
class method Main;
end;
implementation
class method HelloClass.Main;
begin
writeLn('Hello World!');
end;
end.
Общий контейнер
[ редактировать ]namespace GenericContainer;
interface
type
TestApp = class
public
class method Main;
end;
Person = class
public
property FirstName: String;
property LastName: String;
end;
implementation
uses
System.Collections.Generic;
class method TestApp.Main;
begin
var myList := new List<Person>; //type inference
myList.Add(new Person(FirstName := 'John', LastName := 'Doe'));
myList.Add(new Person(FirstName := 'Jane', LastName := 'Doe'));
myList.Add(new Person(FirstName := 'James', LastName := 'Doe'));
Console.WriteLine(myList[1].FirstName); //No casting needed
Console.ReadLine;
end;
end.
Общий метод
[ редактировать ]namespace GenericMethodTest;
interface
type
GenericMethodTest = static class
public
class method Main;
private
class method Swap<T>(var left, right : T);
class method DoSwap<T>(left, right : T);
end;
implementation
class method GenericMethodTest.DoSwap<T>(left, right : T);
begin
var a := left;
var b := right;
Console.WriteLine('Type: {0}', typeof(T));
Console.WriteLine('-> a = {0}, b = {1}', a , b);
Swap<T>(var a, var b);
Console.WriteLine('-> a = {0}, b = {1}', a , b);
end;
class method GenericMethodTest.Main;
begin
var a := 23;// type inference
var b := 15;
DoSwap<Integer>(a, b); // no downcasting to Object in this method.
var aa := 'abc';// type inference
var bb := 'def';
DoSwap<String>(aa, bb); // no downcasting to Object in this method.
DoSwap(1.1, 1.2); // type inference for generic parameters
Console.ReadLine();
end;
class method GenericMethodTest.Swap<T>(var left, right : T);
begin
var temp := left;
left:= right;
right := temp;
end;
end.
Выход программы:
Type: System.Int32 -> a = 23, b = 15 -> a = 15, b = 23 Type: System.String -> a = abc, b = def -> a = def, b = abc Type: System.Double -> a = 1,1, b = 1,2 -> a = 1,2, b = 1,1
Различия между Delphi и Oxygene
[ редактировать ]unit
: заменено ключевым словом пространства имен . Поскольку Oxygene компилирует не для каждого файла, а для каждого проекта, это не зависит от имени файла. Вместо этого ключевое слово unit или namespace используется для обозначения пространства имен по умолчанию, в котором определены все типы для этого файла.procedure
иfunction
:method
хотя это предпочтительное ключевое словоprocedure
иfunction
все еще работаю.overload
: В Oxygene все методы по умолчанию перегружены, поэтому для этого не требуется специального ключевого слова..Create()
: Этот вызов конструктора был заменен вызовомnew
ключевое слово. Его все еще можно включить вproject options
по причинам наследияstring
: символы в строках начинаются с нуля и доступны только для чтения. Строки могут иметь нулевые значения, поэтому проверки пустой строки не всегда достаточно.
Критика
[ редактировать ]Некоторые люди [ ВОЗ? ] хотели бы перенести свой код Win32 Delphi на Oxygene без внесения серьезных изменений. Это невозможно, потому что, хотя Oxygene и выглядит как Delphi, в нем достаточно изменений, чтобы сделать его несовместимым для простой перекомпиляции. Хотя название напоминает другую версию Delphi, это не совсем так. [7]
Помимо языковой разницы, библиотеки визуальных компонентов . в Oxygene недоступна платформа [8] Это еще больше усложняет портирование, поскольку классический код Delphi в значительной степени зависит от VCL.
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ «Эволюция кислородного языка | Кислород | Элементы» . Архивировано из оригинала 05 января 2018 г. Проверено 4 января 2018 г.
- ^ «Страница Embarcadero Prism, внизу страницы изображение, указывающее, что она работает на базе RemObjects Oxygene» . Архивировано из оригинала 27 декабря 2011 г. Проверено 14 декабря 2011 г.
- ^ «Призма XE4, где ты? | Блоги RemObjects» . Архивировано из оригинала 20 июня 2013 г. Проверено 6 июня 2013 г.
- ^ «Перегрузка операторов — Delphi Prism» . Архивировано из оригинала 8 июля 2011 г. Проверено 9 января 2010 г.
- ^ «Встроенные типы — Delphi Prism» . Архивировано из оригинала 8 июля 2011 г. Проверено 10 января 2010 г.
- ^ «Предоставить функциональность, подобную Mixin — Delphi Prism» . Архивировано из оригинала 8 июля 2011 г. Проверено 17 января 2010 г.
- ^ «Обсуждение переполнения стека, где люди отмечают, что Oxygene — это не Delphi Win32» . Архивировано из оригинала 25 октября 2012 г. Проверено 25 июля 2016 г.
- ^ «Обзор Delphi Prism 2010, в третьем абзаце которого говорится, что VCL.net недоступен» . Архивировано из оригинала 4 сентября 2009 г. Проверено 14 декабря 2009 г.