solovyov.net

Я вже й забув про це, але нарешті команда Go наважилася виправити найпотворнішу семантику цикла for, коли змінна з посиланням на сутність всередині циклу має одне й те саме посилання, а змінюється вміст по цьому посиланню. На практиці це означає, що при копіюванні даних (ну коли примітивні типи юзаєш, типу числа чи строки) — все нормально, а при використанні посилання — код не робить те що ти очікуєш.

Це трохи типу такого в джаваскрипті:

for (var i = 0; i < 5; i++) { 
  setTimeout(function() { console.log(i)}, 10);
} 

Коли тільки починаєш програмувати, не дуже очевидно, що воно 5 разів залогає цифру 5. В Go, насправді, все ще трошечки гірше, бо мова нижче рівнем і вони в якості западла приводять отаке:

var all []*Item
for _, item := range items {
  all = append(all, &item)
}

Типу у цьому випадку в масиві all буде виключно останній item, повторений len(items) раз. Ну це очевидно критичне западло, і якщо почитати далі опис проблеми, можна вразитися, як неочевидно ця поведінка триггериться. Код, в якому вона є, і в якому нема, візуально один від одного не відрізниш взагалі.

Я радий, що хоча б у 2022 році команда Go нарешті роздуплилася і змінює мову так, щоб це призводило до простішого коду, а не до простішої імплементації компілятора — незважаючи на їх заяви, вони історично частіше схилялися до другого. Сішарп мав таку саму історію і роздуплився на 10 років раніше. 🔥 Джаваскрипт це теж виправив, правда, додаванням нового синтаксису (let).

В обговоренні повно народу, які страждають, що мова стане простішою для розуміння. Схоже що луддитство викоренити неможливо. 🤣

(@ tg)