que punteros puntero lenguaje declarar como arreglos aritmetica apuntadores pointers go interface

pointers - punteros - Confusión "<tipo> es puntero a la interfaz, no interfaz"



punteros void lenguaje c (2)

Entonces estás confundiendo dos conceptos aquí. Un puntero a una estructura y un puntero a una interfaz no son lo mismo. Una interfaz puede almacenar una estructura directamente o un puntero a una estructura. En el último caso, todavía usa la interfaz directamente, no un puntero a la interfaz. Por ejemplo:

type Fooer interface { Foo() } type Foo struct{} func (f Foo) Foo() {} func main() { var f1 Foo var f2 *Foo = &Foo{} DoFoo(f1) DoFoo(f2) } func DoFoo(f Fooer) { fmt.Printf("[%T] %+v/n", f, f) }

Salida:

[main.Foo] {} [*main.Foo] &{}

https://play.golang.org/p/BGV9d1-IRW

En ambos casos, la variable f en DoFoo es solo una interfaz, no un puntero a una interfaz. Sin embargo, cuando se almacena f2 , la interfaz tiene un puntero a una estructura Foo .

Los punteros a las interfaces casi nunca son útiles. De hecho, el tiempo de ejecución de Go se modificó específicamente algunas versiones para que ya no elimine automáticamente los punteros de interfaz (como lo hace para los punteros de estructura), para desalentar su uso. En la abrumadora mayoría de los casos, un puntero a una interfaz refleja un malentendido de cómo se supone que funcionan las interfaces.

Sin embargo, hay una limitación en las interfaces. Si pasa una estructura directamente a una interfaz, solo los métodos de valor de ese tipo (es decir, func (f Foo) Foo() , no func (f *Foo) Foo() ) pueden usarse para completar la interfaz. Esto se debe a que está almacenando una copia de la estructura original en la interfaz, por lo que los métodos de puntero tendrían efectos inesperados (es decir, no podrían alterar la estructura original). Por lo tanto, la regla general predeterminada es almacenar punteros a estructuras en interfaces , a menos que haya una razón convincente para no hacerlo.

Específicamente con su código, si cambia la firma de la función AddFilter a:

func (fp *FilterMap) AddFilter(f FilterInterface) uuid.UUID

Y la firma GetFilterByID para:

func (fp *FilterMap) GetFilterByID(i uuid.UUID) FilterInterface

Su código funcionará como se esperaba. fieldfilter es de tipo *FieldFilter , que llena completamente el tipo de interfaz AddFilter y, por lo tanto, AddFilter lo aceptará.

Aquí hay un par de buenas referencias para comprender cómo los métodos, los tipos y las interfaces funcionan e integran entre sí en Go:

Estimados compañeros desarrolladores,

Tengo este problema que me parece un poco extraño. Eche un vistazo a este fragmento de código:

package coreinterfaces type FilterInterface interface { Filter(s *string) bool } type FieldFilter struct { Key string Val string } func (ff *FieldFilter) Filter(s *string) bool { // Some code } type FilterMapInterface interface { AddFilter(f *FilterInterface) uuid.UUID RemoveFilter(i uuid.UUID) GetFilterByID(i uuid.UUID) *FilterInterface } type FilterMap struct { mutex sync.Mutex Filters map[uuid.UUID]FilterInterface } func (fp *FilterMap) AddFilter(f *FilterInterface) uuid.UUID { // Some code } func (fp *FilterMap) RemoveFilter(i uuid.UUID) { // Some code } func (fp *FilterMap) GetFilterByID(i uuid.UUID) *FilterInterface { // Some code }

En otro paquete, tengo el siguiente código:

func DoFilter() { fieldfilter := &coreinterfaces.FieldFilter{Key: "app", Val: "152511"} filtermap := &coreinterfaces.FilterMap{} _ = filtermap.AddFilter(fieldfilter) // <--- Exception is raised here }

El tiempo de ejecución no aceptará la línea mencionada porque

"no se puede usar fieldfilter (tipo * coreinterfaces.FieldFilter) como tipo * coreinterfaces.FilterInterface en argumento para fieldint.AddFilter: * coreinterfaces.FilterInterface es puntero a la interfaz, no a la interfaz"

Sin embargo, al cambiar el código a:

func DoBid() error { bs := string(b) var ifilterfield coreinterfaces.FilterInterface fieldfilter := &coreinterfaces.FieldFilter{Key: "app", Val: "152511"} ifilterfield = fieldfilter filtermap := &coreinterfaces.FilterMap{} _ = filtermap.AddFilter(&ifilterfield) }

Todo está bien y al depurar la aplicación realmente parece incluir

Estoy un poco confundido sobre este tema. Al mirar otras publicaciones de blog y subprocesos de desbordamiento de pila que discuten exactamente el mismo problema (por ejemplo, This o This ), el primer fragmento que genera esta excepción debería funcionar, porque tanto el filtro de campo como el mapa de campo se inicializan como punteros a las interfaces, en lugar del valor de interfaces No he podido entender lo que realmente sucede aquí que necesito cambiar para no declarar un FieldInterface y asignar la implementación para esa interfaz. Debe haber una forma elegante de hacer esto.


GetFilterByID(i uuid.UUID) *FilterInterface

Cuando recibo este error, generalmente es porque estoy especificando un puntero a una interfaz en lugar de una interfaz (que en realidad será un puntero a mi estructura que cumple la interfaz).

Hay un uso válido para * interface {...} pero más comúnmente solo estoy pensando ''esto es un puntero'' en lugar de ''esta es una interfaz que resulta ser un puntero en el código que estoy escribiendo''

Solo tirarlo allí porque la respuesta aceptada, aunque detallada, no me ayudó a solucionar el problema.