LINUX.ORG.RU

C++ vs Rust: правда ли, что Rust тупо сложнее крестов в базовых сценариях применения?

 


0

6

Если C++ разраба заставить писать код на определённом подмножестве C++ (в первом приближении: не выделять память руками, не юзать указатели, не кастовать типы), то в принципе течь и падать там будет негде. На деле чуть тоньше и проще: указатели можно, но если тебе его передали в конструктор. Есть циклические ссылки, но тоже можно чё-то придумать. В общем, чёткого набора рецептов нет, опытный разраб в конкретном проекте выработает свои достаточно рабочие, плюс статический анализ и прочие там sanity-check тулзы и valgrind-ы скажут где насрано автоматически.

А есть просто Rust, где достаточно запретить писать unsafe и всё будет гарантированно блестяще и даже думать не надо.

Но говорят, Rust сложнее. Думать там надо уже просто чтобы базово взлететь, тогда как для базового взлёта на C++ достаточно быть тупорылым сишником, которому запретили выделять память. Гонят?

! ! ! ААААА ПРОСЬБА ПЕРЕНЕСТИ В TALKS ОШИБСЯ ФОРУМОМ ! ! !

Дополнение к уже написанному в треде.

  1. Тяжёлое наследие плюсов: его нет, если его не юзать. Я же не пишу в Rust ассемблерные вставки везде. Возможность их написать же не говорит о том, что у Rust тяжёлое наследие всей x86/ARM аппаратной платформы. Нормальный C++ код не содержит никаких макросов, например и передач указателей в пределе. Передай ты std::span, std::string_view и т.п. вместо (char* ptr, uint32_t size).

  2. Никогда не понимал тезис, что синтаксис обычного Си - сложный. Он может быть сложный во всех ВОЗМОЖНОСТЯХ, но в базовых сценариях он кажется примитивным: int function_name(int a, int b) { return a * b;} - это же предельно тупейшая идея синтаксиса, которую придумает любой школьник при наличии задачи изобретения ЯП. Даже конфиги хочется писать в таком стиле - см nginx. Так вот, если сознательно не усложнять себе жизнь, то C++ так же прост.

  3. Посмотрим на такие конструкции Rust, выдернутые из контекста:

languages.get_statistics(&input, &cli.ignored_directories(), &config);

Имеются какие-то &. Не знаю что это, но почему не написано input вместо &input? То есть, юзера заставляют думать про разные виды передачи аргумнетов чтоли? Ссылочно/указательно? Чем это отличается от необходимости в крестах думать про rvalue, lvalue, reference, pointer? То есть, от этого момента язык тоже не ушёл: нельзя как в JS/Python херануть объект в аргумент и зашибись - надо думать как херануть.

(0..10).map(|_| "#").collect::<String>()

Питонячно. Какой-то генератор с вызовом какой-то лямбды на каждый объект генератора? Не в курсе как это точно работает, но питонячно! В современных плюсах подобное тоже выразимо, но это уже всё равно не уровень начинающего: понимание подобного что в плюсах, что в расте - признак не дебила.

