Variant

Godot 中最重要的数据类型。

描述

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

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

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

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

  • VisualScript 也跟踪 Variant 中的属性,但它也使用静态类型。GUI 界面强制要求属性有一个特定的类型,并且不随时间变化。

  • C# 是静态类型的,但是当它需要表示一个动态值时,使用 Mono object 类型来代替 Godot 的 Variant 类。object 是 Mono 运行时对应的同一概念。

  • 静态类型的语言 NativeScript C++ 没有定义一个内置的类似 Variant 的类。Godot 的 GDNative 绑定为用户提供了 godot::Variant 的类;C++ 代码开始与 Godot 运行时交互的地方,你都可能要用 Variant 对象来包装数据。

全局 @GDScript.typeof 函数返回存储在当前变量中的 Variant 类型的枚举值,请参阅 Variant.Type

  1. var foo = 2
  2. match typeof(foo):
  3. TYPE_NIL:
  4. print("foo 是 null")
  5. TYPE_INTEGER:
  6. print("foo 是整数")
  7. TYPE_OBJECT:
  8. # 请注意,Object 是单独的特殊类别。
  9. # 要获取实际的 Object 类型,你需要使用 `get_class()` 方法。
  10. print("foo 是 %s" % foo.get_class()) # 向格式化字符串中注入类名。
  11. # 另外请注意,目前无法通过简单的方法获取脚本的 `class_name` 字符串。
  12. # 要获取该值,你需要深入 ProjectSettings 设置查看隐藏的“_global_script_classes”,这是一个字典的数组。
  13. # 你可以打开 project.godot 文件进行详细查看。

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

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

Variant:

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

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

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

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

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

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

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

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

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

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

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

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

教程