Golang указатель приемник путаница - PullRequest
0 голосов
/ 12 июля 2019

Я недавно начал изучать Голанг для рабочего проекта.Я родом из «с», и у меня возникло некоторое недоумение по поводу технических характеристик приемников указателей в функциях.Должен ли я считать, что получатель обобщен, и ему все равно, является ли объект указателем или литералом, он переведет его в любой тип получателя.

Я знаю, что формулировка моего вопроса может сбивать с толку, поэтому здесьВот пример кода:

func (v *clients) makePtr() {
    (*v).slice = make([]client, 0)
    return
}

func (v clients) makeLit() []client {
    return make([]client, 0)
}

func main() {
    clsPtr := &clients{} // pointer
    clsLit := clients{}  // literal

    clsLit.makePtr() // literal with pointer reciever
    clsLit.makeLit() // literal with pointer reciever
    clsPtr.makePtr() // pointer with literal reciever
    clsPtr.makeLit() // pointer with pointer reciever
}

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

РЕДАКТИРОВАТЬ: Извиняюсь, ребята, возможно, я не смог прояснить вопросполучатель указателя используется для изменения объекта, но я более запутан в отношении синтаксиса, почему получатель указателя работает как для литерала, так и для указателя, так как он получает указатель, не должен ли он работать только с указателем?

Ответы [ 2 ]

1 голос
/ 12 июля 2019

Получатель указателя означает, что если вы измените объект в методе, он изменит базовую структуру.

Когда вы звоните, это не имеет значения.

package main

import (
    "fmt"
)

type data struct {
    val int
}

func (d data) changeNonPersistent(newval int) {
    d.val = newval
}

func (d *data) changePersistent(newval int) {
    d.val = newval
}

func main() {
    // initialize both ptr and val version to 5
    dptr := &data{val: 5}
    dval := data{val: 5}

    fmt.Println(*dptr)
    fmt.Println(dval)

    // non persistent val change to 10
    dptr.changeNonPersistent(10)
    dval.changeNonPersistent(10)

    fmt.Println("Non Persistent-")
    fmt.Println(*dptr)
    fmt.Println(dval)

    // persistent val change to 15
    dptr.changePersistent(15)
    dval.changePersistent(15)

    fmt.Println("Persistent-")
    fmt.Println(*dptr)
    fmt.Println(dval)
}

или смотрите код здесь https://play.golang.org/p/jwOUwsso3PZ

tl; dr;объект или ссылка не имеют значения, если получатель прав.

И вы обычно хотите иметь указатель приемника, только если ваша цель - мутировать.В противном случае просто отправьте копию.

0 голосов
/ 12 июля 2019

В golang это так называемые методы, которые работают с приемником. Аргумент получателя может быть передан по значению или по указателю.

Вы можете написать функции, подобные приведенным ниже, которые являются простыми функциями.

 type Client struct{}

//A pointer to Client    
func makePtr(c *Client){
    //do something with c
}

//A copy of client is made.
func makeLit(cs Client){
    //do something with c
}

Вместо этого, если вы пишете методы, это дает связь со структурой.

type Client struct{}

func (c *Client) makePtr(){
    //do something with c
}

//A copy of client is made.
func (c Client)makeLit(){
    //do something with c
}

Основное назначение методов, которые я вижу в golang, - для реализации интерфейса Именно в силу методов структуры реализуют (или удовлетворяют) интерфейсы.

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