Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Variant

Godot 中最重要的数据类型。

描述

在计算机编程中,Variant(变体)类是用来存储各种其他类型的类。像 PHP、 Lua、 JavaScript 和 GDScript 这样的动态编程语言喜欢用它们在后端存储变量数据。使用 Variant,属性可以自由地更改值类型。

var foo = 2 # foo 是动态类型的整数
foo = "现在 foo 是字符串!"
foo = RefCounted.new() # foo 是 Object
var bar: int = 2 # bar 是静态类型的整数。
# bar = "诶呀!我没法让静态类型的变量变成其他类型!"

Godot 在 Variant 中跟踪所有脚本 API 变量。你一直在无意中使用 Variant。某种语言为保持数据类型而执行自己的规则时,那么就是该语言在基础 Variant 脚本 API 上应用了自定义的逻辑。

  • GDScript 会自动将数值进行包装。默认情况下会将所有数据保存在普通的 Variant 中,也可以选择对变量类型执行自定义的静态类型规则。

  • C# 是静态类型的,但是当它需要表示动态值时,就会在需要 Godot 的 Variant 类的地方使用它自己实现的 Variant 类型。C# Variant 可以用任意兼容类型隐式赋值,但反之则需要显式类型转换。

全局函数 @GlobalScope.typeof 返回的是枚举类型的值,表示当前变量中所存储的 Variant 类型(见 Variant.Type)。

var foo = 2
match typeof(foo):
    TYPE_NIL:
        print("foo 为 null")
    TYPE_INTEGER:
        print("foo 为整数")
    TYPE_OBJECT:
        # 请注意,Object 有自己的特殊分类。
        # 要获取实际的 Object 类型名称,你需要使用 `get_class()` 方法。
        print("foo is a(n) %s" % foo.get_class()) # 将类名注入格式字符串中。
        # 另外请注意,目前没有比较方便的方法来获取脚本的 `class_name` 字符串。
        # 如果要获取,你可以使用 ProjectSettings.get_global_class_list()。

Variant 只占 20 个字节,可以在其中存储几乎所有的引擎数据类型。Variant 很少用于长期保存信息,主要还是用于通信、编辑、序列化和移动数据。

Godot 特别致力于使其 Variant 类尽可能灵活;以使它可被用于各种操作,促进 Godot 所有系统之间的联系。

Variant:

  • 可以存储几乎任何数据类型。

  • 可以在许多 Variant 之间执行操作。GDScript 使用 Variant 作为其原子/原生数据类型。

  • 可以被哈希,所以可以快速与其他 Variant 进行比较。

  • 可以用于数据类型之间的安全转换。

  • 可以用来抽象调用方法和它们的参数。Godot 通过 Variant 导出所有函数。

  • 可以用来推迟调用或在线程之间移动数据。

  • 可以序列化为二进制并存储到磁盘,或通过网络传输。

  • 可以序列化为文本,用于打印数值和可编辑设置项。

  • 可以作为一个导出的属性工作,所以编辑器可以通用地进行编辑。

  • 可以用于字典、数组、解析器等。

容器(数组和字典):它们都是用 Variant 来实现的。Dictionary 可以将任何作为键的数据类型匹配到到任何其他数据类型。Array 就是持有 Variant 的数组。当然,Variant 也可以在里面再容纳 DictionaryArray,使其更加灵活。

对容器的修改会修改所有对它的引用。如果需要多线程访问,应该创建 Mutex 来对它进行锁定。

备注

通过 C# 使用这个 API 时有显著的不同。详见 C# API 与 GDScript 的差异

教程