fn main() -> Result<(), Box<dyn Error>> {

В С++ проще. Не надо писать fn, чтобы сказать, что это функция, достаточно привычных миру () и тип возвращаемого значения в C++ необязательно предварять -> чтобы сообщить компилятору, какое оно. Ту же мы видим некие генерики/шаблоны - в плюсах они выглядят так же.

let mut is_sorted = false;

В Rust это выглядит НАДЁЖНЕЕ чем в С++, потому что заставили написать mut, чтобы сообщить, что это можно менять. В C++ это выглядит так же коротко в принципе: auto is_sorted = false;. Но в крестах ты пишешь const auto is_sorted = false; если надо конст и всё.

Посмотрим как пилятся сруктуры в расте:

pub struct CodeStats {
    /// The blank lines in the blob.
    pub blanks: usize,
    /// The lines of code in the blob.
    pub code: usize,
    /// The lines of comments in the blob.
    pub comments: usize,

Блин, в C++ же проще:

struct CodeStats {
  // The blank lines in the blob.
  usize blanks;
  // The lines of code in the blob.
  usize code;
  // The lines of comments in the blob.
  usize comments;

Я потратил меньше кода в крестах. Мне не надо писать pub напротив каждого поля, я могу его вынести в начало. Плюс, struct в крестах - это по-дефолту всё pub, а class - по-дефолту всё private - можно регулировать приватовость всех полей сразу просто выбором слова, которым объявлять структуру.

Что бесит в Rust: тип в конце. Но в языках, где важна производительность, люди любят подумать про memory layout - «как всё лежит в памяти» и посмотреть в первую очередь на типы всего, что лежит в структуре: какой тип рядом с каким, как это выровняется, например. Понятно, что в структуру в таких случаях данные пихают не по выравниванию, а «что рядом с чем потребляется процом», чтобы «нужное вместе» в одну кеш-линию, поэтому важнее будут имена полей, чем типы. Но всё-таки хочется «от общего к частному»: сначала видеть ЧТО ЭТО В ПРИНЦИПЕ (какой у этого тип), а уже потом как оно называется. Условно, мне хочется в «семантике общения» ситуацию «это собака, её зовут Вася и это тоже собака, и гоша», а не наоборот: «это Вася, а ещё он собака, а это петя и он собака». Я не хочу думать про имена, я хочу сначала схватывать суть уровня «так, тут у нас две псины, что они тут делают», а как они называются я потом разберусь)

pub fn summarise(&self) -> Self {

Об этом уже говорилось, в C++ тут будет меньше кода. А где тип аргумента, статически типизированные вы наши, йопт? В целом понятно, почему они заставили писать pub перед каждой функцией - чтобы тупорылый разраб сразу видел точно публичное оно или нет. А то в C++ напишут слово public: а дальше ряд функций и могут случайно написать функцию не в той секции и она случайно будет public – лучше пусть явно пишут! Но хз, это вкусовщина: мне приятнее организовывать всё именно как в плюсах: написать public и дальше у нас красиво пошёл публичный интерфейс. Нафиг мне pub в глаза пихать на каждый чих. Та же конструкция в C++: Self summarise(T &self) {. Опять же, уже говорилось: наличие & - раст оказался не таким уж простым, юзеру надо думать ссылка там или не ссылка? Где такая же простота, как в ссаном JS, что просто self написал и всё?

Давайте просто сюда посмотрим: https://github.com/sharkdp/fd/blob/master/src/filesystem.rs – в принципе да, всё читаемо, красиво, выразительно. map всякие там. Отсутствие скобок у if бесит конечно, ну ладно, в питонячке так же. Но в целом код на современных крестах выглядит абсолютно так же, может чуть меньше символов напечатать придётся. А где-то вместо map().blabla().bubu() будет несколько процедурных строк, потому что в именно стандартную библиотеку C++ не подвезли именно такой семантики, но она достижима в самом языке.

Посмотрим сюда: https://github.com/XAMPPRocky/tokei/blob/master/src/input.rs

Спецсимвольный perl-адок какой-то немного. Зачем так жить. Степень жести в районе строк 16-26 вообще ничем не способна привлечь юзера в сравнении с самыми мерзкими местами C++. Ясно, что это всё можно как-то объяснить. Точно так же «как-то» можно объяснить вот такой C++ код: https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/src/c++11/thread.cc#L235 - синтаксис обычный такой «сишный», просто вперемешку с макросами и большим количеством ___ в названиях переменных: в общем, оба фаната «как-то» объяснят ад в своих языках, простой мане, которая хотела «простой язык» оба этих места одинаково жопные.

Хочется обратить внимание на такой тонкий психо-нюанс, который похоже имеет место быть в расте: раст далеко не питонячка, всмысле в нём уже таки надо думать о неком таком критическом количестве вещей, что требования к мозгу кандидата поднимаются на такой уровень, где ему уже совсем не противен C++ и возможные дедлоки в тредах не кажутся чем-то сложным: ой, опять мьютексы не в том порядке захватил, поправил и забыл.



Последнее исправление: lesopilorama (всего исправлений: 4)
Ответ на: комментарий от Cergoo

Ну и как бы я напоминаю, что самая тормозная в браузере бабуйня - css - уже переписана в мозилле на Раст и таки мозилла работает уже иногда быстрее хрома. При огромной разнице в количестве разрабов. win-win. Другое дело, не везде Раст нужен.

Shadow ★★★★★
()
Ответ на: комментарий от LamerOk

Верно. Они спокойно будут лежать себе в одном файле в одной табличке на 20, на 100, на 1000 строк. Эту табличку можно прочитать, можно понять, можно выверить переходы, можно проверить вызываемые методы, можно сверить со спекой, если вдруг такая есть

И в чём разница с match{} на столько же ветвей? В том, что в растовой портянке есть лишние переносы строк, которые сбивают тебя с толку? :-D

Крестовый пример сделан ради этого

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

То, что ты не понимаешь, что в конечные автоматы сами по себе == switch, вообще лишает тебя права голоса в этой дискуссии.

Мой милый мальтшыг, я отлично знаю, что такое конечный автомат, и что такое матрица переходов, тоже отлично знаю :-)

intelfx ★★★★★
()
Ответ на: комментарий от kvpfs_2

Хорошо, а разве это не хорошая идея иметь управляющий поток, следящий через очередь за всеми? Я только на питоне мимо крокодил, но как-то так выходило и понравилось.

Shadow ★★★★★
()
Ответ на: комментарий от intelfx

В том, что в растовой портянке есть лишние переносы строк, которые сбивают тебя с толку? :-D

А «лишние» инструкции между переносами строк ты куда потерял, любитель игры в напёрстки?

я отлично знаю, что такое конечный автомат, и что такое матрица переходов, тоже отлично знаю :-)

А я тебе не верю. Если бы ты хоть раз в жизни, хоть в качестве студентческой поделки работал бы со сколько-нибудь сложным конечным автоматом, мне не пришлось бы тебе объяснять красоту крестового примера.

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

Прекрасно! Стало быть мы можем увидеть код на расте, где вся отлично известная тебе ©™ матрица переходов будет выглядеть и редактироваться как матрица, а не как простыня свитча с неизвестным количеством инструкций после каждого кейса, каждый из которых надо выверять вручную?

P.S.

Да, дополню для совсем уж тупых. Автор sml решал две задачи:

  • оформить семантическую матрицу переходов по возможности в наиболее естественном виде в рамках синтаксиса целевого языка программирования - как синтаксическую конструкцию «массив» / «матрица» / «таблица» в зависимости от языка
  • изолировать код обработки событий от матрицы переходов

Последний пункт не менее важен чем первый.

LamerOk ★★★★★
()
Последнее исправление: LamerOk (всего исправлений: 2)
Ответ на: комментарий от Shadow

Может хорошая, может нет, не знаю, смотря что имеется в виду. У меня по сути есть главный поток + Х порожденных под разные задачи (юзер запускает что-нибудь через интерфейса). А потом юзер нажимет «Выход», кол-во потоков в данный момент неизвестно, + после запроса на выход могут появиться новые потоки (модули имеют право тоже что-нибудь запускать).

Решил задачу через передачу в аргументы функции каждого порожденного потока объекта, который в деструкторе декрементирует общий счетчик, главный поток при запросе на завершение шлет всем запросы на остановку и ожидает, когда счетчик будет == 0, лишь после этого берет мьютекс в пуле потоков и делает всем join().

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

kvpfs_2
()
Ответ на: комментарий от rupert

А меня всегда удивляли люди злоупотребляющие аналогиями. Ну это как пацан кричал «Волки», а потом ему настучали по тыкве, в общем все жили долго и счастливо.

Есть теорема Райса: не существует алгоритма, проверяющего нетривиальные семантические свойства программы на Тьюринг-полном языке. Но, если язык ограничить, то можно сделать так, что некоторые семантические свойства будут гарантированы автоматически. Всё. Аналогии идут лесом.

red75prim ★★★
()
Ответ на: комментарий от lesopilorama

Не тупи. Даю подсказку ещё раз:

если исключение не произошло, то это бесплатнее, чем наличие if
В 99.999% случаев

Как ты без if отличишь 00.0001% случай от 99.999% ?

LamerOk ★★★★★
()
Ответ на: комментарий от zurg

На самом деле этот пример - прямо таки эталонная иллюстрация растофанатиков из палаты мер и весов.

Когда растофанатик видит код написанный на другом языке, он не задаётся вопросами «почему этот код так написан?» и «какую задачу решал автор?» Это не имеет для него никакого значения. Единственный вопрос, который волнует растофанатика, это «какие из фич раста можно было бы сюда впендюрить?» Какая будет от этого польза конечному потребителю библиотеки / программы и будет ли она вообще - для растофантика совершенно не важно. Потому что религиозная цель существования растофанатиков - заменить во всей вселенной каждое шило на мыло, так как на мыле буквы «раст».

Это даже попало в МКБ как «RIIR mindset» - «rewrite it in rust».

Растофанатик похож на прыгуна с шестом, который ходит по всему спортивному комплексу, заглядывает в каждую спортивную секцию - по бегу, по плаванию, по боксу, по шахматам - и всем задвигает про то, какой у него отличный шест, какой он гибкий, какой он прочный, какой он упругий, и пытается каждого убедить воспользоваться его шестом, рассказывая, к примеру, как офигенно с помощью шеста двигать фигуры по шахматной доске.

LamerOk ★★★★★
()

Сложнее для освоения на уровне «могу написать программу, которая запустится и что-то сделает». Проще для непосредственного использования для реальных задач после освоения.

CrX ★★★★★
()
Ответ на: комментарий от LamerOk

Если тебе регулярно приходится гуглить значения слов перед тем, как их использовать, это не означает, что у других есть такие же проблемы со словарным запасом и общей эрудицией ;)

intelfx ★★★★★
()
Ответ на: комментарий от LamerOk

Вы вроде бы разные тезисы доказываете, не противоречащие друг другу.

  1. Плюсовый пример лучше, т. к. декларативная таблица.
  2. В плюсах тут нужна магия, а в rust всё просто.
unsigned ★★★★
()
Ответ на: комментарий от unsigned

Это не разные тезисы. Это разные задачи. Задача плюсового примера:

  • создать декларативный язык для описания матрицы переходов
  • вынести код обработчиков событий отдельно от матрицы

Задача примера на расте - показать, что перегрузку можно заменить паттернматчингом. Задача капитанская и не стоила поста на лоре. Юмор ситуации в том, что в процессе замены шила на мыло были полностью утеряны те преимущества, что были у шила, то есть то, ради чего вообще была использована перегрузка в крестах.

Ну то есть, это как если бы кто-то привёл пример абстрактного наследования на крестах с одной виртуальной функцией, а её тут же переписали бы на сишку со switch’ом как «иллюстрацию» преимущества сишки.

LamerOk ★★★★★
()
Последнее исправление: LamerOk (всего исправлений: 1)

А есть просто Rust, где достаточно запретить писать unsafe и всё будет гарантированно блестяще и даже думать не надо.

А почему просто не убрать unsafe из хруста? Или если убрать то он чего-то не будет уметь что очень нужно?

Kolins ★★★★★
()
Ответ на: комментарий от Kolins

Да, не будет уметь то, что очень нужно для системного языка: доступ к произвольным адресам памяти, ассемблерные вставки, вызов внешних функций, реализация некоторых структур данных.

red75prim ★★★
()
Ответ на: комментарий от LamerOk

все эти кон.автоматы тривиально и максимально абстрактно делаются даже на си. если какой-то там руст может сделать это лучше - бросьте в меня камень.

///тип - функция стейта.
type StateFunction...

///конкретные стейт функции
StateFunction state_fun0() {
  ....
  if (cond) return state_fun1; ///переход на стейт1
  else return state_fun2; ///переход на стейт 2
}

StateFunction state_fun1() {
  ....
  return state_fun5; ///переход на стейт 5
}

StateFunction state_fun2() {
  ....
}
...

///текущий стейт
StateFunction curr_state = state_fun0; ///начинаем со стейта 0

while (! bool_exit ) {
  curr_state = curr_state(); ///выполняется функция текущего стейта и возвращает новый стейт.
}

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 2)

