«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Могут ли методы Go с типом получателя «T» вызываться для переменных типа «*T»?

Могут ли методы Go с типом получателя «T» вызываться для переменных типа «*T»?

Опубликовано 22 декабря 2024 г.
Просматривать:674

Can Go Methods with Receiver Type `T` Be Called on Variables of Type `*T`?

Методы Go для типов указателей: вызов методов с приемником T для типа указателя *T

Вопрос:

Спецификация Go гласит, что набор методов типа указателя T включает в себя набор методов соответствующего типа T. это означает, что мы можем вызывать методы с получателем T для переменных типа T?

Ответ:

Хотя спецификация предполагает это, важно отметить что вы не можете напрямую вызывать методы *T на T. Вместо этого компилятор автоматически разыменовывает переменную на &T и вызывает метод, эффективно выполняя (&T).m().

Это поведение явно определено в спецификации Go:

"Вызовы: вызов метода x.m() допустим, если набор методов (тип ) x содержит m, и список аргументов может быть присвоен списку параметров m. Если x является адресным и набор методов &x содержит m, x.m() является сокращением для (&x).m(). "

Демонстрация:

Следующий пример иллюстрирует такое поведение:

package main

import (
    "fmt"
    "reflect"
)

type User struct{}

func (this *User) SayWat() {
    fmt.Println(reflect.TypeOf(this))
    fmt.Println("WAT\n")
}

func main() {
    var user = User{}

    fmt.Println(reflect.TypeOf(user))

    user.SayWat()
}

Несмотря на объявление метода SayWat с получателем *User, мы можем вызвать его для пользователя, который имеет тип User. Компилятор автоматически обрабатывает разыменование и вызывает (&user).SayWat().

Исключение:

Однако это применимо только к адресуемым переменным. Если вы попытаетесь вызвать метод указателя на неадресуемое значение, вы столкнетесь с ошибкой. Например:

func aUser() User {
    return User{}
}

...

aUser().SayWat() // Error: cannot call pointer method on aUser()
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3