类型转换
类型转换是指将一个值从一种类型转换为另一种类型的过程,一般用于将该值赋给将要转换到的变量类型的情况。对于简单数据及类似于对象引用这样的较复杂的数据类型来说,将一个值从一个种类型转换为另一种类型是非常有用的。但是,需要记住的是在类型转换过程中可能会丢失数据。
不同类型的数据具有不同的精确级别,将一个较高精确级别的数据类型转换为一个较低级别的类型时将会导致丢失额外的精度位数。
类型转换有两种形式: 隐性转换或显性转换。
隐性类型转换
某些变量数据类型(一般是数值数据类型 - byte
、 int
、 float
)支持彼此间的自动数据类型转换。这称为隐性类型转换,因为您正在转换数据类型但是却没有显示地说明要转换到的数据类型。当您将一种类型的值或变量分配给另一种类型的变量时执行隐性类型转换。
比如:
var int IntVar; var float FloatVar; ... IntVar = 2; // IntVar holds the value 2 FloatVar = 4.25; // FLoatVar holds the value 4.25 ... IntVar = FloatVar; // IntVar now holds the value 4
FloatVar
和 IntVar
是不同的类型,但是您可以将其中的一种类型的值赋予另一个类型的变量,因为 int
和 float
彼此间支持隐性类型转换。
显性类型转换
尽管数值类型可以进行隐性类型转换,但其他类型的数据需要声明要转换到的类型来进行显性类型转换。并不是所有类型都可以通过显性地类型转换为任何其他类型的数据。被转换的数据类型必须支持转换到的目标类型,否则编译器将会抛出错误。
当显性地类型转换一个值时,您必须要指明要转换到的类型,并在后面的圆括号内指出要转换的值。基本语法是:
TypeToCastTo(ValueToCast)
假设您有个 Vector(向量)
变量,您想将其显示为 String(字符串)
。因为 Vector(向量)
数据类型支持显示地转换为 String(字符串)
类型,所有以下代码是完全有效的:
var Vector Offset; var String OffsetText; ... Offset = vect(1.0, 2.5, 5.0); //Offset now holds the values X=1.0, Y=2.5, Y=5.0 OffsetText = String(Offset); //OffsetText now holds the value "1.0,2.5,5.0"
显性类型转换支持的类型
-
string(字符串型)
-
String
数据类型支持转换为以下类型:- Byte, Int, Float -
String
存放的数值将会被转换为真正的数值型数值。如果String
的值不包含一个数值,那么根据要转换到的类型的不同,类型转换的结果将是0
或0.0
。 - Bool -将
String
的值转换为TRUE
或FALSE
。如果String
包含"True"
或"False"
(不区分大小写),那么文本将会被直接转换为等价的Bool
值。如果这些值都不存在,那么String
的值将首先被转换为数值型值(遵循上面描述的规则),然后如果数值型值为0
,则将其转换为Bool
值FASLE
,其他的任何值则转换为TRUE
。 - Vector, Rotator - 将存放
Vector
或Rotation
类型值(三个数值之间由逗号分割,比如“0.5,23.64,18.43”)的文本形式的String(字符串)
转换为指定的目标类型数据。 对于Vector
转换来说,String(字符串)
中的数值将会被转换为具有两位小数位精确度的Float(浮点型)
值。对于Rotator
转换来说,String(字符串)
中的数值将会被删减,或者删除所有小数位,并将其转换为Int(整型)
值。
Bool
- Byte, Int, Float -
-
Bool
数据类型支持被转换为以下数据类型:- String - 将
Bool
型的TRUE
或FALSE
值分别转换为"True"
或"False"
。 - Byte, Int, Float - 将
Bool
型的TRUE
或FALSE
值分别转换为数值1
或0
。
Byte, Int, Float, Vector, Rotator
- String - 将
-
这些数值型数据类型支持转换为以下类型:
- String - 转换为数值的文本形式。对于
Vector
或Rotator
来说,文本形式是三个数值(X
、Y
、Z
或Pitch
、Yaw
、Roll
),三个值之间由逗号分隔。 - Bool - 将数值转换为
Bool
值TRUE
或FALSE
。任何非零值会被转换为TRUE
,而值0将会被转换为FALSE
。对于Vector
或Rotator
来说,每个分量的值都是0则转换为FALSE
。如果有非零值存在,结果将是TRUE
。
Name
- String - 转换为数值的文本形式。对于
-
Name
数据类型支持转换为以下类型:- String - 将
Name
的文本值转换为一个STRING
文本值。
Vector
- String - 将
-
Vector
数据类型支持转换为以下类型:- Rotator - 将从世界原点处到
Vector
坐标指定位置处的方向向量转换为对应那个方向的Rotator
的Pitch
和Yaw
值。==Roll== 值将总是为0
。
Rotator
- Rotator - 将从世界原点处到
-
Rotator
数据类型支持转换为以下类型:- Vector - 将==Rotator==的
Pitch
、Yaw
和Roll
值转换为从原点开始指向旋转向量方向的Vector
的坐标。
Object Reference
- Vector - 将==Rotator==的
-
Object Reference
数值型数据类型支持转换为以下类型:- Int - 将
Object Reference
转换为唯一的Int
值。 - Bool - 如果
Object Reference
保存了一个有效的引用那么则返回TRUE
,否则如果对象引用的值是None
则返回FALSE
。 - String - 将
Object Reference
转换为文本形式,也就是将正在引用的Object
或Actor
的Name
属性转换为字符串 (转换Name
为一个String
数据) ,否则如果没有引用任何Object
,则将转换为"None"
。 - Object Reference - 假设两个类是相关的,那么一个类的
Object Reference
可以从该类转换为另一个类。请参照转换对象引用部分来获得关于这种类型转换的详细信息。
- Int - 将
转换对象引用
就像上面的简单数据类型的转换函数一样,在UnrealScript中你可以在各种类型之间转换actor和object引用。比如,所有的actors有一个叫"Target"的变量,它是到另一个actor的引用。 假如您正在写一个脚本,在脚本中您需要检查并查看Target是否属于"Pawn" actor类的,并且你需要对您的target做一些特殊的处理,但仅当它是一个pawn类时才有效--比如,您需要调用Pawn函数的其中一个。actor的类型转换操作符可以让您完成这个目的。这里是一个示例:
var actor Target; //... function TestActorConversions() { local Pawn P; // Cast Target to Pawn and assign the result to P. If Target is not a Pawn (or subclass of Pawn), then the value assigned to P will be None. P = Pawn(Target); if( P != None ) { // Target is a pawn, so set its Enemy to Self. P.Enemy = Self; } else { // Target is not a pawn. } }
要想执行actor转换,需要书写类的名称并在后面加上您希望转换的actor表达式,并使用圆括号括起。根据这个转换是否合理,转换将或者成功或者失败。在上面的例子中,如果您的Target指向的是一个Trigger对象而不是一个Pawn,表达式Pawn(Target)将会返回"None"值,因为不能将一个Trigger转换为Pawn。然而,如果您的Target指向一个Brute对象,转换将会成功并返回那个Brute,因为Brute是Pawn的子类。
因此,actor类型转换有两个目的: 第一,你可以使用它们来判断某个actor引用是否属于某个类。第二,你可以使用它们来将一个actor引用从一个类转换为一个更加明确的类。注意这些转换不会影响您正在转换的actor—它们只是使UnrealScript将对待那个actor引用就像它是一个更加明确的类型一样并且允许您访问这个更加子类中所声明的属性和方法。
另一个类型转换的列子是在Inventory脚本中。每个Inventory actor由一个Pawn所有,尽管它的Owner变量可以指向任何Actor(因为Actor.Owner是一个Actor类型的变量)。所以在Inventory代码中我们会将常看到将一个Owner转换为Pawn类型的现象,比如:
// Called by engine when destroyed. function Destroyed() { // Remove from owner's inventory. if( Pawn(Owner)!=None ) Pawn(Owner).DeleteInventory( Self ); }