раст далеко не питонячка, всмысле в нём уже таки надо думать о неком таком критическом количестве вещей, что требования к мозгу кандидата поднимаются на такой уровень, где ему уже совсем не противен C++

Это в сборник мудрых мыслей и великий цитат, я считаю. Хорошо сказано.

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 1)
Ответ на: комментарий от rumgot

У id число всегда, status — строка, потому как statusCode число, а result - это не аргумент функции, а результат, который должен быть понятен из названия самой функции. Математики - это отдельная каста недопрограммистов с однобуквенными названиями переменных и загадочными названиями функций, для которых нужны тупизация и даже венгерская нотация, потому как и типы их писанину понятнее не делают.

rtxtxtrx ★★
()
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от rumgot

Дергание через питоняшьи биндинги по скорости ничем не отличается, но ты можешь и на C++ такое писать, кто ж тебе запретит. Когда я вижу всю эту нейродрочь типа тензерфлоу и пр, то понимаю, что передо мной не погроммист, а очередной я не сварщик, а поэтому у него и проблемы специфические… Плохому погроммисту отсутствие типизации мешает, ага, как танцору — яйца (которые на удивление у всех почти одного размера в отличии от бибиджона)

rtxtxtrx ★★
()
Ответ на: комментарий от LamerOk

Это даже попало в МКБ как «RIIR mindset» - «rewrite it in rust».

