Variant

Godot 中最重要的数据类型。

描述

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

GDScriptC#

  1. var foo = 2 # foo 是动态类型的整数
  2. foo = "现在 foo 是字符串!"
  3. foo = RefCounted.new() # foo 是 Object
  4. var bar: int = 2 # bar 是静态类型的整数。
  5. # bar = "诶呀!我没法让静态类型的变量变成其他类型!"
  1. // C# 是静态类型的。变量设置类型后无法改变。你可以用 `var` 关键字让编译器自动推断类型。
  2. var foo = 2; // foo 是 32 位整数(int)。请注意,GDScript 中的整数是 64 位的,在 C# 中与之等价的是 `long`。
  3. // foo = "foo 过去、现在、将来都是整数,没法变成字符串!";
  4. var boo = "boo 是字符串!";
  5. var ref = new RefCounted(); // var 非常适合与构造函数配合使用。
  6. // Godot 也提供了 Variant 类,类似于一个与所有 Variant 兼容类型的联合体。
  7. Variant fooVar = 2; // fooVar 是动态类型的整数(在 Variant 类型中存储为 `long`)。
  8. fooVar = "现在 fooVar 是字符串!";
  9. fooVar = new RefCounted(); // fooVar 是 GodotObject。

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

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

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

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

GDScriptC#

  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 is a(n) %s" % foo.get_class()) # 将类名注入格式字符串中。
  11. # 另外请注意,目前没有比较方便的方法来获取脚本的 `class_name` 字符串。
  12. # 如果要获取,你可以使用 ProjectSettings.get_global_class_list()。
  1. Variant foo = 2;
  2. switch (foo.VariantType)
  3. {
  4. case Variant.Type.Nil:
  5. GD.Print("foo 为 null");
  6. break;
  7. case Variant.Type.Int:
  8. GD.Print("foo 为整数");
  9. break;
  10. case Variant.Type.Object:
  11. // 请注意,Object 有自己的特殊分类。
  12. // 可以将 Variant 转换为 GodotObject,通过反射获取名称。
  13. GD.Print($"foo is a(n) {foo.AsGodotObject().GetType().Name}");
  14. break;
  15. }

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 的差异

教程

Previous Next


© 版权所有 2014-present Juan Linietsky, Ariel Manzur and the Godot community (CC BY 3.0). Revision b1c660f7.

Built with Sphinx using a theme provided by Read the Docs.