Cuando se trabaja con datos, a menudo es necesario convertir variables de un tipo de datos a otro. Por ejemplo, para mostrar el resultado de un cálculo es necesario convertir un float en una cadena.
Toda conversión de tipos dentro de Verse es explícita, lo que significa que debes utilizar una función como ToString()
o utilizar un operador de multiplicación (*
) para convertir un objeto en un tipo de datos diferente. La conversión explícita de un tipo en otro también se denomina casting de tipos.
Conversión de float en int
Convertir un float en un int requiere una función que especifique cómo convertirá un número de coma flotante en un número entero. Las siguientes funciones se encargan de la conversión, pero funcionan de forma diferente. Tú decides cuál se adapta mejor a cada situación.
En este ejemplo, diferentes funciones convierten cuatro valores literales float
en valores int
. A continuación, set
asigna los valores a variables de tipo int
. La expresión if
crea el contexto de fallo para estas funciones falibles.
var WoodCollected:int = 0
var StoneCollected:int = 0
var GoldCollected:int = 0
var FoodCollected:int = 0
if:
# WoodCollected ahora es 2
set WoodCollected = Round[1.5]
# StoneCollected ahora es 1
set StoneCollected = Floor[1.9]
# GoldCollected ahora es 2
set GoldCollected = Ceil[1.2]
# FoodCollected ahora es 1
set FoodCollected = Int[1.56]
Print("Madera recogida: {WoodCollected}")
Print("Piedra recogida: {StoneCollected}")
Print("Oro recogido: {GoldCollected}")
Print("Comida recogida: {FoodCollected}")
Conversión de int en float
La forma de convertir un tipo de datos int en un tipo de datos float es multiplicar por 1.0 el entero. El operador de multiplicación (*
) convierte el entero en un número de coma flotante antes de realizar la multiplicación.
Este código convierte la variable int
StartingPositionX
en una float
mediante multiplicación para poder utilizarla en la declaración de una variable vector3
. El tipo de datos vector3
requiere valores de tipo float
para sus campos X
, Y
y Z
.
var StartingPositionX:int = 960
# CurrentX = 960.0
var CurrentX:float = StartingPositionX * 1.0
var CurrentPosition:vector3 = vector3{X := CurrentX, Y := 0.0, Z := 0.0}
Print("X actual: {CurrentX}")
Conversión en una cadena
Puedes convertir varios tipos de datos en una string
utilizando una función ToString()
o una interpolación de cadenas que llame a una función ToString()
. Actualmente, los siguientes tipos tienen funciones ToString()
incorporadas en Verse.
- float
- int
- []char
- char
- vector2
- vector3
- rotation
En este ejemplo, puedes ver cómo las variables se convierten en una cadena mediante las funciones de interpolación y ToString()
. Ambos métodos tienen el mismo resultado porque la interpolación de cadenas llama a ToString()
.
var WoodCollected:int = 100
# Convertir utilizando la interpolación de cadenas
Print("Madera recogida: { WoodCollected }")
# o función ToString()
Print("Madera recogida: " + ToString(WoodCollected))
var InitialDistance:float = 3.625
# Convertir utilizando la interpolación de cadenas
Print("Distancia inicial: { InitialDistance }")
# o función ToString()
Print("Distancia inicial: " + ToString(InitialDistance))
var CurrentPosition : vector3 = vector3{X:= 960.0, Y:= 540.0, Z := 20.0}
# Convertir utilizando la interpolación de cadenas
Print("Posición actual: { CurrentPosition }")
# o función ToString()
Print("Posición actual: " + ToString(CurrentPosition))
Cómo convertir un tipo de datos personalizado en una cadena
Los tipos de datos personalizados también pueden convertirse en cadenas implementando una función ToString(custom_type)
para el tipo de datos. Si existe una función ToString(custom_type)
, la interpolación de cadenas la utilizará para convertir automáticamente los tipos de datos en cadenas.
Aquí tienes un ejemplo de función personalizada ToString()
para un enum
de frutas.
fruit := enum:
Apple
Banana
Strawberry
ToString(Fruit: fruit):string =
case(Fruit):
fruit.Apple => "Manzana"
fruit.Banana => "Plátano"
fruit.Strawberry => "Fresa"
PickUpFruit():void =
# Ejemplos de uso de la interpolación de cadenas para convertir datos en cadenas
var FruitItem:fruit = fruit.Banana
# Recogido: Plátano
Print("Recogido: {FruitItem}")
set FruitItem = fruit.Apple
# Recogido: Manzana
Print("Recogido: {FruitItem}")
Aquí tienes un ejemplo de función personalizada ToString()
para una clase personalizada. Observa que la función ToString()
se declara fuera de la clase waypoint
. En la función SetDestination()
, la interpolación de cadena de Destination
está llamando a la función personalizada ToString()
.
# Clase personalizada con un constructor y una función ToString()
waypoint := class():
DisplayName:string
Position:vector3 = vector3{}
MakeWaypoint<constructor>(Name:string, X:float, Y:float, Z:float) := waypoint:
DisplayName := Name
Position := vector3{X := X, Y := Y, Z := Z}
ToString(Waypoint: waypoint):string =
return "{Waypoint.DisplayName} at {Waypoint.Position}"
SetDestination():void =
Destination:waypoint = MakeWaypoint("River", 919.0, 452.0, 545.0)
# Río en {x=919.0, y=452.0, z=545.0}
Print("Destino: {Destination}")
Conversión de una referencia de objeto en otro tipo
Puedes convertir explícitamente referencias a objetos (o casting de tipos) en diferentes clases o interfaces utilizando la siguiente sintaxis:
if (NewObjectReference := object_type_to_cast_to[ObjectReference]) {}
object_type_to_cast_to representa la clase o interfaz en la que intentas convertir la referencia. Se trata de una expresión falible porque la conversión de tipo fallará si el objeto no puede convertirse en el tipo especificado. El intento de convertir una referencia de objeto en una clase fallará si la clase no coincide con el tipo del objeto, el tipo de una superclase o una interfaz que implemente la clase del objeto.
Este código declara una interfaz positionable
, una clase abstract shape
que hereda de positionable
y dos subclases de shape
: triangle
y square
. A continuación, crea un objeto de tipo square
llamado MyShape
e intenta convertirlo en otros tres tipos. Aquí tienes un desglose de los resultados.
Conversión de tipo square en |
Resultado |
---|---|
square |
Es correcto porque MyShape es square |
triangle |
Es incorrecto porque triangle no es una superclase de square y triangle no es una interfaz implementada por square |
positionable |
Es correcto porque square es una subclase de shape y todas las subclases de shape deben implementar positionable . |
# Definiciones de clases e interfaces
positionable := interface() {}
shape := class<abstract>(positionable) {}
triangle := class(shape) {}
square := class(shape) {}
# Crea un objeto `square` referenciado mediante la superclase de tipo `shape`
MyShape:shape = square{}
# El resultado será correcto porque MySquare es un objeto `square`
if(MySquare := square[MyShape]):
Print("Conversión correcta de forma a cuadrado")
if(MyTriangle := triangle[MyShape]):
Print("Esto no se imprimirá nunca.")
else:
Print("Error al convertir MyShape en un triángulo. Este es el comportamiento esperado.")
# El resultado será correcto porque la interfaz `positionable` debe ser implementada por subclases de `shape`
if(MyDrawable := positionable[MyShape]):
Print("Conversión correcta de forma a positionable")
En el último ejemplo, la conversión de tipo funcionará, pero no es necesaria. Este código tendrá el mismo resultado:
MyDrawable:positionable = MyShape
Ejemplos de conversión de tipos
Un caso de uso de la conversión de tipos de objetos en UEFN es encontrar actores de un tipo determinado y llamar a funciones basadas en el tipo. Para saber cómo lograrlo, consulta Cómo encontrar actores con una etiqueta de jugabilidad.