Skip to content

类型转换 ​

不同的类型之间,不能直接进行操作,此时就需要用到类型转换

gdscript
var integer: int = "100" # 错误,无法将字符串赋值给整数

类型转换的方法 ​

转换类型可以使用如下方法

  • 构造函数(Constructor)(int(), float())可以进行兼容类型间的强制转换

  • type_convert(Variant, Variant.Type),将给定的值转化为目标类型,转换失败时返回目标类型的默认值

  • str(),尽可能以最佳方式将一个或多个任何 Variant类型的参数转换为一个 String。

  • var_to_str(Variant),将给定值转化为格式化的String

  • str_to_var(String),将var_to_str(Variant)返回的已格式化的string转化为原始Variant

构造函数转换 ​

以基础类型为例,兼容的类型如下表

类型兼容类型构造函数
intString,bool, float, intint(String),int(bool),int(float),int(int)
floatString, bool, int, floatfloat(String), float(bool), float(int), float(float)
boolfloat, int, boolbool(float), bool(int), bool(bool)
StringNodePath, StringName, StringString(NodePath), String(StringName), String(String)
StringNameString, StringNameStringName(String), StringName(StringName)
NodePathString, NodePathNodePath(String), NodePath(NodePath)

在使用构造函数转换类型时需要注意的有

  • 将代表整数的字符串转换为int时会遵循如下规则:

    • 删除所有非数字字符,除了字符串首位的负号(-)

    • 遇到小数点(.)后停止(int("-1.2.3")将会返回-1)

    • 转换失败将得到int默认值(print(int("abc")) # 会输出 0,而不是报错)

转换前最好加上检查:"abc".is_valid_int()

gdscript
print("abc".is_valid_int()) # 输出 false
  • 将代表十进制数的字符串转化为float时会遵循如下规则

    • 在首个非数字字符处停止(float("12xy3")将会得到12.0)

    • 除非是首次遇到小数点(.)或指数标记(e/E)、正负号(+/-)(float("1e3")结果为1000.0, float("12.3.1")结果为12.3)

    • 转换失败将得到float默认值(print(float("abc")) # 会输出 0.0,而不是报错)

    转换前最好加上检查:"abc".is_valid_float()

    gdscript
    print("abc".is_valid_float()) # 输出 false
  • 尽量避免String到StringName的频繁转换

gdscript
var integer: int = int("100")
var str: String = "3.14159"
var float_number: float = float(str)

type_convert(Variant, Variant.Type)转换 ​

万能转换方法,将给定的值转换为目标值,失败时转换的结果是目标类型的默认值

第一个参数是需要转换的值

第二个参数是目标类型,是一个Variant.Type枚举常量,也可以直接传入一个整数

虽然转换后的结果是一个Variant,但其数据和类型和请求的目标类型是相同的

gdscript
var a : int = type_convert("Hi!", TYPE_INT) # a的值是0
var b : int = type_convert("123", TYPE_INT) # b的值是123
var c : int = type_convert(123.4, TYPE_INT) # c的值是123
var d : Vector2 = type_convert(5, TYPE_VECTOR2) # d的值是(0.0, 0.0)
var e = type_convert("Hi!", TYPE_NIL) # e的值是<null>
Variant.Type枚举: ​
枚举常量整数值对应类型
TYPE_NIL0null
TYPE_BOOL1bool
TYPE_INT2int
TYPE_FLOAT3float
TYPE_STRING4String
TYPE_VECTOR25Vector2
TYPE_VECTOR2I6Vector2i
TYPE_RECT27Rect2
TYPE_RECT2I8Rect2i
TYPE_VECTOR39Vector3
TYPE_VECTOR3I10Vector3i
TYPE_TRANSFORM2D11Transform2D
TYPE_VECTOR412Vector4
TYPE_VECTOR4I13Vector4i
TYPE_PLANE14Plane
TYPE_QUATERNION15Quaternion
TYPE_AABB16AABB
TYPE_BASIS17Basis
TYPE_TRANSFORM3D18Transform3D
TYPE_PROJECTION19Projection
TYPE_COLOR20Color
TYPE_STRING_NAME21StringName
TYPE_NODE_PATH22NodePath
TYPE_RID23RID
TYPE_OBJECT24Object及其子类
TYPE_CALLABLE25Callable
TYPE_SIGNAL26Signal
TYPE_DICTIONARY27Dictionary
TYPE_ARRAY28Array
TYPE_PACKED_BYTE_ARRAY29PackedByteArray
TYPE_PACKED_INT32_ARRAY30PackedInt32Array
TYPE_PACKED_INT64_ARRAY31PackedInt64Array
TYPE_PACKED_FLOAT32_ARRAY32PackedFloat32Array
TYPE_PACKED_FLOAT64_ARRAY33PackedFloat64Array
TYPE_PACKED_STRING_ARRAY34PackedStringArray
TYPE_PACKED_VECTOR2_ARRAY35PackedVector2Array
TYPE_PACKED_VECTOR3_ARRAY36PackedVector3Array
TYPE_PACKED_COLOR_ARRAY37PackedColorArray
TYPE_PACKED_VECTOR4_ARRAY38PackedVector4Array
TYPE_MAX39Variant.Type枚举的最大值

str()转换 ​

尽可能以最佳的方式将一个或多个任何类型的值转换为字符串

gdscript
var a = [10, 20, 30]
var b = 3.1415
print(str(a, b)) # 输出"[10, 20, 30]3.1415"
print(str(a)) # 输出"[10, 20, 30]"

var_to_str(Variant)转换 ​

将给定的值转化为格式化的字符串,区别于str()

对对象使用时将得到一个其所有属性都被格式化的字符串

常用于数据的序列化

gdscript
var a = { "a": 1, "b": 2 }
print(var_to_str(a))
print(str(a))

输出:

gdscript
# var_to_str:
{
        "a": 1,
        "b": 2
}

# str:
{ "a": 1, "b": 2 }

不支持转换信号(Signal)和可调用体(Callable),无论它们有什么数据,转换后始终是空值


str_to_var(String)转换 ​

尝试将已格式化的字符串转化为原始的Variant

常用于数据的反序列化

gdscript
var data = '{ "a": 1, "b": 2 }' # data 是一个 String
var dict = str_to_var(data)     # dict 是一个 Dictionary
print(dict["a"])                # 输出 1

自动类型推断 ​

在声明变量并初始化时,可以自动推断类型,这种情况可以省略类型名称

语法如下

  • var 变量名 := 有效初始值

var a: int = 100 等效于 var a := 100

var node: Sprite2D = Sprite2D.new() 等效于 var node := Sprite2D.new()

有效的初始值是指指定的值具有定义的类型:

  • 内置类型(如 int, bool, Vector2等)

  • 引擎的对象类型(如Node, Resource等)

  • 包含脚本资源的常量名(如 MyScript,前提是声明了 const MyScript = preload("res://my_script.gd"))

  • 同一脚本中的内部类,需要注意作用域(比如:在相同作用域内,在 class InnerClass 中声明 class NestedClass 则会得到 InnerClass.NestedClass)

  • 通过class_name声明的全局类

  • 自动加载的单例节点

无法对Variant类型进行自动类型推断:

gdscript
var a = 10 # 不设置类型,实际上是Variant
var b := a # 错误,无法推断变量b的类型,因为变量b或变量a没有设置类型

as关键字 ​

强制转换运算符,常用于引用类型间的转换

要转换的值 as 目标类型

对于对象类型,如果值的类型是目标类型或目标类型的子类,进行转换后会得到同一个对象

gdscript
var my_node2D: Node2D
my_node2D = $Sprite2D as Node2D # Sprite2D是Node2D的子类,所以会转换成功

$NodePath是方法get_node("NodePath")的简写

除此之外,get_node("%UniqueNode")的简写是%UniqueNode,以唯一名称获取节点

如果值的类型不是目标类型也不是目标类型的子类,会导致转换失败,虽然不会报错,但会得到null值

gdscript
var my_node2D: Node2D
my_node2D = $Button as Node2D # 返回的结果将是`null`,因为Button不是Node2D的子类

也就是说,对于类来说,as只能向上转换(子类→父类),不能向下转换(父类→子类),就像一个家庭,不能凭空产生家谱中没有的家族成员

对于内置类型,如果允许,即支持使用构造函数进行转换,也可以进行强制转换,否则将触发报错,因此推荐将其用于引用类型间的转换

例如不能将NodePath或StringName使用as转换为bool,因为其构造函数不存在该转换

gdscript
var my_int: int
my_int = true as int # 得到的结果是1
my_int = Vector2() as int # 错误,两个类型间不兼容,无法转换

对于String类型,即使String和int, float兼容,也不能对常量值使用as,必须使用String类型的变量,转换的行为也同使用构造函数一样

gdscript
var my_int: int = "123" as int # 错误,无法将字符串转换为整数
var my_str: String = "123"
var my_int: int = my_str as int # 正确语法
var my_float: float = "3.14" as float # 错误,无法将字符串转化为浮点数
var my_str_2: String = "3.14"
var my_float: float = my_str_2 as float # 正确语法

# 注意:这样写虽然不会在编辑器中报错,但是会在运行时报错
var my_str :String= "true"
var my_bool:bool = my_str as bool # Invalid cast: could not convert value to 'bool'.

在进行场景树交互时,as关键字非常有用,因为get_child, get_node 的结果其值的类型是Node,而不是我们需要的目标类型,它有可能是其他类型的节点,所以这个时候需要使用强制类型转换

gdscript
var my_sprite := $Character as Sprite2D
($AnimPlayer as AnimationPlayer).play("walk")

一些练习 ​

  1. 想一想可以用哪些方法将字符串"123"转化为整数

  2. 总结一下各种转换类型的方法、使用场景以及注意点

  3. 想一想这段代码的等价写法有哪些:var value := str(100)