usar tipos programacion lenguaje las implementan funciones funcion estandar como características basicas argumentos concurrency go channels pass-by-reference

concurrency - tipos - Son canales pasados por referencia implícitamente



funciones estandar en programacion c (4)

Las variables de canal son referencias, pero depende de su definición de ''referencia''. La especificación del lenguaje nunca menciona tipos de referencia.

Ningún canal (variable) se ''modifica'' en la función sum . El envío a un canal cambia su estado.

En otras palabras, sí, el canal se implementa como un puntero a alguna estructura de tiempo de ejecución. Tenga en cuenta que eso es estrictamente necesario para la semántica de referencia.

EDITAR: La oración anterior estaba destinada a decir: "Tenga en cuenta que eso no es estrictamente necesario para la semántica de referencia", es decir. la palabra "no" fue MIA. Perdón por cualquier confusión eventualmente creada.

The go tour tiene este ejemplo para los canales: https://tour.golang.org/concurrency/2

package main import "fmt" func sum(a []int, c chan int) { sum := 0 for _, v := range a { sum += v } c <- sum // send sum to c } func main() { a := []int{7, 2, 8, -9, 4, 0} c := make(chan int) go sum(a[:len(a)/2], c) go sum(a[len(a)/2:], c) x, y := <-c, <-c // receive from c fmt.Println(x, y, x+y) }

El canal c se modifica en la función suma y los cambios persisten después de que la función ha terminado. Obviamente, c se pasó por referencia pero no se creó ningún puntero a c. ¿Los canales se pasan implícitamente por referencia en go?


Se podría decir que sí, pero decir "El canal c se modifica en la función suma" no es realmente la terminología correcta. Los envíos y recepciones de canales realmente no se consideran modificaciones.

Tenga en cuenta que las divisiones y los mapas se comportan de forma similar; consulte http://golang.org/doc/effective_go.html para obtener más detalles.

También "pasado por referencia" implica que se podría hacer una asignación a c en sum que cambiaría su valor (en oposición a sus datos subyacentes) fuera de la suma, lo que no es el caso.


Todo en Go se pasa y se asigna por valor. Ciertos tipos incorporados, incluidos los tipos de canales y los tipos de mapas, se comportan como indicadores opacos de alguna estructura interna oculta. Y es posible modificar esa estructura interna por operaciones en el canal o mapa. Comienzan como nil , que es análogo al puntero nil .


Técnicamente están copiados, porque cuando usas make , estás asignando algo en el montón, por lo que técnicamente es un puntero detrás de las escenas. Pero el tipo de puntero no está expuesto, por lo que se puede considerar como un tipo de referencia.

EDITAR : Desde la especificación:

La función incorporada make toma un tipo T, que debe ser un sector, un mapa o un tipo de canal, seguido opcionalmente por una lista de expresiones específica del tipo. Devuelve un valor de tipo T (no * T). La memoria se inicializa como se describe en la sección de valores iniciales.

Un canal debe inicializarse antes de poder usarse. Make hace esto, por lo que puede usarse como un tipo de referencia.

Lo que esto significa básicamente es que puedes pasarlo a una función y escribir o leer en él. La regla general es que si usa make , new o & , puede pasarlo a otra función sin copiar los datos subyacentes.

Entonces, los siguientes son tipos de "referencia":

  • rodajas
  • mapas
  • canales
  • punteros
  • funciones

Solo los tipos de datos (números, bools y structs, etc.) se copian al pasar a una función. Las cadenas son especiales, porque son inmutables, pero no pasan por valor. Esto significa que lo siguiente no funcionará como se esperaba:

type A struct { b int } func f(a A) { a.b = 3 } func main() { s := A{} f(s) println(s.b) // prints 0 }