Go function with parameters instead of name?

Asked

Viewed 39 times

0

Hello, I would like to understand how functions work in the Go language, I made a code to assemble the data structure Stack and I came across two functions that in place of the name has a parentheses with parameters and soon after the name with other parentheses and your parameter, thank you!

Follow the code:

type Stack struct {
    items []int
}

func (s *Stack) Push(i int) {
    s.items = append(s.items, i)
}

func (s *Stack) Pop() int {
    l := len(s.items) - 1
    toRemove := s.items[l]
    s.items = s.items[:l]

    return toRemove
}
  • What specifically is the question?

1 answer

2


The question is a little confusing, but I think I’ve come to understand it. Your doubt seems to consist of:

type AlgumTipo struct {
}

func (t *AlgumTipo) UmaFuncao(argumento int) {
}

The function UmaFuncao seems to be what it describes as "functions that in place of the name have a parentheses with parameters and soon after the name with other parentheses and its parameter".


Unfortunately, I don’t know if I can explain.


What happens is that you can implement functions directly in their type (which can be either struct, or anything else).

Consider the two codes:

type Cliente struct {
    Username string
}

func (c *Cliente) Name(titulo string) string {
    return titulo + c.Username
}

You could also write as:

type Cliente struct {
    Username string
}

func Name(c *Cliente, titulo string) string {
    return titulo + c.Username
}

Then you could use (in the first case):

cliente := Client{Username:"Bob"}
fmt.Println(cliente.Name("Senhor, "))

// Resultado: Senhor, Bob

Translating the func (c *Cliente) Name(titulo string) string:

The (c *Cliente) defines the name of c for the Client struct. Allowing access to the type Cliente struct{}.

The Name() is the name of the function.

The titulo string is the input arguments/parameters for the function. Thus, defining the name of titulo for the variable that will receive (the string is the guy).

The string end is the function result type.


The (c *Cliente) is obtaining struct information from Cliente, or is it implements the type Cliente. How I created a struct with the name "Bob" when calling the Name(...) he read this information (using the c.Username). Besides, how does he use the *Cliente it is also able to modify the contents of the struct.

As in your case, when using:

func (s *Stack) Push(i int) {
    s.items = append(s.items, i)
}

You define the items of Stack current.

Note: be careful with parallel/concurrent accesses, if two functions change the same variable at the same time the program can literally crash! You can use the sync.Mutex and so on to prevent it, but that’s another matter.


One question you might have is why use (c *Cliente) Name(titulo string) string instead of creating a Name(c *cliente, titulo string) string? Among other factors, the main one is the use of Interface.

You can create a Interface as:

type Namer interface {
    Name(prefix string) string
}

That way, anything that implements such a function will be a Namer.

This is quite useful in some situations. For example io.Reader, the io.Reader is an interface (https://golang.org/pkg/io/#Reader):

type Reader interface {
    Read(p []byte) (n int, err error)
}

I mean, for example (but don’t use that), if you make a:

func (c *Cliente) Read(p []byte) (n int, err error) {
    n = copy(p, []byte(c.Username))
    return n, io.EOF
}

You will have implemented the io.Reader in the type Cliente struct{}.

  • Thank you very much for the explanation, I understood perfectly!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.