Bei der Arbeit mit Daten ist es oft notwendig, Variablen von einem Datentyp in einen anderen zu konvertieren. Die Anzeige des Ergebnisses einer Berechnung erfordert zum Beispiel die Konvertierung von Float in String.
Alle Typumwandlungen in Verse sind explizit, d.h. du musst eine Funktion wie ToString()
oder einen Operator wie multiply (*
) verwenden, um ein Objekt in einen anderen Datentyp umzuwandeln. Die explizite Umwandlung eines Typs in einen anderen wird auch Typ-Casting genannt.
Konvertierung von Float zu Int
Die Konvertierung von einer Float- in eine Int-Zahl erfordert eine Funktion, die ausdrücklich angibt, wie sie von einer Fließkommazahl in eine Ganzzahl konvertiert. Die folgenden Funktionen dienen alle der Konvertierung, arbeiten aber alle unterschiedlich. Es liegt an dir, zu entscheiden, was in einer bestimmten Situation am besten funktioniert.
In diesem Beispiel wandeln verschiedene Funktionen vier Float
-Literalwerte in Int
-Werte um. Dann werden die Werte mit set
den Variablen des Typs int
zugewiesen. Der if
-Ausdruck schafft den Fehlerkontext für diese fehlbaren Funktionen.
var WoodCollected:int = 0
var StoneCollected:int = 0
var GoldCollected:int = 0
var FoodCollected:int = 0
if:
# WoodCollected is now 2
set WoodCollected = Round[1.5]
# StoneCollected is now 1
set StoneCollected = Floor[1.9]
# GoldCollected is now 2
set GoldCollected = Ceil[1.2]
# FoodCollected is now 1
set FoodCollected = Int[1.56]
Print("WoodCollected: {WoodCollected}")
Print("StoneCollected: {StoneCollected}")
Print("GoldCollected: {GoldCollected}")
Print("FoodCollected: {FoodCollected}")
Konvertieren von Int zu Float
Die Konvertierung von einem int-Datentyp zu einem float-Datentyp erfolgt durch Multiplikation der Ganzzahl mit 1,0. Der Multiplikationsoperator (*
) wandelt die Ganzzahl in eine Fließkommazahl um, bevor die Multiplikation durchgeführt wird.
Dieser Code wandelt die int
-Variable StartpositionX
durch Multiplikation in eine Float
-Variable um, so dass sie in der Deklaration einer Vektor3
-Variable verwendet werden kann. Für den Datentyp vector3
sind Werte vom Typ float
für die Felder X
, Y
und Z
erforderlich.
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("CurrentX: {CurrentX}")
Konvertieren in String
Du kannst mehrere Datentypen zu einem String
konvertieren, indem du entweder eine ToString()
Funktion oder String-Interpolation benutzt, die eine ToString()
Funktion aufruft. Derzeit haben die folgenden Typen eingebaute ToString()
-Funktionen in Verse.
- float
- int
- []char
- char
- vector2
- vector3
- rotation
In diesem Beispiel wird gezeigt, wie Variablen durch String-Interpolation und ToString()
-Funktionen zu einem String umgewandelt werden. Beide Methoden haben das gleiche Ergebnis, da die String-Interpolation ToString()
aufruft.
var WoodCollected:int = 100
# Konvertierung mittels String-Interpolation
Print("WoodCollected: { WoodCollected }")
# oder ToString()-Funktion
Print("WoodCollected: " + ToString(WoodCollected))
var InitialDistance:float = 3.625
# Konvertierung mittels String-Interpolation
Print("InitialDistance: { InitialDistance }")
# oder ToString()-Funktion
Print("InitialDistance: " + ToString(InitialDistance))
var CurrentPosition : vector3 = vector3{X:= 960.0, Y:= 540.0, Z := 20.0}
# Konvertierung mittels String-Interpolation
Print("CurrentPosition: { CurrentPosition }")
# oder ToString()-Funktion
Print("CurrentPosition: " + ToString(CurrentPosition))
Konvertieren eines benutzerdefinierten Datentyps in einen String
Benutzerdefinierte Datentypen können auch in Strings umgewandelt werden, indem eine Funktion ToString(custom_type)
für den Datentyp implementiert wird. Wenn eine Funktion ToString(custom_type)
existiert, verwendet die String-Interpolation diese, um Datentypen automatisch in Strings zu konvertieren.
Hier ist ein Beispiel für eine benutzerdefinierte ToString()
-Funktion für eine enum
(Aufzählung) von Früchten.
fruit := enum:
Apfel
Banane
Erdbeere
ToString(Fruit: fruit):string =
case(Fruit):
fruit.Apfel => "Apfel"
fruit.Banane => "Banane"
fruit.Erdbeere => "Erdbeere"
PickUpFruit():void =
# Beispiele für die Verwendung der String-Interpolation zur Umwandlung von Daten in Strings
var FruitItem:fruit = fruit.Banane
# Gepflückt: Banane
Print("Gepflückt: {FruitItem}")
set FruitItem = fruit.Apfel
# Gepflückt: Apfel
Print("Gepflückt: {FruitItem}")
Hier ist ein Beispiel für eine benutzerdefinierte ToString()
-Funktion für eine benutzerdefinierte Klasse. Beachte, dass die ToString()
-Funktion außerhalb der waypoint
-Klasse deklariert ist. In der Funktion SetDestination()
ruft die String-Interpolation von Destination
die benutzerdefinierte Funktion ToString()
auf.
# Benutzerdefinierte Klasse mit Construktor und einer ToString()-Funktion
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} an {Waypoint.Position}"
SetDestination():void =
Destination:waypoint = MakeWaypoint("Fluss", 919.0, 452.0, 545.0)
# Fluss an {x=919.0, y=452.0, z=545.0}
Print("Ziel: {Destination}")
Konvertieren einer Objektreferenz zu einem anderen Typ
Mit der folgenden Syntax kannst du explizit Referenzen zu Objekten konvertieren oder zu verschiedenen Klassen oder Schnittstellen type-casten:
if (NewObjectReference := object_type_to_cast_to[ObjectReference]) {}
Der object_type_to_cast_to steht für die Klasse oder Schnittstelle, zu der du die Referenz zu konvertieren versuchst. Dies ist ein fehlbarer Ausdruck, da das Typ-Casting fehlschlägt, wenn das Objekt nicht zum angegebenen Typ konvertiert werden kann. Der Versuch, eine Objekt-Referenz zu einer Klasse zu konvertieren, schlägt fehl, wenn die Klasse nicht mit dem Typ des Objekts, dem Typ einer Oberklasse oder eines Interface übereinstimmt, das von der Klasse des Objekts implementiert wird.
Dieser Code deklariert ein Interface positionable
, eine abstrakte Klasse shape
, die von positionable
erbt, und zwei Subklassen von shape
: triangle
und square
. Dann wird ein Objekt vom Typ square
mit dem Namen MyShape
erzeugt und versucht, es in drei andere Typen umzuwandeln. Hier ist eine Aufschlüsselung der Ergebnisse.
square Typ-Cast zu |
Ergebnis |
---|---|
square |
erfolgreich, weil MyShape ein square ist |
triangle |
scheitert, weil triangle keine Oberklasse von square ist und triangle kein Interface ist, das square implementiert |
positionable |
erfolgreich, weil square eine Subklasse von shape ist, und alle Subklassen von shape müssen positionable implementieren. |
# Klassen- und Interface-Definitionen
positionable := interface() {}
shape := class<abstract>(positionable) {}
triangle := class(shape) {}
square := class(shape) {}
# Erstellen eines Square-Objekts, das über den Superklassentyp shape referenziert wird.
MyShape:shape = square{}
# Dies wird gelingen, da MySquare ein Square-Objekt ist.
if(MySquare := square[MyShape]):
Print("Erfolgreicher Typ-Cast zu Square")
if(MyTriangle := triangle[MyShape]):
Print("Dies wird nie gedruckt.")
else:
Print("Typ-Cast von MyShape zu Dreieck fehlgeschlagen. Dies ist das erwartete Verhalten.")
# Dies wird gelingen, da das positionierbare Interface von Subklassen von shape implementiert werden muss.
if(MyDrawable := positionable[MyShape]):
Print("Typ-Cast von shape zu positionable erfolgreich")
Im letzten Beispiel ist ein Typ-Casting möglich, aber nicht notwendig. Dieser Code führt zu demselben Ergebnis:
MyDrawable:positionable = MyShape
Beispiele für die Typkonvertierung
Ein Anwendungsfall für das Typ-Casting von Objekten in UEFN ist die Suche nach Actors eines bestimmten Typs und der Aufruf von Funktionen auf der Grundlage des Typs. Um herauszufinden, wie man das macht, siehe Suchen nach Actors mit einem Gameplay Tag in Gameplay-Tags.