Это не сработает, потому что вы аннулируете head
на первой итерации. Вот поток:
temp := head
// Since temp is a pointer, any modifications made to it will also
// impact head. So when you set temp.Next here, you're also setting
// head.Next. Since prev is always nil on the first iteration, you've
// set head.Next = nil.
temp.Next = prev
prev = temp
// This will set head to nil, always.
head = head.Next
В правильной версии обновление head = head.Next
до того, как произойдет какая-либо запись, означает, что вы уже перешли к следующему элементу, и поэтому безопасно перезаписать значение.
По сути, вторая версия отсекает все элементы списка, кроме первой. Если вы не делали ссылку на второй элемент до вызова этой функции, то теперь они отключены и будут собирать мусор.
Обновления на основе комментариев:
Когда вы делаете что-то вроде temp := head
, вы говорите: «создайте указатель с именем temp
и укажите на то же, на что указывает head
». Если затем вы измените то, на что указывает temp
(как, например, выполнение temp.Next = prev
), вы также увидите изменения при чтении данных, на которые указывает head
, поскольку они все еще указывают на то же место.
Когда вы затем делаете head = head.Next
, вы говорите «обновите head
, чтобы он указывал туда, куда указывает head.Next
». Это обновляет сам head
вместо данных, на которые он указывает, поэтому вы не увидите никаких изменений, связанных с temp
.
Вот хороший ресурс, чтобы узнать больше об указателях: https://dave.cheney.net/2017/04/26/understand-go-pointers-in-less-than-800-words-or-your-money-back