Golang is my favorite language, it is concise, efficient, easy to learn, the development of high efficiency, can also be compiled into machine code ...
Although it was born, and is now popular in the market, but it is a new language, there are many people are not very accustomed to the place (that is, the pit, (^__^)), I as a novice, while learning, while stepping on the pit, I hope to other people have reference role.
File names don't end with __test.go.
The naming of the Golang source file is not the same as in other languages, but Golang comes with unit test, and its unit test has a small specification: all unit test files end with __test.go!
So, when you name a non-unit test file as Xxx_test.go, and you are determined to compile, you will get an error: No buildable go source files in XXXXXX (your file path).
So, remember, the end of __test.go is the unit test file, and remember not to put the unit test file and normal go file together, be sure to put the unit test file into a directory, otherwise it will be compiled.
Statement FMT. Println ("Here is Kanji:" + string variable) The value of the string variable does not print out the problem
The following procedures are available:
Package Main
Import "FMT"
Func Main () {
M1: = GetString ()
Fmt. Println ("Now is:" + M1)
}
Func getString () string{
Return "Abd"
}
Run command go run test.go
But the individual print variable m1 can display normally
Import "FMT"
Func Main () {
M1: = GetString ()
Fmt. PRINTLN (M1)
Fmt. Println ("Now is:" + M1)
}
Func getString () string{
Return "Abd"
}
What is this for? It's strange!
In fact, this is to blame the IDE, my IDE is Phpstorm + Golang plug-in package, IDE comes with the console of Chinese support is very unfriendly, with Chinese characters printed out, easy to display, in fact, through the terminal print out, is correct!
When multiple defer occur, multiple defer are executed in LIFO (last in, first out) order
Package Main
Import "FMT"
Func Main () {
Defer func () {
Fmt. Println ("1")
}()
Defer func () {
Fmt. Println ("2")
}()
Defer func () {
Fmt. Println ("3")
}()
}
The corresponding output is:
3
2
1
You can pass any value in the panic, not just a string
Package Main
Import "FMT"
Func Main () {
Defer func () {
If r: = Recover (); r! = nil{
Fmt. Println (R)
}
}()
Panic ([]int{12312})
}
Output:
[12312]
When you use a for range to iterate over an array or map, the traversed pointer is constant, and each traversal executes only a copy of the struct value.
Import "FMT"
Type Student struct{
Name string
Age int
}
Func Main () {
var stus []student
Stus = []student{
{Name: "One", age:18},
{Name: "A", age:19},
}
Data: = Make (Map[int]*student)
For I, V: = Range stus{
Data[i] = &v//should be changed to: data[i] = &stus[i]
}
For I, V: = Range data{
Fmt. Printf ("key=%d, value=%v \ n", i,v)
}
}
Therefore, the result output is:
Key=0, Value=&{two 19}
Key=1, Value=&{two 19}
No inheritance in Go! No inheritance! Go is called combination! It's a combination!
Import "FMT"
Type Student struct{
Name string
Age int
}
Func (P *student) Love () {
Fmt. Println ("Love")
}
Func (P *student) like () {
Fmt. Println ("like first")
P.love ()
}
Type boy struct {
Student
}
Func (b * Boy) Love () {
Fmt. Println ("hate")
}
Func Main () {
B: = boy{}
B.like ()
}
Output:
Like first
Love
Regardless of the order of operation, when the parameter is a function, the value of the parameter is evaluated first
Func Main () {
A: = 1
Defer print (function (a))
A = 2;
}
func function (num int) int{
Return num
}
Func print (num int) {
Fmt. PRINTLN (num)
}
Output:
1
Note whether the function of a struct or a struct
Import "FMT"
Type people interface {
Speak ()
}
Type Student struct{
Name string
Age int
}
Func (Stu *student) speak () {
Fmt. Println ("I am a student, I Am", stu.age)
}
Func Main () {
var p people
p = student{name: "Ryugou", age:12}//should be changed to P = &student{name: "Ryugou", Age:12}
P.speak ()
}
Output:
Cannot use student literal (type student) as type people in assignment:
Student does not implement people (speak method has pointer receiver)
Make (chan int) and make (chan int, 1) are not the same
Once Chan has been written to the data, the current goruntine will be blocked, knowing that someone can receive it (ie "<-ch") and it will keep blocking if no one receives it. And if Chan takes a buffer, it puts the data in the buffer until the buffer is full before it blocks.
Import "FMT"
Func Main () {
CH: = make (chan int)//change to ch: = Make (chan int, 1) just fine.
CH <-1
Fmt. PRINTLN ("Success")
}
Output:
Fatal Error:all Goroutines is asleep-deadlock!
The function of the Golang Select, similar to the Select, poll, Epoll, is to listen to the IO operation and trigger the corresponding action when the IO operation occurs.
The code form of select is very similar to switch, but the action statement in the Select Case can only be an "IO operation" (not just the value <-channel, the assignment channel<-), and select waits until a case The sentence is completed, that is, until the data is read successfully from the channel. The SELECT statement ends
Import "FMT"
Func Main () {
CH: = Make (chan int, 1)
CH <-1
Select {
Case msg: =<-ch:
Fmt. PRINTLN (msg)
Default
Fmt. PRINTLN ("Default")
}
Fmt. PRINTLN ("Success")
}
Output:
1
Success
Default can tell if Chan is full.
Import "FMT"
Func Main () {
CH: = Make (chan int, 1)
Select {
Case msg: =<-ch:
Fmt. PRINTLN (msg)
Default
Fmt. PRINTLN ("Default")
}
Fmt. PRINTLN ("Success")
}
Output:
Default
Success
The case is not read successfully at this time because the data is not written in ch and is empty. The select executes the default statement.
Uninitialized variables are not present in the Go language
The basic way to define a variable is:
var sender name type = Expression
Both types and expressions can be omitted, and if an initialization expression is omitted, the variable is initialized with a value of 0.
A numeric variable corresponds to a value of 0.
Boolean variable corresponds to False
The 0 value of the string corresponds to an empty string
The interface or reference type (including the Slice,map,chan) variable corresponds to nil
The 0 value for an aggregation type, such as an array or struct, is a 0 value of the type that each element or field pair should be.
var s string
Fmt. PRINTLN (s)//""
: = Problem of attention
Use: = variable defined, can only be used inside the function.
When defining multiple variables: = Around is not necessarily all just declared, some may just be assignment, such as the following ERR variable
In, err: = OS. Open (infile)
Todo
Out, err: = OS. Create (outfile)
New is just a predefined function in the go language, it's not a keyword, we can use new as a variable or other
For example:
Func Delta (old, new int) int {
Return New-old
}
The above is correct.
Not using new will definitely allocate memory on the heap
The compiler will automatically choose to allocate storage space on the stack or on the heap, but it may be surprising that the choice is not determined by the way Var or new declares variables.
Take a look at the example:
var global *int
Func f () {
var x int X=1
Global = &x
}
Func g () {
Y: = new (int)
*y = 1
}
The x in the F () function allocates memory on the heap, and y in the G () function is allocated on the stack.
The init function can contain multiple files in the same file
In the same package file, you can include multiple init functions, and multiple init functions are executed in the same order as they are defined.
No "objects" in Golang
Package Main
Import (
"FMT"
)
Type test struct {
Name string
}
Func (t *test) GetName () {
Fmt. Println ("Hello World")
}
Func Main () {
var t *test
t = Nil
T.getname ()
}
Can you output it normally? Will it be an error?
The output is:
Hello World
can be output normally. Go is not object-oriented language, go is not the meaning of object, go language book objects and Java, PHP objects are different, not the real "object", is the entity of the struct in go.
Call the GetName method, you can also convert to: Type.method (t Type, arguments) in Go
So, the above code can also be written in the main function:
Func Main () {
(*test). GetName (Nil)
}
The meaning of the pointer * symbol in GO
& the meaning that everyone understands, take the address, if you want to get a variable address, just add & before the variable.
For example:
A: = 1
B: = &a
Now, I get the address of a, but I want to get the value of a pointer, how do I do it? With the * number, *b can be.
* means to take a value on the pointer.
The following adds a value to a
A: = 1
B: = &a
*b++
* and & can cancel each other, while note that,*& can be offset, but &* can not; So a and *&a are the same, and *&*&*&a is the same.
Os. Args Gets the command-line directive arguments, which should start with the 1 coordinate of the array
Os. The first element of args, the OS. Args[0], is the name of the command itself
Package Main
Import (
"FMT"
"OS"
)
Func Main () {
Fmt. Println (OS. Args[0])
}
The above code, after go build, is packaged into an executable file, main, and then run the instruction./main 123
Output:./main
Problem with the capacity of array slicing slice
Take a look at the following code:
Import (
"FMT"
)
Func Main () {
Array: = [4]int{10, 20, 30, 40}
Slice: = Array[0:2]
Newslice: = Append (slice, 50)
NEWSLICE[1] + = 1
Fmt. Println (Slice)
}
What is the output, please?
The answer is:
[10 21]
If slightly modified, the above newslice is changed to expand three times, Newslice: = Append (Append (Append (slice, 50), 100), 150) are as follows:
Import (
"FMT"
)
Func Main () {
Array: = [4]int{10, 20, 30, 40}
Slice: = Array[0:2]
Newslice: = Append (Append (Append (slice, 50), 100), 150)
NEWSLICE[1] + = 1
Fmt. Println (Slice)
}
The output is:
[10 20]
What the hell is this special?
This will start from the expansion of the Golang slice, the expansion of the slice, is when the slice added elements, the tile capacity is not enough, will be expanded, the size of the expansion follows the following principle: (If the tile capacity is less than 1024 elements, then the expansion of the slice cap will double, multiplied by 2 Once the number of elements exceeds 1024 elements, the growth factor becomes 1.25, which increases the original capacity by One-fourth each time. If the capacity of the original array has not been touched after the expansion, then the position of the pointer in the slice is still the original array (this is the cause of the bug), and if the capacity of the original array is exceeded after the expansion, then go will open a new memory and copy the original value. This situation does not affect the original array in the slightest.
It is recommended to avoid the creation of bugs as much as possible.
Map reference does not exist key, do not error
What does the following example output, will be an error?
Import (
"FMT"
)
Func Main () {
Newmap: = Make (Map[string]int)
Fmt. Println (newmap["a"])
}
The answer is:
0
No error. Unlike Php,golang's map and Java's HashMap, Java references that do not exist return NULL, and Golang returns the initial value
Map uses range to traverse order problems, not in order of entry, but in random order
Take a look at the following example:
Import (
"FMT"
)
Func Main () {
Newmap: = Make (Map[int]int)
For I: = 0; I < 10; i++{
Newmap[i] = i
}
For key, Value: = Range newmap{
Fmt. Printf ("Key is%d, value is%d\n", key, value)
}
}
Output:
Key is 1, value is 1
Key is 3, value is 3
Key is 5, value is 5
Key is 7, value is 7
Key is 9, value is 9
Key is 0, value is 0
Key is 2, value is 2
Key is 4, value is 4
Key is 6, value is 6
Key is 8, value is 8
is in a disorderly order. Map traversal order is not fixed, this design is intentional, can prevent the program from relying on a particular traversal order.
The channel is passed as a function parameter and can be declared as a fetch only (<-Chan) or only sent (Chan <-)
When a function declares a channel as a parameter of a type, the CHANNL can be declared to be only a value (<-chan) or only a value (Chan <-) can be sent, and no special instructions can be taken to either value or send a value.
For example, you can only send values
Func setData (Ch chan <-string) {
Todo
}
If <-ch is present in the above function, it will compile without passing.
The following is the only value that can be taken:
Func setData (ch <-chan string) {
Todo
}
If ch<-is present in the above function, it will be error during compile time.
When using channel, pay attention to the execution flow problem between goroutine
Package Main
Import (
"FMT"
)
Func Main () {
CH: = Make (Chan string)
Go SetData (CH)
Fmt. Println (<-ch)
Fmt. Println (<-ch)
Fmt. Println (<-ch)
Fmt. Println (<-ch)
Fmt. Println (<-ch)
}
Func setData (Ch Chan string) {
CH <-"Test"
Ch <-"Hello wolrd"
CH <-"123"
CH <-"456"
Ch <-"789"
}
What is the execution flow of the above code?
A send or value operation based on a non-cached channel will cause the current goroutine to block and wait until another goroutine does the opposite or send the operation before it runs normally.
The process in the above example is this:
The main goroutine waits to receive, the other one goroutine sends "test" and waits for processing; After the communication is completed, the "test" is printed, and two goroutine continue to run their own.
The main goroutine waits to receive, the other goroutine sends "Hello World" and waits for processing; After the communication is finished, the "Hello World" is printed, and two goroutine continue to run their own.
The main goroutine waits to receive, the other one goroutine sends "123" and waits for processing; After completing the communication, print out "123"; two goroutine each continue to run their own.
The main goroutine waits to receive, the other one goroutine sends "456" and waits for processing; After completing the communication, print out "456"; two goroutine each continue to run their own.
The main goroutine waits to receive, the other one goroutine sends "789" and waits for processing; After completing the communication, print out "789"; two goroutine each continue to run their own.
Remember: The Golang channel is used to communicate between Goroutine and is blocked during communication.