Los punteros son útiles por varias razones. Los punteros permiten controlar el diseño de la memoria (afecta la eficiencia de la memoria caché de la CPU). En Go podemos definir una estructura donde todos los miembros están en memoria contigua:
type Point struct {
x, y int
}
type LineSegment struct {
source, destination Point
}
En este caso, las Point
estructuras están incrustadas dentro de la LineSegment
estructura. Pero no siempre puede incrustar datos directamente. Si desea admitir estructuras como árboles binarios o listas vinculadas, debe admitir algún tipo de puntero.
type TreeNode {
value int
left *TreeNode
right *TreeNode
}
Java, Python, etc.no tienen este problema porque no le permite incrustar tipos compuestos, por lo que no es necesario diferenciar sintácticamente entre incrustación y apuntar.
Problemas con estructuras Swift / C # resueltos con punteros Go
Una posible alternativa para lograr lo mismo es diferenciar entre struct
y class
como lo hace C # y Swift. Pero esto tiene limitaciones. Aunque normalmente puede especificar que una función toma una estructura como inout
parámetro para evitar copiar la estructura, no le permite almacenar referencias (punteros) a estructuras. Esto significa que nunca puede tratar una estructura como un tipo de referencia cuando lo encuentra útil, por ejemplo, para crear un asignador de grupo (ver más abajo).
Asignador de memoria personalizado
Usando punteros también puede crear su propio asignador de grupo (esto está muy simplificado con muchas verificaciones eliminadas para mostrar el principio):
type TreeNode {
value int
left *TreeNode
right *TreeNode
nextFreeNode *TreeNode; // For memory allocation
}
var pool [1024]TreeNode
var firstFreeNode *TreeNode = &pool[0]
func poolAlloc() *TreeNode {
node := firstFreeNode
firstFreeNode = firstFreeNode.nextFreeNode
return node
}
func freeNode(node *TreeNode) {
node.nextFreeNode = firstFreeNode
firstFreeNode = node
}
Intercambia dos valores
Los punteros también le permiten implementar swap
. Eso es intercambiar los valores de dos variables:
func swap(a *int, b *int) {
temp := *a
*a = *b
*b = temp
}
Conclusión
Java nunca ha podido reemplazar por completo a C ++ para la programación de sistemas en lugares como Google, en parte porque el rendimiento no se puede ajustar en la misma medida debido a la falta de capacidad para controlar el diseño y el uso de la memoria (las fallas de caché afectan el rendimiento de manera significativa). Go ha tenido como objetivo reemplazar C ++ en muchas áreas y, por lo tanto, necesita admitir punteros.