mirror of
https://github.com/godotengine/godot-docs-l10n.git
synced 2025-12-31 09:49:22 +03:00
139 lines
11 KiB
ReStructuredText
139 lines
11 KiB
ReStructuredText
:github_url: hide
|
||
|
||
.. _class_Variant:
|
||
|
||
Variant
|
||
=======
|
||
|
||
Самый важный тип данных в Godot.
|
||
|
||
.. rst-class:: classref-introduction-group
|
||
|
||
Описание
|
||
----------------
|
||
|
||
В компьютерном программировании класс Variant — это класс, который предназначен для хранения множества других типов. Динамические языки программирования, такие как PHP, Lua, JavaScript и GDScript, любят использовать их для хранения данных переменных на бэкэнде. С этими Variant свойства могут свободно менять типы значений.
|
||
|
||
|
||
.. tabs::
|
||
|
||
.. code-tab:: gdscript
|
||
|
||
var foo = 2 # foo — это динамическое целое число
|
||
foo = "Теперь foo — это строка!"
|
||
foo = RefCounted.new() # foo — это объект
|
||
var bar: int = 2 # bar — статически типизированное целое число.
|
||
# bar = "Ой-ой! Я не могу сделать так, чтобы статически типизированные переменные стали другим типом!"
|
||
|
||
.. code-tab:: csharp
|
||
|
||
// C# статически типизирован. Как только переменная получает тип, ее нельзя изменить. Вы можете использовать ключевое слово `var`, чтобы компилятор автоматически вывел тип.
|
||
var foo = 2; // Foo — это 32-битное целое число (int). Будьте осторожны, целые числа в GDScript — 64-битные, а их прямой эквивалент в C# — `long`.
|
||
// foo = "foo было и всегда будет целым числом. Его нельзя преобразовать в строку!";
|
||
var boo = "Boo — это строка!";
|
||
var ref = new RefCounted(); // var особенно полезен при использовании вместе с конструктором.
|
||
|
||
// Godot также предоставляет тип Variant, который работает как объединение всех совместимых с Variant типов.
|
||
Variant fooVar = 2; // fooVar — это динамическое целое число (хранящееся как `long` в типе Variant).
|
||
fooVar = "Теперь fooVar — это строка!";
|
||
fooVar = new RefCounted(); // fooVar — это GodotObject.
|
||
|
||
|
||
|
||
Godot отслеживает все переменные API скриптов в Variants. Даже не осознавая этого, вы постоянно используете Variants. Когда определенный язык применяет собственные правила для сохранения типизированных данных, то этот язык применяет собственную логику к базовому API скриптов Variant.
|
||
|
||
- GDScript автоматически оборачивает в них значения. Он хранит все данные в простых Variant по умолчанию, а затем опционально применяет пользовательские правила статической типизации к типам переменных.
|
||
|
||
- C# является статически типизированным, но использует собственную реализацию типа Variant вместо класса Godot **Variant**, когда ему нужно представить динамическое значение. Variant C# может быть назначен любой совместимый тип неявно, но преобразование требует явного приведения.
|
||
|
||
Глобальная функция :ref:`@GlobalScope.typeof()<class_@GlobalScope_method_typeof>` возвращает перечислимое значение типа Variant, сохраненного в текущей переменной (см. :ref:`Variant.Type<enum_@GlobalScope_Variant.Type>`).
|
||
|
||
|
||
.. tabs::
|
||
|
||
.. code-tab:: gdscript
|
||
|
||
var foo = 2
|
||
match typeof(foo):
|
||
TYPE_NIL:
|
||
print("foo это null")
|
||
TYPE_INT:
|
||
print("foo — целое число")
|
||
TYPE_OBJECT:
|
||
# Обратите внимание, что объекты — это отдельная особая категория.
|
||
# Чтобы получить имя базового типа объекта, вам понадобится метод `get_class()`.
|
||
print("foo is a(n) %s" % foo.get_class()) # вставьте имя класса в отформатированную строку.
|
||
# Обратите внимание, что при этом не получается глобальный идентификатор `class_name` скрипта.
|
||
# Если требуется `class_name`, используйте вместо этого `foo.get_script().get_global_name()`.
|
||
|
||
.. code-tab:: csharp
|
||
|
||
Variant foo = 2;
|
||
switch (foo.VariantType)
|
||
{
|
||
case Variant.Type.Nil:
|
||
GD.Print("foo это null");
|
||
break;
|
||
case Variant.Type.Int:
|
||
GD.Print("foo — целое число");
|
||
break;
|
||
case Variant.Type.Object:
|
||
// Обратите внимание, что объекты — это отдельная особая категория.
|
||
// Вы можете преобразовать Variant в GodotObject и использовать рефлексию, чтобы получить его имя.
|
||
GD.Print($"foo is a(n) {foo.AsGodotObject().GetType().Name}");
|
||
break;
|
||
}
|
||
|
||
|
||
|
||
Variant занимает всего 20 байт и может хранить внутри себя практически любой тип данных движка. Variant редко используются для хранения информации в течение длительного времени. Вместо этого они используются в основном для связи, редактирования, сериализации и перемещения данных.
|
||
|
||
Godot специально инвестировал в то, чтобы сделать свой класс Variant максимально гибким; настолько, что он используется для множества операций, чтобы облегчить связь между всеми системами Godot.
|
||
|
||
Variant:
|
||
|
||
- Может хранить практически любой тип данных.
|
||
|
||
- Может выполнять операции между многими вариантами. GDScript использует Variant в качестве своего атомарного/собственного типа данных.
|
||
|
||
- Может быть хеширован, поэтому его можно быстро сравнивать с другими вариантами.
|
||
|
||
- Может использоваться для безопасного преобразования между типами данных.
|
||
|
||
- Может использоваться для абстрагирования вызывающих методов и их аргументов. Godot экспортирует все свои функции через Variant'ы.
|
||
|
||
- Может использоваться для отсрочки вызовов или перемещения данных между потоками.
|
||
|
||
- Может быть сериализован как двоичный и сохранен на диске или передан по сети.
|
||
|
||
- Может быть сериализован в текст и использован для печати значений и редактируемых настроек.
|
||
|
||
- Может работать как экспортируемое свойство, поэтому редактор может редактировать его универсально.
|
||
|
||
- Может использоваться для словарей, массивов, парсеров и т. д.
|
||
|
||
\ **Контейнеры (Array и Dictionary):** Оба реализованы с использованием вариантов. :ref:`Dictionary<class_Dictionary>` может сопоставлять любой тип данных, используемый в качестве ключа к любому другому типу данных. :ref:`Array<class_Array>` просто содержит массив вариантов. Конечно, вариант также может содержать :ref:`Dictionary<class_Dictionary>` и :ref:`Array<class_Array>` внутри, что делает его еще более гибким.
|
||
|
||
Изменения контейнера изменят все ссылки на него. :ref:`Mutex<class_Mutex>` следует создать для его блокировки, если требуется многопоточный доступ.
|
||
|
||
.. note::
|
||
|
||
Существуют заметные различия при использовании данного API с C#. Подробнее см. :ref:`doc_c_sharp_differences`.
|
||
|
||
.. rst-class:: classref-introduction-group
|
||
|
||
Обучающие материалы
|
||
--------------------------------------
|
||
|
||
- :doc:`Введение вариативных классов <../engine_details/architecture/variant_class>`
|
||
|
||
.. |virtual| replace:: :abbr:`virtual (Этот метод обычно должен быть переопределен пользователем, чтобы иметь какой-либо эффект.)`
|
||
.. |required| replace:: :abbr:`required (This method is required to be overridden when extending its base class.)`
|
||
.. |const| replace:: :abbr:`const (Этот метод не имеет побочных эффектов. Он не изменяет ни одну из переменных-членов экземпляра.)`
|
||
.. |vararg| replace:: :abbr:`vararg (Этот метод принимает любое количество аргументов после описанных здесь.)`
|
||
.. |constructor| replace:: :abbr:`constructor (Этот метод используется для создания типа.)`
|
||
.. |static| replace:: :abbr:`static (Этот метод не нуждается в вызове экземпляра, поэтому его можно вызвать напрямую, используя имя класса.)`
|
||
.. |operator| replace:: :abbr:`operator (Этот метод описывает допустимый оператор для использования с этим типом в качестве левого операнда.)`
|
||
.. |bitfield| replace:: :abbr:`BitField (Это значение является целым числом, составленным как битовая маска следующих флагов.)`
|
||
.. |void| replace:: :abbr:`void (Нет возвращаемого значения.)`
|