pointers go slice

pointers - Cortar un puntero de corte pasado como argumento



go slice (1)

Tengo el siguiente código:

func main() { var buf []byte{1, 2, 3, 4, 5} buf = buf[2:] fmt.Println(buf) panic(1) }

Sin embargo, quiero pasar un puntero al segmento de bytes de buf a otra función, y cortarlo allí, así que algo así como:

func main() { var buf []byte{1, 2, 3, 4, 5} sliceArr(&buf, 2) fmt.Println(buf) panic(1) } func sliceArr(buf *[]byte, i int) { *buf = *buf[i:] }

Me da un error que no puedo usar el tipo []byte como tipo *[]byte en argumento para la función sliceArr() , y que no puedo cortar el tipo *[]byte . Que pasa ¿Las rebanadas no se pasan por referencia por defecto? Intenté hacer esto sin un puntero, pero no funciona: la matriz se está copiando. ¿Cómo puedo hacer esto?


El error cannot use type []byte as type *[]byte in argument to sliceArr() proviene de un error tipográfico que no ha publicado (intentó pasar un segmento y no un puntero a un segmento a sliceArr() ).

En cuanto al otro error ( cannot slice type *[]byte ), solo necesita usar paréntesis para agrupar la referencia del puntero:

*buf = (*buf)[i:]

Y accidentalmente omitió un signo = de la declaración de variable. Aparte de eso, todo funciona como lo escribiste:

func main() { var buf = []byte{1, 2, 3, 4, 5} sliceArr(&buf, 2) fmt.Println(buf) } func sliceArr(buf *[]byte, i int) { *buf = (*buf)[i:] }

Salida (pruébalo en Go Playground ):

[3 4 5]

Nota:

Tenga en cuenta que la especificación establece que si p es un puntero a una matriz , p[low:high] es la abreviatura de (*p)[low:high] , es decir, el puntero se desreferencia automáticamente para usted. Esto no sucede automáticamente si p es un puntero a un segmento , p[low:high] no es válido ya que no puede cortar un puntero. Por lo tanto, debe desreferenciar el puntero manualmente en caso de punteros a sectores.

La razón de esta desviación es que un puntero a un segmento es muy raro ya que los segmentos ya son descriptores "justos" (a una parte contigua de una matriz subyacente), y los segmentos se pasan sin un puntero la mayor parte del tiempo, así que si es raro caso (como este) necesita pasar un puntero, debe ser explícito sobre cómo manejarlo. Las matrices, por otro lado, representan todos los elementos; asignar o pasar matrices copia todos los valores, por lo que es mucho más común usar punteros a matrices (que punteros a sectores); por lo tanto, se justifica tener más soporte de lenguaje para trabajar con punteros de matriz.

También tenga en cuenta que su tarea podría lograrse requiriendo solo un segmento (sin puntero) como tipo de parámetro y devolviendo el nuevo valor de segmento, que por supuesto debe asignarse a la persona que llama (un buen ejemplo de esto es la función incorporada append() )

Nota 2:

Si el tipo de parámetro es un segmento (y no un puntero a un segmento), y pasa un segmento, la matriz subyacente no se copia, solo el encabezado del segmento. Pero en este caso, si corta el argumento (que es una copia del encabezado del corte) y asigna de nuevo el nuevo corte (encabezado del corte) al argumento, simplemente está cambiando el valor del parámetro (una variable local) y no el valor original (variable) que se pasó, es por eso que no funcionará.

Lea las siguientes publicaciones de blog para obtener más detalles sobre los sectores:

Go Slices: uso y aspectos internos

Arreglos, cortes (y cadenas): la mecánica de ''agregar''