А что им остается. Нового ничего сделать нельзя, потому как язык убог для написания программ с графическим интерфейсом, а все возможные консольные утилиты уже придуманы

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

В оригинале слово дуругое и букв на одну меньше

rtxtxtrx ★★
()
Ответ на: комментарий от rtxtxtrx

У id число всегда, status — строка,

але. даже «просто числа» разные бывают, и по знаковости и по разрядности и по цельности, и по представлению запятой.

и строки разные бывают. и строка, которая содержит например путь к файлу, это не та строка, которая содержит пароль. это если типами пользоваться правильно.

а ваш детский сад, где все числа одинаковые и строки - на одно лицо, мастерам погромистского жанра просьба не предлагать.

alysnix ★★★
()
Ответ на: комментарий от alysnix

и строка, которая содержит например путь к файлу, это не та строка, которая содержит пароль. это если типами пользоваться правильно

это уже шизофрения какая-то, противорчещая принципу Оккама

мастерам погромистского жанра просьба не предлагать

id из базы берут, а в базе это всегда числа, но мастерам такое откуда знать + в скриптовых языках нет кучи типов для int и float, там это по факту один тип float64

rtxtxtrx ★★
()
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от rtxtxtrx

это уже шизофрения какая-то, противорчещая принципу Оккама

