Если функция копирует элемент слайса в переменную, работает ли она с указателем на этот элемент или с копией? - PullRequest
0 голосов
/ 02 мая 2019

Пример ситуации:

Есть глобальная структура, содержащая фрагмент структур.

type stctUser struct {
    user string
    privilege int
    created time.Time
}

type stctAllUsers struct {
    sync.RWMutex
    slcUsers []stctUser
}
var strctAllUsers stctAllUsers

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

var strctUserTemp stctUser
strctAllUsers.RLock
for a := range strctAllUsers.slcUsers {
    if tmpName == strctAllUsers.slcUsers[a].user {
        strctUserTemp = strctAllUsers.slcUsers[a]
        break
    }
}
strctAllUsers.RUnlock

Работает ли strctUserTemp с отдельной копией slcUsers [a], или это указатель на этот элемент слайса?Например, strctAllUsers.slcUsers [a] равен "Tom" и, если изменить strctUserTemp.user = "Bob", strctAllUsers.slcUsers [a] все равно будет Tom?

(Раньше кажется, что при создании копиифрагмент новой переменной будет означать, что изменения этой новой переменной могут изменить оригинал ... поэтому он назначил указатель вместо создания копии. Или я неправильно запомнил?)

Обновление: видя, как я былслишком глупо, чтобы потратить пять минут, чтобы проверить это ... вот ссылка на поведение, которое заставило меня в первую очередь подвергнуть сомнению это, и я хотел уточнить реализацию, прежде чем предположить, что я понимаю, что происходит, и создать ошибку в реальномвещи, над которыми я работал.https://play.golang.org/p/ndmJ0h1z-sT

1 Ответ

4 голосов
/ 02 мая 2019

Самое главное: назначение всегда копирует .Однако это может быть копия указателя.

Существует три основных сценария:

  1. У вас есть фрагмент значений.Вы назначаете элемент из среза локальной переменной, создавая копию значения.Нет связи между локальной переменной и элементом слайса.
  2. У вас есть слайс указателей.Вы назначаете элемент из среза локальной переменной, создавая копию указателя.Изменения в указанном значении будут отражены при любом другом использовании элемента слайса, поскольку локальный указатель и указатель в слайсе указывают на одну и ту же память.
  3. У вас есть слайс значений.Вы присваиваете ссылку на элемент из среза локальной переменной (например, myVar := &mySlice[0]).Локальная переменная содержит копию ссылки, созданной выражением адресации.Изменения в значении локальной переменной отражаются при любом другом использовании элемента slice, поскольку локальный указатель указывает непосредственно на память, в которой хранится этот элемент slice.

Обратите внимание, что последний параметр означает, что вы 'будет иметь хрупкий указатель - если вы добавите к срезу, а базовый массив перемещается в памяти, вы получите некоторое запутанное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...