What is the point of having pointers in Go?

I know that pointers in Go allow mutations of function arguments, but it would not be easier if they only accepted references (with corresponding constant or mutable qualifiers). Now we have pointers, and for some built-in types, such as maps and channels, an implicit pass by reference.

Am I missing something or pointers in Go is just an unnecessary complication?

+64
pointers go
Dec 07 '09 at 22:47
source share
4 answers

References cannot be reassigned, while pointers can. This in itself makes links useful in many situations where links cannot be used.

+34
Dec 07 '09 at 23:05
source share

I really like the example from http://www.golang-book.com/8

func zero(x int) { x = 0 } func main() { x := 5 zero(x) fmt.Println(x) // x is still 5 } 

Unlike

 func zero(xPtr *int) { *xPtr = 0 } func main() { x := 5 zero(&x) fmt.Println(x) // x is 0 } 
+31
May 05 '13 at 20:57
source share

Go is designed to be a concise, minimalistic language. Therefore, it began with simple values ​​and pointers. Later, as necessary, some reference types (fragments, maps, and channels) were added.




Go programming language: Language Design FAQ: Why are references to maps, fragments and channels while arrays are values?

"This topic has a lot of history. Previously, maps and channels were syntactically pointers, and it was impossible to declare or use an instance of a non-pointer. In addition, we struggled with how arrays should work. In the end, we decided that there was a strict separation of pointers and values difficult to use the language. Introducing reference types, including slices for handling the reference form of arrays, solved these problems. Link types add some sad complexity to the language, but they have a big impact on usability: When they were introduced, Go has become a more productive and convenient language. "




Fast compilation is the main goal of Go programming language design; which has its costs. One of the victims is the ability to mark variables (with the exception of basic compile-time constants) and parameters as immutable. He was requested, but rejected.




golang-nuts: go language. Some reviews and doubts.

"Adding const to the type system makes it appear everywhere and makes it delete it everywhere if something changes. Although there might be some benefit to designating objects that are immutable in some way, we don’t think that a const type specifier should go." .

+23
Dec 08 '09 at 1:47
source share

Pointers are useful for several reasons. Pointers allow you to control the layout of the memory (affects the efficiency of the processor cache). In Go, we can define a structure in which all members are in contiguous memory:

 type Point struct { x, y int } type LineSegment struct { source, destination Point } 

In this case, Point structures are embedded in the LineSegment structure. But you cannot always directly insert data. If you want to support structures such as binary trees or a linked list, then you need to maintain some kind of pointer.

 type TreeNode { value int left *TreeNode right *TreeNode } 

Java, Python, etc. do not have this problem, because they do not allow the insertion of composite types, so there is no need to syntactically distinguish between nesting and guidance.

Problems with Swift / C # Structures Solved with Go Pointers

A possible alternative to doing this is to distinguish between struct and class like C # and Swift. But this has limitations. Although you can usually indicate that a function takes a structure as an inout to avoid copying the structure, it does not allow you to store references (pointers) to structures. This means that you can never consider a structure as a reference type when you find it useful, for example, to create a pool allocator (see below).

Custom memory block

Using pointers, you can also create your own pool allocator (this is very simplified with a lot of checks removed to just show the principle):

 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 } 

Change two values

Pointers also allow you to implement swap . This replaces the values ​​of two variables:

 func swap(a *int, b *int) { temp := *a *a = *b *b = temp } 

Conclusion

Java has never been able to completely replace C ++ for system programming in places like Google, partly because performance cannot be tuned to the same degree due to the inability to control layout and memory usage (cache misses affect performance significantly). Go aims to replace C ++ in many areas and therefore must support pointers.

+23
Mar 24 '14 at 21:29
source share



All Articles