function - qué - explicar la diferencia entre función y método.
¿Cuál es la diferencia de funciones y métodos en Go? (3)
Por lo que entiendo en este momento: las funciones son "globales", lo que significa que no tengo que importar un paquete para usar funciones, siempre están ahí. Los métodos están vinculados a paquetes. ¿Es esto correcto?
No, eso no es correcto. Solo hay un par de funciones del paquete builtin que están siempre disponibles. Todo lo demás necesita ser importado.
El término "método" surgió con programación orientada a objetos. En un lenguaje OOP (como C ++ por ejemplo) puede definir una "clase" que encapsula datos y funciones que pertenecen juntas. Esas funciones dentro de una clase se llaman "métodos" y se necesita una instancia de esa clase para llamar a dicho método.
En Go, la terminología es básicamente la misma, aunque Go no es un lenguaje OOP en el significado clásico. En Go, una función que toma un receptor generalmente se llama método (probablemente solo porque las personas todavía están acostumbradas a la terminología de OOP).
Así por ejemplo:
func MyFunction(a, b int) int {
return a + b
}
// Usage:
// MyFunction(1, 2)
pero
type MyInteger int
func (a MyInteger) MyMethod(b int) int {
return a + b
}
// Usage:
// var x MyInteger = 1
// x.MyMethod(2)
Estoy tratando de comenzar con Go y la documentación es muy buena. Lo que no encontré en la documentación es la diferencia entre funciones y métodos.
Por lo que entiendo en este momento: las funciones son "globales", lo que significa que no tengo que importar un paquete para usar funciones, siempre están ahí. Los métodos están vinculados a paquetes. ¿Es esto correcto?
La respuesta de Tux es genial, pero quiero aumentarla con el uso de los métodos de Go con struct
s (porque aquí es donde lo usé a menudo). Asumamos que quieres construir algo para calcular varios métodos en triángulos. Comienzas con una struct
:
type Triangle struct {
a, b, c float64
}
y luego le gustaría agregar algunas funciones para calcular el perímetro y el cuadrado:
func valid(t *Triangle) error {
if t.a + t.b > t.c && t.a + t.c > t.b && t.b + t.c > t.a {
return nil
}
return errors.New("Triangle is not valid")
}
func perimeter(t *Triangle) (float64, error) {
err := valid(t)
if err != nil {
return -1, err
}
return t.a + t.b + t.c, nil
}
func square(t *Triangle) (float64, error) {
p, err := perimeter(t)
if err != nil {
return -1, err
}
p /= 2
s := p * (p - t.a) * (p - t.b) * (p - t.c)
return math.Sqrt(s), nil
}
Y ahora tienes tu programa de trabajo Go Playground . En este caso, su función toma un parámetro (puntero a un triángulo) y hace algo. En la palabra OOP las personas pueden haber creado una clase y luego agregar métodos. Podemos ver nuestra estructura como clase de clase con campos y ahora agregamos métodos:
func (t *Triangle) valid() error {
if t.a + t.b > t.c && t.a + t.c > t.b && t.b + t.c > t.a {
return nil
}
return errors.New("Triangle is not valid")
}
func (t *Triangle) perimeter() (float64, error) {
err := t.valid()
if err != nil {
return -1, err
}
return t.a + t.b + t.c, nil
}
func (t *Triangle) square() (float64, error) {
p, err := t.perimeter()
if err != nil {
return -1, err
}
p /= 2
s := p * (p - t.a) * (p - t.b) * (p - t.c)
return math.Sqrt(s), nil
}
y tenemos un ejemplo completamente funcional .
Tenga en cuenta que realmente se parece a un método para objetos.
Se explican en detalle aquí - https://anil.cloud/2017/01/26/golang-functions-methods-simplified/
Una función en Go sigue la sintaxis:
func FunctionName(Parameters...) ReturnTypes...
Ejemplo:
func add(x int, y int) int
Ejecutar:
add(2,3)
Un método es como una función, pero unido a un tipo (llamado como receptor). La guía oficial establece "Un método es una función con un argumento de receptor especial". El receptor aparece entre la palabra clave func y el nombre del método. La sintaxis de un método es:
func (t ReceiverType) FunctionName(Parameters...) ReturnTypes...
Ejemplo:
func (t MyType) add(int x, int y) int
Ejecutar:
type MyType string
t1 := MyType("sample")
t1.add(1,2)
Ahora vamos a traer punteros a la mesa. Go lang es pasar por valor, significa que se pasan nuevas copias de los parámetros a cada llamada de función / método. Para pasarlos por referencia, puede usar punteros.
Sintaxis de la función con puntero en argumento / lista de parámetros.
func FunctionName(*Pointers...,Parameters...) ReturnTypes...
Ejemplo
func add(t *MyType, x int, y int) int
Ejecutar:
type MyType string
t1 := MyType("sample")
add(&t1,4,5)
De forma similar para los métodos, el tipo de receptor puede ser un puntero. Sintaxis del método con puntero (como receptor)
func (*Pointer) FunctionName(Parameters...) ReturnTypes...
Ejemplo
func (t *MyType) add(x int, y int) int
Ejecutar:
type MyType string
t1 := MyType("sample")
t1.add(2,3)
Tenga en cuenta que aún podemos escribir t1.add () para ejecutar el método con un receptor de puntero (incluso aunque ''t1'' no sea un puntero) y Go lo interpretará como (& t1) .add (). De forma similar, un método con un receptor de valores también se puede llamar usando el puntero, Go interpretará p.add () como as (* p) .add () en ese caso (donde ''p'' es un puntero). Esto es aplicable solo para métodos y no para funciones.
Los métodos con receptor de puntero son muy útiles para obtener un comportamiento similar al de "Java" en el que el método realmente está modificando el valor al que apunta el receptor y no en una copia del mismo.