Один из способов определить составной или пользовательский тип в D - это
задать его через struct
:
struct Person {
int age;
int height;
float ageXHeight;
}
Структуры всегда создаются на стеке (если не созданы через new
) и копируются
по значению при присвоении или при передаче в качестве параметра функции.
auto p = Person(30, 180, 3.1415);
auto t = p; // создаётся копия
При создании нового объекта типа struct
его члены могут быть инициализированы в порядке, в котором они определены в структуре. Пользовательский конструктор можно задать с помощью this(...)
.
Чтобы избежать конфликта имён, доступ к текущему экземпляру можно явно получить через this
:
struct Person {
this(int age, int height) {
this.age = age;
this.height = height;
this.ageXHeight = cast(float)age * height;
}
...
Person p(30, 180); // инициализация
p = Person(30, 180); //присвоение нового экземпляра
Структура может содержать любое число методов. Они по умолчанию являются
public
и доступны снаружи. Их можно объявить private
, тогда их смогут вызывать только методы этой же структуры, либо другой код того же модуля.
struct Person {
void doStuff() {
...
private void privateStuff() {
...
p.doStuff(); // вызов метода doStuff
p.privateStuff(); // запрещено
Если метод объявлен как const
, то невозможно изменить любой из его членов. Это обеспечивается компилятором. Объявление метода как const
делает его вызываемым из любого const
или immutable
объекта и гарантирует, что метод никогда не изменит состояние этого объекта.
Если метод объявлен как static
, он может быть вызван без создания
экземпляра объекта, вроде Person.myStatic()
, но не может вызывать
не-static
методы. Статический метод может быть использован, если методу не требуется доступ к полям объекта, но логически он относится к тому же классу. Также можно использовать статический метод для реализации функциональности, не требующей создания объекта, например, шаблона проектирования Singleton (разрешен только один экземпляр).
Обратите внимание, что структура не может наследовать от другой структуры.
Иерархию типов можно построить только с использованием классов, которые рассматриваются в одном из следующих разделов.
Однако с помощью alias this
или mixins
можно легко достичь полиморфного наследования.
Учитывая struct Vector3
, реализуйте следующие функции и добейтесь, чтобы пример
приложения успешно выполнялся:
length()
- возвращает длину вектора
dot(Vector3)
- возвращает скалярное произведение двух векторов
toString()
- возвращает строковое представление вектора.
Функция std.string.format
возвращает строку, используя printf
-подобный синтаксис:
format("MyInt = %d", myInt)
. Более подробно строки будут рассмотрены в одном
из следующих разделов.