Начиная с кода вроде:
type Foo struct {
V bool
}
func (f Foo) bar() bool {
return f.V
}
Можно ли изменить на func (f *Foo) bar() bool без увеличения основного номера версии? То есть, если вы знаете, что с вашим типом нет проблем с безопасностью потоков. Если да, то обратное изменение тоже разрешено, верно?
Насколько я могу судить, любой код, вызывающий функцию, независимо от того, является ли переменная значением или указателем, будет продолжать компилироваться и работать должным образом после обоих изменений.
Спасибо! Я думаю, что это ответ, это несовместимо с внесением этого изменения. Я полагаю, что пункт 4 в ответе на этот вопрос также означает, что он изменит тип (указатель или значение), удовлетворяющий любым интерфейсам, для которых у него есть методы, поэтому я полагаю, что это делает обратное изменение несовместимым, если оно удовлетворяет любым интерфейсам (и вы не можете гарантировать, что это не так).
К счастью, я проверил его, и в любом случае не имеет значения скорость, является ли мой тип указателем или значением.
@Британцы, не могли бы вы добавить это ответ, чтобы я мог его принять?

Если для типа Foo у вас есть метод с приемником значения:
func (f Foo) Method() {...}
Затем этот метод определяется как для Foo, так и для *Foo, и в обоих случаях метод получает копию экземпляра Foo. Если вы измените это на:
func (f *Foo) Method() {...}
тогда Foo.Method доступен только для *Foo, а не для Foo. Таким образом, такое изменение может вызвать ошибки компиляции.
Если у вас есть метод, объявленный с приемником указателя, и теперь вы меняете его на приемник значения, вы объявляете метод как для Foo, так и для *Foo, поэтому у вас не должно быть ошибок компиляции. Семантика метода также изменится, потому что теперь Method будет получать копию экземпляра Foo, даже если этот экземпляр адресный или является указателем.
Я протестировал его, и он компилируется для использования переменной-указателя с получателем значения: go.dev/play/p/pKwO7oA39w7 Я думал, что это не сработает, пока тоже не проверил!
Согласно комментариям, этот ответ дает хорошее резюме T и *T типов получателей. Ниже приведено несколько примеров, когда изменение с func (f Foo) bar() bool на func (f *Foo) bar() bool нарушило бы существующий код.
Пример 1: T не адресуется (детская площадка):
type Foo struct {
V bool
}
func (f *Foo) bar() bool { // Change to `(f Foo)` and this will work
return f.V
}
func x() Foo {
return Foo{true}
}
func main() {
fmt.Printf("%v", x().bar())
}
Пример 2: Интерфейс (детская площадка):
type Foo struct {
V bool
}
func (f *Foo) bar() bool { // Change to `(f Foo)` and this will work
return f.V
}
type Fooer interface {
bar() bool
}
func main() {
var x Fooer
x = Foo{}
fmt.Println(x.bar())
}
это отвечает на ваш вопрос?. Вот пример, который ломается при изменении.