Skip to content

Указатели в Go: преобразование в произвольный тип, их сравнение, присвоение значения

Можно ли значение указателя преобразовать в произвольный тип указателя? (спойлер: нет)

В Go значение указателя типа T1 может быть напрямую и явно преобразовано в другой тип указателя T2, только если выполняется любое из следующих двух условий.

  1. Базовые типы типа T1 и T2 идентичны (игнорируя теги структуры), в частности, если один из типов T1 и T2 является безымянным типом, а их базовые типы идентичны (с учетом тегов структуры), то преобразование может быть неявным.

  2. Type T1 и T2 являются безымянными типами указателей, и базовые типы их базовых типов идентичны (игнорируя теги структуры).

Например, для показанных ниже типов указателей:

существуют следующие факты:

  1. Значения типа *int64 могут быть неявно преобразованы в тип Ta и наоборот, поскольку их базовые типы оба являются *int64.

  2. Значения типа *MyInt могут быть неявно преобразованы в тип Tb и наоборот, поскольку их базовые типы оба являются *MyInt.

  3. Значения типа *MyInt могут быть явно преобразованы в тип *int64 и наоборот, поскольку они оба безымянны, а базовые типы их базовых типов оба являются типами int64.

  4. Значения type Ta не могут быть напрямую преобразованы в тип Tb, даже явно. Однако, согласно только что перечисленным первым трем фактам, значение pa типа Ta может быть косвенно преобразовано в тип Tb путем вложения трех явных преобразований, Tb((*MyInt)((*int64)(pa))).

Никакие значения этих типов указателей не могут быть преобразованы в тип *uint64 любым безопасным способом.

Можно ли значение указателя сравнивать со значениями произвольного типа указателя? (спойлер: снова нет)

В Go указатели можно сравнить с операторами \== и !\=. Два значения указателя Go можно сравнивать только в том случае, если выполняется любое из следующих трех условий:

  1. Типы двух указателей Go идентичны.

  2. Одно значение указателя может быть неявно преобразовано в тип указателя другого (type casting). Базовые типы двух типов должны быть идентичными, и любой из двух типов двух указателей Go является безымянным.

  3. Только один из двух указателей представлен голым (нетипизированным) nil идентификатором.

Пример указан на скриншоте.

Можно ли значение указателя присвоить значениям указателя других типов указателя? (спойлер: опять нет)

Условия для присвоения значения указателя другому значению указателя аналогичны условиям для сравнения значения указателя с другим значением указателя, которые перечислены выше.