шизофрения, это считать что все строки совместимы по смыслу. а все числа имеют одну разрядность и что лопаты можно складывать с землекопами и делить на температуру.

alysnix ★★★
()
Ответ на: комментарий от rtxtxtrx

id из базы берут, а в базе это всегда числа,

число это то, для чего определены обычные арифметические операции.

вопрос - id можно складывать, вычитать, делить, умножать? нет. поэтому id это не число. а некое уникальное значение перечислимого типа.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

тебя никто не заставляет писать на нормальных языках где вместо кучи типов чисел есть лишь - один float 64, который представляет int и float, но под капотом всего один тип. пока ты воюешь с типами и путаешься в указателях с ссылками успешные пацаны становятся синьорами-квадробобиками в 21

вопрос - id можно складывать, вычитать, делить, умножать?

такие вопросы только у неосиляторов возникают. id — это всегда число у проектировщиков баз. но есть исключения в виде sql server у виндузятников и mongodb для успешных квадробобиков, пишущих на б-гомерзкой ноде.

все твои странные заявления свидетельствуют лишь о твоем узком кругозоре и неспособности разобраться в чем-либо самостоятельно

rtxtxtrx ★★
()
Ответ на: комментарий от rtxtxtrx

id — это всегда число у проектировщиков баз

потому что те, кто разработал эти субд и дал юным пионерам-«проектировщикам баз» заработать кусок хлеба, ничего иного и не предполагали.

