Одним із способів визначення складених або спеціалізованих типів у D є
визначення їх через struct
:
struct Person {
int age;
int height;
float ageXHeight;
}
Структури завжди створюються у стеці (якщо не створенi за допомогою new
)
і копіюються за значенням при присвоєнні чи при передачі у якості
параметру фукнції.
auto p = Person(30, 180, 3.1415);
auto t = p; // створюється копія
Коли створюється новий об'єкт типу struct
, його члени можуть бути
ініціалізовані у тому ж порядку, в якому вони визначені у 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); // iнiцiалiзацiя
p = Person(30, 180); // призначення новим екземпляром
struct
може містити будь-яку кількість функцій. За замовчуванням усi
вони мають рiвень захисту public
і доступнi ззовні. Вони можуть також
мати рiвень захисту private
. У цьому випадку їх зможуть викликати
лише функції тієї ж структури, або інши код того ж самого модуля.
struct Person {
void doStuff() {
...
private void privateStuff() {
...
p.doStuff(); // викликає метод doStuff
p.privateStuff(); // заборонено
Якщо функція оголошується з ключовим словом const
, то буде заборонено
змінювати будь-який її член. Це забезпечується компілятором. Функція з
ключовим словом const
може бути викликаною з будь-якого const
або
immutable
об'єкта, і є гарантія, що ця функція не змінить стан об'єкта.
Якщо функція оголошена як static
, вона буде викликатися без екземпляра
об'єкта (наприклад - Person.myStatic()
), але їй заборонений доступ до
будь-яких не-static
членів. static
функцію можна використовувати,
якщо вам не потрібний доступ до полів об'єкту, але логічно його
розмістити у тому ж класі. Також можна використовувати статичні функції
для реалізації функціональності, якій не потрібно створювати об'єкт.
Наприклад, шаблон проектування Сінглтон (або Singleton
, який існує
лише в одному екземплярi) використовує static
.
Зверніть увагу, що struct
не може успадковуватись від іншого struct
.
Iєрархiї типів можуть бути побудовані тільки з використанням класів,
з якими ми ознайомимось у наступному розділі. Однак з alias this
або mixins
можна легко досягти поліморфного успадкування.
Маючи struct Vector3
реалізувати наступні функції і зробити
так, щоб приклад програми виконувався успішно:
length()
- повертає довжину вектора.
dot(Vector3)
- повертає скалярний добуток двох векторiв.
toString()
- повертає рядкове уявлення вектору.
Функцiя std.string.format
повертає рядок використовуючи printf
-подiбний синтаксис:
format("MyInt = %d", myInt)
. Більш детально рядки будуть пояснені у
наступих розділах.