Понедельник, 25 Ноября 2024, 10:44

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Странная ошибка компилятора C# в Unity
alexsilentДата: Четверг, 16 Июля 2020, 09:25 | Сообщение # 1
почти ветеран
Сейчас нет на сайте
Код
// Создание Матч3 Блока
void CreateBlock(int x,int y) {
    Block bl;
    for (int a = 0; a<1000; a++) { // Цикл перебора удачного шанса выпадения, чтобы редкие блоки не выпадали часто
        bl = Blocks[Random.Range(0,Blocks.Length)]; // здесь будет полюбому хотя бы один раз инициализирована "bl"
        if (Random.Range(0.1f,99.9f)<=bl.Chance) {break;} //Шанс выпадения блока от 0% до 100%
    }
    Game.Last = Instantiate(bl.gameObject); // создание клетки
    // КОМПИЛЯТОР РУГАЕТСЯ НА ЭТУ СТРОКУ, хотя из кода видно,
    // что переменная "bl" в любом случае будет инициализирована в цикле "for"
}


компилятор выдаёт ошибку:
"Assets/SCRIPTS/Match3/Match3.cs(63,27): error CS0165: Use of unassigned local variable `bl'"

Чтобы ошибки не было, вместо
Код
Block bl;

приходиться писать строку
Код
Block bl = Blocks[Random.Range(0,Blocks.Length)];

считай два раза одну и ту же строку писать, при инициализации переменной и потом в цикле



Сообщение отредактировал alexsilent - Четверг, 16 Июля 2020, 10:07
drcrackДата: Четверг, 16 Июля 2020, 10:12 | Сообщение # 2
старожил
Сейчас нет на сайте
так:
Код
var bl = default(Block);

либо (если это класс):
Код
Block bl = null;


Сообщение отредактировал drcrack - Четверг, 16 Июля 2020, 10:13
GMasstaДата: Четверг, 16 Июля 2020, 10:14 | Сообщение # 3
частый гость
Сейчас нет на сайте
Block bl = null;

И добавь проверку на не null
if(bl == null) return;
Game.Last = Instantiate(bl.gameObject);


Make games, not war
Посмотри мои игры для мобилок, влепи лукаса!
Тут я делаю игры на Unity


Сообщение отредактировал GMassta - Четверг, 16 Июля 2020, 10:17
Storm54Дата: Четверг, 16 Июля 2020, 10:14 | Сообщение # 4
постоянный участник
Сейчас нет на сайте
В C# нельзя использовать переменную, если она не была инициализирована - в ошибке так и написано.

В данном случае bl инициализируется только внутри цикла, но нет гарантий, что цикл вообще будет выполнен, соответственно, переменная так и останется не инициализированной.

Можно просто объявить переменную с начальным значением, например
Код
Block bl = default;
alexsilentДата: Четверг, 16 Июля 2020, 10:23 | Сообщение # 5
почти ветеран
Сейчас нет на сайте
drcrack, Storm54, GMassta, спасибо ребята! Я просто привык с JS, что не обязательно объявлять null,
буду знать!

Цитата GMassta ()
if(bl == null) return;


Говоря об этой строке, я часто ещё со времён JS, проверяю вот так:

Код
if(!bl) return;


Можно ли так в С# проверять? Просто сам C# вроде не ругается на мою строку и всё нормально работает.


Сообщение отредактировал alexsilent - Четверг, 16 Июля 2020, 10:23
drcrackДата: Четверг, 16 Июля 2020, 10:23 | Сообщение # 6
старожил
Сейчас нет на сайте
Код
Block bl = default;

Это относительно новая фича из C# 7 и не факт что у тса в проекте будет доступна

Добавлено (16 Июля 2020, 10:25)
---------------------------------------------
Цитата
Можно ли так в С# проверять? Просто сам C# вроде не ругается на мою строку и всё нормально работает.

Можно если класс определяет implicit каст к bool

