Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
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 = "诶呀!我没法让静态类型的变量变成其他类型!"
// 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 是动态类型的整数(在 Variant 类型中存储为 `long`)。
fooVar = "现在 fooVar 是字符串!";
fooVar = new RefCounted(); // fooVar 是 GodotObject。
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_INT:
print("foo 为整数")
TYPE_OBJECT:
# 请注意,Object 有自己的特殊分类。
# 要获取实际的 Object 类型名称,你需要使用 `get_class()` 方法。
print("foo is a(n) %s" % foo.get_class()) # 将类名注入格式字符串中。
# 请注意,获取到的并不是脚本的 `class_name` 全局名称。
# 如果要获取 `class_name`,请改用 `foo.get_script().get_global_name()`。
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:
// 请注意,Object 有自己的特殊分类。
// 可以将 Variant 转换为 GodotObject,通过反射获取名称。
GD.Print($"foo is a(n) {foo.AsGodotObject().GetType().Name}");
break;
}
Variant 只占 20 个字节,可以在其中存储几乎所有的引擎数据类型。Variant 很少用于长期保存信息,主要还是用于通信、编辑、序列化和移动数据。
Godot 特别致力于使其 Variant 类尽可能灵活;以使它可被用于各种操作,促进 Godot 所有系统之间的联系。
Variant:
可以存储几乎任何数据类型。
可以在许多 Variant 之间执行操作。GDScript 使用 Variant 作为其原子/原生数据类型。
可以被哈希,所以可以快速与其他 Variant 进行比较。
可以用于数据类型之间的安全转换。
可以用来抽象调用方法和它们的参数。Godot 通过 Variant 导出所有函数。
可以用来推迟调用或在线程之间移动数据。
可以序列化为二进制并存储到磁盘,或通过网络传输。
可以序列化为文本,用于打印数值和可编辑设置项。
可以作为一个导出的属性工作,所以编辑器可以通用地进行编辑。
可以用于字典、数组、解析器等。
容器(数组和字典):它们都是用 Variant 来实现的。Dictionary 可以将任何作为键的数据类型匹配到到任何其他数据类型。Array 就是持有 Variant 的数组。当然,Variant 也可以在里面再容纳 Dictionary 和 Array,使其更加灵活。
对容器的修改会修改所有对它的引用。如果需要多线程访问,应该创建 Mutex 来对它进行锁定。
备注
通过 C# 使用该 API 时会有显著不同,详见 C# API 与 GDScript 的差异。