Pull to refresh
14
0
Alexander Ivanov @alexanderivanov

Менеджер

Send message

Статья написана не для того чтобы рассказать о возможности привнести assert'ы из Си в Go, а о том, как правильно ими пользоваться (в том числе и на Си)

Если внимательно прочитать статью и уловить суть, то фраза:

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

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

взял код из эксперимента. верну изначальный вариант. Там все буфера предварительно аллоцируются используя sync.Once в начале GetBytes

прошу прощения, вскоре перекрашу картинки и перефразирую сказанное

Согласен, с терминологией порой возникает путаница. Сказал переалоцирование слайса, так как append применяется к слайсу и внешне это именно так и воспринимается, а так да, переалоцирование массива на котором построен(?) слайс.

Думаю, что и термин "передаваться по ссылке" не совсем точный, точнее было бы сказать, что когда аргумент - это указатель, то внутрь функции попадает копия этого указателя, до тех пор, пока никто эту копию не изменил, и спокойно меняет память указываемую оригинальным и скопированным указателем, путаницы не возникает, так как указывают они на одну память.
Тут чуть сложнее, не копия указателя, а копия структуры слайса, где хранится указатель на массив на котором построен слайс.
Но как только внутри функции указатель в копии слайса переписали новым значением (что, вероятно, и делает append вызываемый внутри функции при недостатке capacity), память массива оригинального слайса будет отличаться от того, который был скопирован в функцию, и результат будет неожиданным, если на это не обратить внимание.

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

когда по-другому никак

Не только map, но и slice и string будут передаваться "по ссылке".

Но если строки к счастью не получится модифицировать внутри если не "хитрить" например с unsafe указателями, то для слайсов есть нюансы. Например, если внутри функции слайс переаллоцируется, то исходный слайс не меняется, так как на стеке создаётся временный.
Переаллоцирование слайса гарантированно случится если требуется перераспределение памяти при изменении его capacity. Но так же почему-то новый слайс создастся внутри из-за append'а ДАЖЕ если capacity оригинального слайса достаточное.

https://go.dev/play/p/6nLdrBKpVPY

Сразу вспомнилась книжка Бориса Виана «Уничтожим всех уродов», там про то, как качели эволюции могут качнуться в обратную сторону после того, как вокруг все станут идеальными супер человеками. Спойлерить больше не буду, кто не читал, рекомендую.

Information

Rating
Does not participate
Location
Нижний Новгород, Нижегородская обл., Россия
Works in
Date of birth
Registered
Activity