08/11/2023 12:30
Post №351
>>>61
>Пора переходить на язык Zig.
Зачем? Там нет ничего, кроме синтаксического сахара, который к тому же снижает читамость кода.
Можно рассмотреть для примера сравнение спосбов обработки ошибок в Zig и С
https://gist.github.com/andrewrk/d285c8f912169329e5e28c3d0a63c1d8
Сверху два примера на С, первый - с возвратом из функции, второй - с использованим goto. Первое, что бросается в глаза: в обоих примерах код элементарен, прост и однозначен для понимания.
Рассмотрим часть примера с возвратом:
struct SoundIo *soundio = soundio_create();
if (!soundio) {
fprintf(stderr, "out of memory\n");
return 1;
}
int err;
if ((err = soundio_connect(soundio))) {
fprintf(stderr, "unable to connect: %s\n", soundio_strerror(err));
soundio_destroy(soundio);
return 1;
}
Что же происходит в коде на Zig (третий пример)?
const soundio = c.soundio_create() orelse return error.OutOfMemory;
Вроде все понятно, но что за вызов: error.OutOfMemory? Это надо лезть и разбираться, где это определено, как переопределить при необходимости, и что делать если требуется обработка ошибки по возвращаемому коду...
defer c.soundio_destroy(soundio);
try sio_err(c.soundio_connect(soundio))
А вот это уже совсем интерсно! Здесь неявный вызов c.soundio_destroy(soundio) при ошибке в try. То есть получается вызов критической функции, влияющий на утечку памяти, производится неявно? И что такое sio_err()? Опять надо лезть рабираться где это определено и как работает.
То есть что бы сделать элементарную проверку, требуется залазить в "потроха" и выяснять как конкретно в данном случае оргинизован обработчик ошибок? Вдруг там что-то переопределно и отличается от поведения по умолчанию?
Ради экономии нескольких строчек простейшего и понятного кода использовать непонятные вызовы. Не слишком ли высокая цена за синтаксический сахар?