Variant

i3D中最重要的数据类型。

描述

在计算机编程中,变体类(Variant class)是一种被设计用来存储多种其他类型的类。像PHP、Lua、JavaScript和S3Script等动态编程语言,喜欢在后端使用它们来存储变量的数据。有了这些变体,属性能够自由地改变值类型。

var foo = 2 # foo is dynamically an integer
foo = "Now foo is a string!"
foo = RefCounted.new() # foo is an Object
var bar: int = 2 # bar is a statically typed integer.
# bar = "Uh oh! I can't make statically typed variables become a different type!"

i3D会跟踪变体(Variants)内的所有脚本API变量。你可能都没意识到,其实你一直在使用变体。当某种特定语言对数据类型施加自身规则时,那么该语言就是在基础变体脚本API之上应用其自定义逻辑。- S3Script会自动将值包装在变体中。默认情况下,它将所有数据保留在普通变体中,然后可选择对变量类型强制执行自定义静态类型规则。- C#是静态类型语言,但在需要表示动态值时,会使用其自身对变体类型的实现来替代i3D的Variant类。C#变体可以隐式分配任何兼容类型,但转换需要显式强制转换。全局@GlobalScope.typeof()函数返回当前变量中存储的变体类型的枚举值(请参阅Variant.Type)。

var foo = 2
match typeof(foo):
    TYPE_NIL:
        print("foo is null")
    TYPE_INT:
        print("foo is an integer")
    TYPE_OBJECT:
        # 请注意,对象是其自身的特殊类别。
        # 要获取底层对象类型的名称,你需要使用`get_class()`方法。
        print("foo is a(n) %s" % foo.get_class()) # 将类名注入格式化字符串中。
        #请注意,这不会获取脚本的 `class_name` 全局标识符。
        # 如果需要 `class_name`,请使用 `foo.get_script().get_global_name()`。

A变体仅占用20字节,并且几乎可以在其中存储任何引擎数据类型。变体很少用于长时间保存信息。相反,它们主要用于通信、编辑、序列化以及数据的移动。

i3D专门致力于使其变体类尽可能灵活;以至于它被用于多种操作,以促进i3D所有系统之间的通信。

一个变体:

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

  • 可以在多个变体之间执行操作。S3Script将变体用作其原子/原生数据类型。

  • 可以进行哈希处理,因此可以快速与其他变体进行比较。

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

  • 可以用于抽象调用方法及其参数。i3D通过变体导出其所有函数。

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

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

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

  • 可以作为导出属性使用,因此编辑器可以通用地对其进行编辑。

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

Containers (Array and Dictionary):两者均使用变体实现。Dictionary可以将用作键的任何数据类型与任何其他数据类型进行匹配。Array仅保存一个变体数组。当然,一个变体内部也可以保存一个Dictionary和一个Array,使其更加灵活。

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