name oop constructor go

oop - name - Constructores en Go



groovy get class name string (7)

En realidad, hay dos mejores prácticas aceptadas:

  1. Haga que el valor cero de su estructura sea un valor predeterminado razonable. (Si bien esto parece extraño para la mayoría de las personas que provienen de los productos "tradicionales", a menudo funciona y es realmente conveniente).
  2. Proporcione una función func New() YourTyp o si tiene varios de esos tipos en las funciones de su paquete func NewYourType1() YourType1 y así sucesivamente.

Documente si un valor cero de su tipo es utilizable o no (en cuyo caso tiene que ser configurado por una de las funciones New... (Para los "tradicionalistas" ¡Vaya! Alguien que no lea la documentación no lo hará). podrá usar sus tipos correctamente, incluso si no puede crear objetos en estados indefinidos).

Tengo una estructura y me gustaría que se inicialice con algunos valores predeterminados razonables.

Normalmente, lo que hay que hacer aquí es usar un constructor, pero como go no es realmente OOP en el sentido tradicional, estos no son objetos verdaderos y no tiene constructores.

Me di cuenta del método init, pero eso está en el nivel del paquete. ¿Hay algo más similar que se pueda usar en el nivel de estructura?

Si no, ¿cuál es la mejor práctica aceptada para este tipo de cosas en Go?


Golang no es un lenguaje OOP en sus documentos oficiales. Todos los campos de la estructura de Golang tienen un valor determinado (no como c / c ++), por lo que la función del constructor no es tan necesaria como cpp. Si necesita asignar algunos campos a algunos valores especiales, use las funciones de fábrica. La comunidad de Golang sugiere nuevos nombres de patrones.


Hay algunos equivalentes de constructores para cuando los valores cero no pueden hacer valores predeterminados razonables o para cuando algún parámetro es necesario para la inicialización de la estructura.

Supongamos que tiene una estructura como esta:

type Thing struct { Name string Num int }

entonces, si los valores cero no son adecuados, normalmente construiría una instancia con una función NewThing que devuelva un puntero:

func NewThing(someParameter string) *Thing { p := new(Thing) p.Name = someParameter p.Num = 33 // <- a very sensible default value return p }

Cuando su estructura es lo suficientemente simple, puede usar esta construcción condensada:

func NewThing(someParameter string) *Thing { return &Thing{someParameter, 33} }

Si no desea devolver un puntero, una práctica es llamar a la función makeThing lugar de NewThing :

func makeThing(name string) Thing { return Thing{name, 33} }

Referencia: Asignación con nuevo en Go Efectivo .


Ir tiene objetos. Los objetos pueden tener constructores (aunque no constructores automáticos). Y, por último, Go es un lenguaje OOP (los tipos de datos tienen métodos adjuntos, pero hay infinitas definiciones de lo que es OOP).

Sin embargo, la mejor práctica aceptada es escribir cero o más constructores para sus tipos.

Como @dystroy publicó su respuesta antes de terminar esta respuesta, permítanme agregar una versión alternativa de su constructor de ejemplo, que probablemente escribiría en su lugar como:

func NewThing(someParameter string) *Thing { return &Thing{someParameter, 33} // <- 33: a very sensible default value }

La razón por la que quiero mostrarle esta versión es que muy a menudo se pueden usar literales "en línea" en lugar de una llamada de "constructor".

a := NewThing("foo") b := &Thing{"foo", 33}

Ahora *a == *b .


Me gusta la explicación de esta publicación de blog :

La función Nuevo es una convención de Go para paquetes que crean un tipo de núcleo o diferentes tipos para que los use el desarrollador de la aplicación. La función Nuevo es una convención de Go para paquetes que crean un tipo de núcleo o diferentes tipos para que los use el desarrollador de la aplicación. Mira cómo se define e implementa New en log.go, bufio.go y cypto.go:

log.go

// New creates a new Logger. The out variable sets the // destination to which log data will be written. // The prefix appears at the beginning of each generated log line. // The flag argument defines the logging properties. func New(out io.Writer, prefix string, flag int) * Logger { return &Logger{out: out, prefix: prefix, flag: flag} }

bufio.go

// NewReader returns a new Reader whose buffer has the default size. func NewReader(rd io.Reader) * Reader { return NewReaderSize(rd, defaultBufSize) }

crypto.go

// New returns a new hash.Hash calculating the given hash function. New panics // if the hash function is not linked into the binary. func (h Hash) New() hash.Hash { if h > 0 && h < maxHash { f := hashes[h] if f != nil { return f() } } panic("crypto: requested hash function is unavailable") }

Como cada paquete actúa como un espacio de nombre, cada paquete puede tener su propia versión de Nuevo. En bufio.go se pueden crear múltiples tipos, por lo que no hay una nueva función independiente. Aquí encontrará funciones como NewReader y NewWriter.


No hay constructores por defecto en Go, pero puede declarar métodos para cualquier tipo. Puede hacer que sea un hábito declarar un método llamado "Init". No estoy seguro de cómo se relaciona esto con las mejores prácticas, pero ayuda a mantener los nombres cortos sin perder claridad.

package main import "fmt" type Thing struct { Name string Num int } func (t *Thing) Init(name string, num int) { t.Name = name t.Num = num } func main() { t := new(Thing) t.Init("Hello", 5) fmt.Printf("%s: %d/n", t.Name, t.Num) }

El resultado es:

Hello: 5


otra forma es;

package person type Person struct { Name string Old int } func New(name string, old int) *Person { // set only specific field value with field key return &Person{ Name: name, } }