Что такое TOptional<T>
TOptional<T> — это шаблонный тип, обертка в которую мы оборачиваем нужный нам тип данных, которое может быть установлено или отсутствовать.
Зачем нужен TOptional<T>
Если нам нужно проверить были записаны какие либо данные в переменную или нет.
В обычной ситуации мы создадим новую переменную записываем в нее значения а после сравниваем с «Магическим значением» что обязывает нас помнить и учитывать такие проверки а если их будет несколько риск ошибки на ровном месте возрастает в разы
Пример кода с проверкой на «Магическое значение»
UPROPERTY(EditDefaultsOnly)
TArray<UObject*> ItemSlots;
int32 FindFirstEmptySlot()
{
for (int32 i = 0; i < ItemSlots.Num(); i++)
{
if (IsValid(ItemSlots[i]))
{
return i;
}
}
return -1;
}
void AddItemSlot(UObject* NewItem)
{
int32 EmptySlot = FindFirstEmptySlot();
if (EmptySlot != -1)
{
}
}В этом коде после поиска слота мы должны проверить найден ли он, а для этого нам необходимо сравнить его с каким-то «магическое значение»
- нужно помнить, что
-1означает «не найдено» - для разных типов придётся использовать разные значения
- легко допустить ошибку при сравнении
TOptional<T> решает эту проблему теперь нам не нужно будет придумывать какие-то значения если мы ничего не нашли теперь у нас есть единообразная проверка для всех подобных случаев и при замене типа нам не нужно будет менять условия во всех местах где использовался этот тип данных
TOptional<int32> FindFirstEmptySlot()
{
for (int32 i = 0; i < ItemSlots.Num(); i++)
{
if (IsValid(ItemSlots[i]))
{
return i;
}
}
return TOptional<int32>();
}
void AddItemSlot(UObject* NewItem)
{
TOptional<int32> EmptySlot = FindFirstEmptySlot();
if (EmptySlot.IsSet())
{
int32 Value = EmptySlot.GetValue();
}
}
Что изменилось
- код становится чище и безопаснее
- мы не используем «магические значения»
- одинаковая проверка для любых типов
Когда использовать TOptional<T>
- Вместо «магических значений»
- нужно явно показать, что результат может быть пустым
- Когда значение может отсутствовать, но не является ошибкой
Когда не нужно использовать
- yже используется указатель
- когда нет нужды проверять значение есть или нет
⚠️ важно помнить если вы вызовете GetValue() метод для неинициализированного значения то вы получите краш игры или редактора
if (EmptySlot.IsSet())
{
int32 Value = EmptySlot.GetValue();
}