Как сказано в спецификации Go, набор методов типа T
состоит из всех методов
с типом приемника T
, в то время как соответствующий указатель типа *T
состоит из всех методов с получателем *T
или T
. Это означает, что набор методов *T
включает в себя T
, но не наоборот.
Это различие возникает потому, что если значение интерфейса содержит указатель *T
, вызов метода может получить значение путем разыменования указателя, но если значение интерфейса содержит значение T
, для вызова метода нет безопасного способа получить указатель. (Это позволило бы методу изменить содержимое значения внутри интерфейса, что не разрешено спецификацией языка.)
Даже в тех случаях, когда компилятор может взять адрес значения чтобы перейти к методу, если метод изменяет значение, изменение будет потеряно у вызывающего. Например, если метод Write
из bytes.Buffer
использовал получатель значения, а не указатель, этот код:
var buf bytes.Buffer
io.Copy(buf, os.Stdin)
будет копировать стандартный ввод в копию buf
, а не в сам buf
. Это почти никогда не является ожидаемым поведением.
Читайте также:
Комментариев нет:
Отправить комментарий