Код
public static implicit operator bool(Something smth) {
  return smth != null;
}


В большинстве классов Unity (и унаследованных от них) это есть по умолчанию

Цитата
И добавь проверку на не null
if(bl == null) return;

В чем конкретно смысл этой строчки?
Типо, если по каким-то причинам возникла ошибка при инициализации игры, пусть юзер просто смотрит на пустой экран, а разраб гадает где и почему что-то пошло не так?


Сообщение отредактировал drcrack - Четверг, 16 Июля 2020, 10:29
GMasstaДата: Четверг, 16 Июля 2020, 10:51 | Сообщение # 7
частый гость
Сейчас нет на сайте
Цитата drcrack ()
пусть юзер просто смотрит на пустой экран

У кого пустой, у кого после этого пойдет перезапуск нужных участков, чтобы все работало нормально... Но как не крути, это всяко лучше, чем ошибка и выключение приложения... Я после такого повторно вряд ли запущу, как и многие другие.


Make games, not war
Посмотри мои игры для мобилок, влепи лукаса!
Тут я делаю игры на Unity
drcrackДата: Четверг, 16 Июля 2020, 11:10 | Сообщение # 8
старожил
Сейчас нет на сайте
Цитата
У кого пустой, у кого после этого пойдет перезапуск нужных участков, чтобы все работало нормально...

У меня возникает два вопроса
1) Что именно перезапустит нужные участики если вызывающий код даже не узнает о проблеме?
2) Как это будет работать если перезапуск с использованными настройками всегда приводит к ошибке?

Разработку ПО вроде не вчера придумали и давно уже понятно что ошибка в критичном коде должна ронять приложение, чтобы ее можно было сразу же отловить и исправить.
В случае если она дожила до релиза — отправить отчет разработчикам.

Код
if(bl == null) return;

А такой код допустим только там, где null это не исключение, а нормальное значение переменной, и return не приведет к незапланированному поведению приложения

PS
Цитата
"Assets/SCRIPTS/Match3/Match3.cs(63,27): error CS0165: Use of unassigned local variable `bl'"

Добавлю, что нет никаких технических ограничений, не позволяющих инициализировать локальные переменные аналогично полям
Но разрабы решили сделать это ошибкой просто потому что по их мнению случаи использования таких переменных очень часто являются знаком, что в коде что-то не так
Хотя по-моему предупреждения статического анализатора должны оставаться предупреждениями, а не ошибками, не позволяющими компилировать код
Впрочем это не особо напрягает


Сообщение отредактировал drcrack - Четверг, 16 Июля 2020, 11:18
GMasstaДата: Четверг, 16 Июля 2020, 11:43 | Сообщение # 9
частый гость
Сейчас нет на сайте
Цитата drcrack ()
1) Что именно перезапустит нужные участики если вызывающий код даже не узнает о проблеме?

Лол, я даже не знаю, что он пишет, просто напомнил, что нужно обработать свой возможный null. А тебе лишь бы показать какой ты гуру... спасибо кэп не знал, что Return так работает! То есть return, а то ты и к размеру букв придираешься)))


Make games, not war
Посмотри мои игры для мобилок, влепи лукаса!
Тут я делаю игры на Unity
drcrackДата: Четверг, 16 Июля 2020, 13:19 | Сообщение # 10
старожил
Сейчас нет на сайте
Не похоже что ты вообще хоть что-то понял, так что забей, надеюсь хоть ТС задумается
alexsilentДата: Пятница, 17 Июля 2020, 17:40 | Сообщение # 11
почти ветеран
Сейчас нет на сайте
Цитата drcrack ()
var bl = default(Block);

drcrack, и спасибо за Default, как раз понадобилась первый раз эта штука в совершенно неожиданном месте,
надеюсь я её правильно прикрутил, просто Vector2.zero не хотел прикручиваться к функции:
Код

public void MakeFall(string mode, Vector2 speed = default(Vector2)) {
    //...
}
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг