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{}
.
What specifically is the question?
– Inkeliz