The language golang is similar to languages such as java and c#, and is quite different from c/c++. It has an automatic memory management mechanism, which saves you worry and effort.
However, if you write golang really according to the habit of writing Java, it is easy to have problems, because golang has the concept of pointers. Although this pointer is an automated version of c/c++, it also has the characteristics of pointers. If you are not familiar with the principles, the written program will not have a running bug, but its performance is not friendly.
Therefore, you cannot write golang completely based on the idea of writing Java, and you must pay attention to the differences.
We know that in Java, except for basic types, all variable types are reference types. You can pass the reference as a parameter at will, or return the reference as a return value, without any problems.
public class Main { static class Person{ private String name; private String addr; private int age; public void addAge() { age ++; } } private static Person addAge(Person person) { (); return person;//You can return like this, no problem } public static void main(String[] args){ Person person = new Person(); addAge(person);//You can call this, no problem } }
If you haven't written c/c++, you will feel that all this seems so natural, as if this is the most common operation. However, if you have written c/c++, you will find that writing like this is not the norm, but a very beautiful thing. You must avoid writing like this in c/c++.
class Person { private: string name; string addr; int age; public: void addAge() { this->age++; } }; Person addAge(Person person) { (); return person; //Cannot return directly, the person object will be copied} int main() { Person person; addAge(person);//Cannot be passed directly, the person object will be copied}
As shown in the above code, if the person object is passed or returned directly, the data in the object will be copied, resulting in additional overhead, because this is the pattern of passing by value. There are also such copies passed by value in Java, but they will only work on the basic types. The basic types are very small, with only 8 bytes long and 4 bytes int, and objects are all passed by reference.
There are more than one way to solve this problem in C++, but the code written is very lame and ugly. Here we use pointers to solve this copy problem
class Person { private: string name; string addr; int age; public: void addAge() { this->age++; } }; Person* addAge(Person* person) { person->addAge(); return person; //It can be returned, and the entire object will not be copied, only the pointer (8 bytes)} int main() { Person person; addAge(&person);//Pass after fetching the address, the entire object will not be copied, only the pointer (8 bytes) //or Person* pPerson = new Person; addAge(pPerson);//Directly pass pointer delete pPerson;//Dynamic allocation must be deleted, otherwise there is a risk of memory leakage}
Is C++ much more troublesome than Java? So we usually complain that Java syntax is bloated and is called by C#, person, and kotlin, but it can beat C++ because C++ can allow you to pass parameters and return values well.
Although the overall mechanism of golang tends to java's ease of use, it inherits the habit of C++ when passing variables back, distinguishes between passing by value and passing by pointer. If the value and pointer are not distinguished when writing code, although the program will not report an error, it will cause additional copy overhead and is not performance-friendly.
type Person struct { name string addr string age int } func (this* Person) addAge() { ++ } func addAge(person Person) Person { () return person //Cannot return directly, the person object will be copied} func main() { person := Person{} addAge(person)//Cannot be passed directly, the person object will be copied}
The above code is an error demonstration. It is completely fine to write this in Java, but it is not possible in golang because it is passed by value and will copy objects, just like c/c++.
type Person struct { name string addr string age int } func (this* Person) addAge() { ++ } func addAge(person* Person) *Person { () return person //It can be returned, and the entire object will not be copied, only the pointer (8 bytes)} func main() { person := Person{} addAge(&person)//Pass after fetching the address, the entire object will not be copied, only the pointer (8 bytes) //or person1 := new(Person) addAge(person1)//Send the pointer directly, and will not copy the entire object, but will only copy the pointer (8 bytes)}
This is the correct way to use it, pass it by pointer, just like c/c++.
At the same time, when you directly use golang's built-in map or slice type, you don't have to worry about this problem, because the map or slice produced by make is the pointer type by default, and it will not be copied by value when passing and returning.
func doSome(input map[string]string) map[string]string { input["hello"] = "world" return input //You can return directly, and you will not copy by value. The map is a pointer by default} func main() { data := make(map[string]string,5) doSome(data) //It can be passed directly, and it will not be copied by value. Map is a pointer}
Therefore, if you transfer from java to golang and have not written c/c++ at the same time, then you must pay great attention to this issue. You must not write go completely based on the habit of writing java code, otherwise if you only copy large objects in the loop, it will be a performance poison.
In short, golang, a computer language, has the characteristics of java and c/c++. To be able to be used well, it is necessary to have the foundation of these two languages.
Summarize
This is the end of this article about the value types and pointer types in go language. For more related go language value types and pointer types, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!