This is the first blog of the author. The author has been developing and learning the algorithm by practicing Java and getting through the technology stack of the server side, but man is not as good as god. The intention of the school recruitment is Golang engineer. The learning cost of Java programmers to Go is still larger, especially for most Of the Java background to Go colleagues, Pointers is the first difficulty.
Without complication, a pointer is a simple variable, except that its value represents an address in memory that may have other variables or structures on it, and that’s all. Is the only special dolls logic: a pointer is a variable, so it also need an address in memory to store, which means that the pointer is a pointer, so accordingly, as a result of the existence of pointer, any variable value is a kind of operation: & var, said access to the variable where the address, or the variable of pointer value; For pointer variables, there is an additional * PTR operation to get the value it represents, that is, the variable or structure at the corresponding address.
After understanding Pointers, I think there are probably some Java programmers who have the same confusion as me. Java doesn’t have this thing and I can use it quite well. So what is it really useful for?
public class Test { public static void main(String[] args) { int i = 0; onePlus(i); System.out.println(i); } static void onePlus(int i) { i += 1; }}Copy the code
As the code shows, I’m going to increment the value of variable I in the function call by 1, but everyone knows that the output I is still 0. As for the reason, a bit of familiarity with the JVM can explain it, but if I want to satisfy my needs, I need to return the computed value and reassign I. In fact, the GO code will produce the same result, not to mention.
But for programmers who have used Pointers, they don’t like the idea of returning a reassignment and want our function call to pass in the variable we want to move, not a copy of it (the value passes the result). To do this, use a pointer as follows:
package main
import "fmt"
func main(){
var i = 1
onePlus(&i)
fmt.Println(i)
}
func onePlus(ptr *int){
*ptr+=1
}
Copy the code
After experiencing the effect of Pointers, in fact, if you think deeply about the problem, the effect of Pointers and assignment, reference have a lot to do. In fact, Java rules are very simple and clear: all variables are only divided into two types: simple type and reference type. When assigning value, simple type is value transfer, and reference type is address transfer; This is exactly the same as the == operation: simple types compare values and reference types compare addresses, so we must be familiar with the difference between the two sets of code:
public static void main(String[] args) {
int i = 0;
int j = i;
j++;
System.out.println(i);
}
Copy the code
public static void main(String[] args) {
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;
arr2[0] = 0;
System.out.println(Arrays.toString(arr1));
}
Copy the code
The second block of code, if interpreted from the JVM, is that the values of two variables in the local variable table on the stack frame are actually the same block address value, pointing to a unique array in the heap. If you have to think about Pointers in Java, it seems that no one cares about the address of the local variable table in the virtual machine stack… So in summary Java assignments, comparisons, and function calls are the same, and we have no doubt about the result of code like this:
public class Test { public static void main(String[] args) { int[] arr = {1, 2, 3}; test(arr); System.out.println(Arrays.toString(arr)); } static void test(int[] arr) { arr[0] = 1; }}Copy the code
If you think that’s the end of it, the trouble is just beginning… If you were to write the above Java code again with the Go code, you would be surprised to find that the function call failed to modify the array. The reason isn’t that hard to find: Unlike Java’s definition of Arrays extends Object, Go considers Arrays to be a value type. So I wondered if I could use Pointers to solve this problem, like adding one to I by *ptr++.
package main import "fmt" func main() { arr := [3]int{1, 2, Println (arr)} func test(PTR *[3]int){// PTR [0] = 0 // (* PTR) [0] = 0 // var nums = * PTR // nums[0] = 0}Copy the code
This is one difference between Go and Java.
In Go, a data structure very similar to an array is Slice, but a Slice is essentially a structure, that is, a reference type rather than a value type, which means that its variable is not the Slice itself but points to it, or that its value is the address value where the Slice itself can be found. So, if you want to modify the slice using a function call, you don’t even need a pointer, just the structure itself.
However, does this mean that the Go language has both value passing (which is itself a copy) and reference passing (where no copy occurs)? No, the only way to pass a value in Go is to pass a value. Even if you pass a variable that refers to a body, the pass to a function call is not really the same variable you passed (you can use “%p” &slice to check both addresses), but they both have the same value. All point to the same structure (&slice[0]).
Conclusion:
- Pointer concepts and applications
- The difference between The array structure in Java and Go and the understanding of assignment operations
- Commonalities and differences between value types and reference types when making function calls in Go