Przy pracy z danymi często zachodzi konieczność konwertowania zmiennych z jednego typu danych na inny. Na przykład wyświetlenie wyniku obliczeń wymaga konwersji z wartości zmiennopozycyjnej (float) na ciąg tekstowy (string).
Wszystkie konwersje typu w Verse są jawne, co oznacza, że trzeba użyć takiej funkcji jak ToString() lub wykorzystać operator – na przykład mnożenia (*) do konwersji obiektu na inny typ danych. Jawna konwersja jednego typu na inny bywa również nazywana rzutowaniem typu.
Konwersja wartości zmiennopozycyjnej (float) na liczbę całkowitą (int)
Konwersja z typu float na typ int wymaga funkcji, która w jawny sposób określa, w jaki sposób przebiegnie konwersja z wartości zmiennopozycyjnej na liczbę całkowitą. Każda z poniższych funkcji umożliwia przeprowadzenie konwersji, ale działa w sposób odmienny od innych. To użytkownik musi zadecydować, która z nich najlepiej sprawdzi się w danej sytuacji.
W tym przykładzie różne funkcje konwertują cztery wartości literału float na wartości całkowite przy użyciu operatora or w celu utworzenia kontekstu niepowodzenia. Następnie set przypisuje wartości do zmiennych typu int.
# The Int[] method has the <decides> effect,
# This means that we need to account for failure as it is a failable expression.
# This results in the following
# var WoodInt:int = failable expression or the value if it fails.
var WoodCollectedFloat:float = 10.5
var WoodInt:int = Int[WoodCollectedFloat] or 0
Print("Printing WoodInt Value (10): {WoodInt}")
# Similar to Int[], Floor[], Ceil[], and Round[] also have the <decides> effect
W tym przykładzie wyrażenie if tworzy kontekst niepowodzenia dla tych funkcji zawodnych, a set przypisuje wartości do zmiennych typu int.
var WoodCollected:int = 0
var StoneCollected:int = 0
var GoldCollected:int = 0
var FoodCollected:int = 0
if:
# This block is the condition of the if expression
# Which creates the failure context
# If any fail, the entire chain of execution is rolled back
# And the else branch, if it exists, is executed
Konwersja liczby całkowitej (int) na wartość zmiennopozycyjną (float)
Operator mnożenia (*) konwertuje liczbę całkowitą na wartość zmiennopozycyjną przed wykonaniem mnożenia. Konwersja z typu danych int na typ float polega na pomnożeniu liczby całkowitej przez 1.0.
Ten kod konwertuje zmienną int StartingPositionX na typ float za pomocą mnożenia, aby można jej było użyć w deklaracji zmiennej vector3. Typ danych vector3 wymaga wartości typu float dla swoich pól X, Y i Z.
# Required for the vector3 type
using { /UnrealEngine.com/Temporary/SpatialMath}
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}")Konwersja na ciąg tekstowy (string)
Istnieje możliwość konwertowania wielu typów danych na string przy użyciu funkcji ToString() lub interpolacji ciągu tekstowego, w trakcie której wywoływana jest funkcja ToString(). Obecnie w Verse funkcje ToString() wbudowane są w następujące typy:
wartość zmiennopozycyjna (float)
liczba całkowita (int)
[]char
char
vector2
vector3
rotation
W tym przykładzie widać zmienne konwertowane na ciąg tekstowy za pomocą interpolacji ciągu tekstowego oraz funkcji ToString(). Obydwie metody pozwalają uzyskać taki sam wynik, ponieważ w trakcie interpolacji ciągu tekstowego wywoływana jest funkcja ToString().
var WoodCollected:int = 100
# Convert using string interpolation
Print("WoodCollected: { WoodCollected }")
# or ToString() function
Print("WoodCollected: " + ToString(WoodCollected))
var InitialDistance:float = 3.625
# Convert using string interpolation
Print("InitialDistance: { InitialDistance }")
# or ToString() function
Konwersja niestandardowego typu danych na ciąg tekstowy (string)
Niestandardowe typy danych również można konwertować na ciągi tekstowe poprzez zaimplementowanie funkcji ToString(custom_type) dla typu danych. Jeśli istnieje funkcja ToString(custom_type), interpolacja ciągu tekstowego wykorzysta ją do automatycznego skonwertowania typów danych na ciągi tekstowe.
Poniżej przedstawiono przykład niestandardowej funkcji ToString() dla wartości enum owoców.
fruit := enum:
Apple
Banana
Strawberry
ToString(Fruit: fruit):string =
case(Fruit):
fruit.Apple => "Apple"
fruit.Banana => "Banana"
fruit.Strawberry => "Strawberry"
Poniżej przedstawiono przykład niestandardowej funkcji ToString() dla klasy niestandardowej. Zwróć uwagę, że funkcja ToString() została zadeklarowana poza klasą waypoint. W funkcji SetDestination() interpolacja ciągu tekstowego Destination wywołuje funkcję niestandardową ToString().
# Custom class with constructor and a ToString() function
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 =
Konwersja odwołania do obiektu na inny typ
Odwołania do obiektów można w sposób jawny konwertować (lub wykonywać dla nich rzutowanie typu) na różne klasy lub interfejsy z użyciem następującej składni:
if (NewObjectReference := object_type_to_cast_to[ObjectReference]) {}object_type_to_cast_to reprezentuje klasę lub interfejs, do których odwołanie próbujesz skonwertować. Jest to wyrażenie zawodne, ponieważ konwersja typu się nie powiedzie, jeśli obiektu nie da się skonwertować na określony typ. Próba skonwertowania odwołania do obiektu na klasę nie powiedzie się, jeśli klasa jest niezgodna z typem obiektu, typem podklasy lub interfejsem, który klasa obiektu implementuje.
Ten kod deklaruje interfejs positionable, klasę abstrakcyjną shape, która dziedziczy z interfejsu positionable, oraz dwie podklasy shape: triangle i square. Następnie tworzy on obiekt typu square o nazwie MyShape i podejmuje próbę rzutowania jego typu na trzy inne typy. Poniżej przedstawiono uzyskane wyniki.
| Rzutowanie typu square na | Rezultat |
|---|---|
| Powiedzie się, ponieważ |
| Nie powiedzie się, ponieważ |
| Powiedzie się, ponieważ |
# Class and interface definitions
positionable := interface() {}
shape := class<abstract>(positionable) {}
triangle := class(shape) {}
square := class(shape) {}
# Create a square object referenced using the superclass type shape
MyShape:shape = square{}
# This will succeed since MySquare is a square object
W ostatnim przykładzie rzutowanie typu zadziała, ale nie jest konieczne. Kod zwróci taki sam wynik:
MyDrawable:positionable = MyShapePrzykładowe zastosowania konwersji typu
Jednym z przypadków zastosowania rzutowania typu obiektu w UEFN jest wyszukiwanie aktorów określonego typu i wywoływanie funkcji na podstawie typu. Aby dowiedzieć się, jak to zrobić, patrz: Wyszukiwanie aktorów oznaczonych tagiem rozgrywki w tagach rozgrywki.