«проектировщики баз» это не программисты, и не разработчики субд. им много не надо.

alysnix ★★★
()
Ответ на: комментарий от rtxtxtrx

id число всегда

  • нет, может быть строка

statusCode число

  • а status не обязательно

result - это не аргумент функции, а результат, который должен быть понятен из названия самой функции.

  • Ага т.е. любой тип
rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 2)
Ответ на: комментарий от rtxtxtrx

пока ты воюешь с типами и путаешься в указателях с ссылками успешные пацаны становятся синьорами-квадробобиками в 21

Знавал я их. Они потом не могут вообще ничего нормального. Например херачат хэш таблицы там, где списка за глаза.

rumgot ★★★★★
()
Ответ на: комментарий от LamerOk

Чего 0_0, хватит спорить с голосами в своей голове, и выдумывать за других. Задача была - сделать типобезопасный эффективный и по возможности удобный конечный автомат, всё, точка. Какая нахрен перегрузка, срать на неё десять раз, и на виртуальные функции с наследованием тоже срать.

создать декларативный язык для описания матрицы переходов

и в растовой версии он есть, минимальный и декларативный настолько на сколько это вообще возможно - " Establ => Connected " - куда ещё декларативнее?

вынести код обработчиков событий отдельно от матрицы

представь себе, в расте есть функции ( которые уже в примере), а так же модули, и дженерики с трейтами: выноси что хочешь, куда хочешь, и как хочешь. Хочется синтаксически таблички рисовать, юзаешь макросы, и тут плюсы вообще со свистом продуют. Вообще пример то ещё щадящий для плюсов, но даже так, по требованию типобезопасности они уже не дотягивуют.

zurg
()
Ответ на: комментарий от rumgot

Сойдёт для сельской местности, в смысле системщины и около неё. Хрен его знает почему, но у системщиков чувство синтаксического прекрасного не то что отсутствует, оно отрицательное несмотря на все их инженерные скилы. Вот у Гвидо и некоторых функциональщиков с этим сильно получше, ну и ещё у тех кто аду пилил

zurg
()
Ответ на: комментарий от alysnix

Типобезопасность же, и зерокост с эффективностью желательно, где это всё в сишке? Ну и хочется всё-таки нормальный полноценный язык, а не сишку, вот вообще не хочется разгребать самого примитивного процедурного вида макароны, 70 -80 е давно кончились

zurg
()
Ответ на: комментарий от zurg

в приведенном примере «типобезопасностость» абсолютная. там просто нечему ломаться, а определение машины состояний именно то, что дает теория.

никакой руст, паттерн матчинг(красивое название для оператора if), перечисления и проч. ерунда не нужны. нужны только функции состояний и все.

alysnix ★★★
()
Ответ на: комментарий от zurg

И это ещё самое простое для рачта, если по полной расчехлить растовый тайпстейт вменяемый аналог на плюсах вообще не получится написать

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

Еще не считая того, что все эти растовые «тайпстейты» в конечном итоге требуют от тебя нафигачить всяких мусорных enum-ов в коде, то есть по сути являются сишными tagged union для идиотов.

struct foo { int hi() { return 1; } };
struct bar { long long hi() { return 2; } };

void cb(auto s) {
  if constexpr (is_same_v<decltype(s.hi()), int>) {
    cout << "foo\n";
  } else {
    cout << "bar\n";
  }
}

void f(int x) {
  if (x % 2 == 1) {
    cb(foo{});
    return;
  }
  cb(bar{});
}

давай, удачи и хорошего настроения.

Lrrr ★★★★★
()
Ответ на: комментарий от rtxtxtrx

id - это что угодно, как status и result.

status — строка, потому как statusCode число

Да с чего ты это взял вообще? Из сборника внегласных правил js?

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 1)
Ответ на: комментарий от rtxtxtrx

Т.е. получается так. Из-за того, что в js нет статических типов, его адепты изобрели суррогат в виде негласных правил именования, предназначенных для понимания, какой тип у той или иной переменной на основе ее имени. Т.е. вы изобрели а-ля венгерку, при том что сама венгерка уже нафиг не нужна в языках со статической типизацией.

rumgot ★★★★★
()