Обращение к полям структуры

введите сюда описание изображения

"И снова эти указатели". Пример из курса. Автор обращается к *Воркеру и итерирует по списку юзеров, а не к разыменованному указателю (вроде так можно, ок, допускаем). Вопроса два:

  1. на строчке 37 берем одного юзера, и уже тут разыменовываем указатель. Не понятно, почему на 36стр. не разыменовываем, тут разыменовываем
  2. на строчке 37, если навести курсор, показывает тип *Юзер, хотя в структуре Воркер массив просто юзеров. Возможно сам отвечу на 1 и 2ой вопросы: возможно эти строчки идентичны, и указатель относится не к w?
&w.users[i] 
&(w.users[i])

Ответы (2 шт):

Автор решения: Alpensin

На 36 строке мы бежим по индексам слайса. На 37-й получаем по индексу структуру юзера и присваиваем переменной user указатель на юзера. Мы не разыменовываем ничего на 37-й. Разыменование это когда мы перед переменной с указателем пишем *. А & это наоборот, получение адреса в памяти у значения, т.е. получение указателя.

→ Ссылка
Автор решения: Pak Uula

В спецификации языка Го есть понятие адресуемости, addressability: https://go.dev/ref/spec#Address_operators

Оператор & возвращает адрес адресуемого операнда:

  • переменная, &v
  • разыменование указателя, &*ptr
  • индексирование слайса, &someSlice[i]
  • поле адресуемого операнда структурного типа, &some.Field
  • индексирование адресуемого операнда типа массив, &some.ArrField[i].

Кроме того, можно получить адрес у составного литерала, &SomeStruct{ SomeField: someVal }

В вашем случае &w.users[i] операндом является w.users[i]. w - переменная, значит адресумый операнд. w.users - поле адресумого операнда, тоже адресуемый операнд. Дальше наступает скользкий момент. В спецификации сказано про слайсы на одном уровне с переменными, зато про массивы сказано индексирование адресуемого массива. Тип []User - не массив, а слайс, но можно сделать вид, будто мы этого не понимаем, и обобщить спецификацию: w.users[i] - это индексирование адресуемого операнда типа слайс, и поэтому тоже адресуемый операнд. Я не первый раз сталкиваюсь с неполнотой спецификации, и поэтому не дёргаюсь )

Следовательно, выражение &w.users[i] есть получение адреса i-го элемента слайса w.users.

Ну и для примера несколько видов неадресуемых операндов:

  • возвращаемое значение функции, &f(x)
  • индексирование отображения,
    var someMap = map[string]int{"one": 1}
    var ptr = &someMap[""]
    
  • константа
    const x int = 0
    var p = &x
    
→ Ссылка