Merge commit '3efe5b8e43f3b1d46f4c6f10e7d9604f94af1c86' into ja
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# 2 Go basic knowledge
|
||||
|
||||
Go is a compiled system programming language, and it belongs to the C-family. However, its compilation speed is much faster than other C-family languages. It has only 25 keywords, even less than 26 English letters! Let's take a look at these keywords before we get started.
|
||||
Go is a compiled system programming language, and it belongs to the C-family. However, its compilation speed is much faster than other C-family languages. It has only 25 keywords..., even less than 26 English letters! Let's take a look at these keywords before we get started.
|
||||
|
||||
break default func interface select
|
||||
case defer go map struct
|
||||
@@ -8,10 +8,10 @@ Go is a compiled system programming language, and it belongs to the C-family. Ho
|
||||
const fallthrough if range type
|
||||
continue for import return var
|
||||
|
||||
In this chapter, I'm going to teach you some basic Go knowledge. You will find how concise the Go programming language is, and the beautiful design of the language. Programming can be very fun in Go. After we complete this chapter, you'll be familiar with the above keywords.
|
||||
In this chapter, I'm going to teach you some basic Go knowledge. You will find out how concise the Go programming language is, and the beautiful design of the language. Programming can be very fun in Go. After we complete this chapter, you'll be familiar with the above keywords.
|
||||
|
||||
## Links
|
||||
|
||||
- [Directory](preface.md)
|
||||
- Previous chapter: [Chapter 1 Summary](01.5.md)
|
||||
- Next section: ["Hello, Go"](02.1.md)
|
||||
- Next section: ["Hello, Go"](02.1.md)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# 2.1 Hello, Go
|
||||
|
||||
Before we start building an application in Go, we need to learn how to write a simple program. It's like you cannot build a building without knowing how to build its foundation. Therefore, we are going to learn the basic syntax to run some simple programs in this section.
|
||||
Before we start building an application in Go, we need to learn how to write a simple program. You can't expect to build a building without first knowing how to build its foundation. Therefore, we are going to learn the basic syntax to run some simple programs in this section.
|
||||
|
||||
## Program
|
||||
|
||||
According to international practice, before you learn how to programming in some languages, you may want to know how to write a program to print "Hello world".
|
||||
According to international practice, before you learn how to program in some languages, you will want to know how to write a program to print "Hello world".
|
||||
|
||||
Are you ready? Let's Go!
|
||||
|
||||
@@ -26,7 +26,7 @@ One thing that you should know in the first is that Go programs are composed by
|
||||
|
||||
`package<pkgName>` (In this case is `package main`) tells us this source file belongs to `main` package, and the keyword `main` tells us this package will be compiled to a program instead of package files whose extensions are `.a`.
|
||||
|
||||
Every executable program has one and only one `main` package, and you need an entry function called `main` without any argument and return value in the `main` package.
|
||||
Every executable program has one and only one `main` package, and you need an entry function called `main` without any arguments or return values in the `main` package.
|
||||
|
||||
In order to print `Hello, world…`, we called a function called `Printf`. This function is coming from `fmt` package, so we import this package in the third line of source code, which is `import "fmt"`
|
||||
|
||||
@@ -44,10 +44,10 @@ You may notice that the example above contains many non-ASCII characters. The pu
|
||||
|
||||
## Conclusion
|
||||
|
||||
Go uses `package` (like modules in Python) to organize programs. The function `main.main()` (this function must be in the `main` package) is the entry point of any program. Go supports UTF-8 characters because one of the creators of Go is a creator of UTF-8, so Go supports multi-language from the time it was born.
|
||||
Go uses `package` (like modules in Python) to organize programs. The function `main.main()` (this function must be in the `main` package) is the entry point of any program. Go supports UTF-8 characters because one of the creators of Go is a creator of UTF-8, so Go supports multiple languages from the time it was born.
|
||||
|
||||
## Links
|
||||
|
||||
- [Directory](preface.md)
|
||||
- Previous section: [Go basic knowledge](02.0.md)
|
||||
- Next section: [Go foundation](02.2.md)
|
||||
- Next section: [Go foundation](02.2.md)
|
||||
|
||||
132
en/eBook/02.2.md
132
en/eBook/02.2.md
@@ -4,9 +4,9 @@ In this section, we are going to teach you how to define constants, variables wi
|
||||
|
||||
## Define variables
|
||||
|
||||
There are many forms of syntax that can define variables in Go.
|
||||
There are many forms of syntax that can use to define variables in Go.
|
||||
|
||||
Use keyword `var` is the basic form to define variables, notice that Go puts variable type `after` variable name.
|
||||
The keyword `var` is the basic form to define variables, notice that Go puts the variable type `after` the variable name.
|
||||
|
||||
// define a variable with name “variableName” and type "type"
|
||||
var variableName type
|
||||
@@ -29,7 +29,7 @@ Define multiple variables with initial values.
|
||||
*/
|
||||
var vname1, vname2, vname3 type = v1, v2, v3
|
||||
|
||||
Do you think it's too tedious to define variables use the way above? Don't worry because Go team found this problem as well. Therefore if you want to define variables with initial values, we can just omit variable type, so the code will look like this:
|
||||
Do you think it's too tedious to define variables use the way above? Don't worry because the Go team has found this to be aproblem. Therefore if you want to define variables with initial values, we can just omit the variable type, so the code will look like this instead:
|
||||
|
||||
/*
|
||||
Define three variables with type "type", and initialize their values.
|
||||
@@ -37,7 +37,7 @@ Do you think it's too tedious to define variables use the way above? Don't worry
|
||||
*/
|
||||
var vname1, vname2, vname3 = v1, v2, v3
|
||||
|
||||
Well, I know this is still not simple enough for you, so do I. Let's see how we fix it.
|
||||
Well, I know this is still not simple enough for you. Let's see how we fix it.
|
||||
|
||||
/*
|
||||
Define three variables with type "type", and initialize their values.
|
||||
@@ -45,13 +45,13 @@ Well, I know this is still not simple enough for you, so do I. Let's see how we
|
||||
*/
|
||||
vname1, vname2, vname3 := v1, v2, v3
|
||||
|
||||
Now it looks much better. Use `:=` to replace `var` and `type`, this is called brief statement. But wait, it has one limitation that this form can only be used inside of functions. You will get compile errors if you try to use it outside of function bodies. Therefore, we usually use `var` to define global variables, and we can use this brief statement in `var()`.
|
||||
Now it looks much better. Use `:=` to replace `var` and `type`, this is called a brief statement. But wait, it has one limitation: this form can only be used inside of functions. You will get compile errors if you try to use it outside of function bodies. Therefore, we usually use `var` to define global variables and we can use this brief statement in `var()`.
|
||||
|
||||
`_` (blank) is a special name of variable, any value that is given to it will be ignored. For example, we give `35` to `b`, and discard `34`.( ***This example just show you how it works. It looks useless here because we often use this symbol when we get function return values.*** )
|
||||
`_` (blank) is a special variable name. Any value that is given to it will be ignored. For example, we give `35` to `b`, and discard `34`.( ***This example just show you how it works. It looks useless here because we often use this symbol when we get function return values.*** )
|
||||
|
||||
_, b := 34, 35
|
||||
|
||||
If you don't use any variable that you defined in the program, compiler will give you compile errors. Try to compile following code, see what happens.
|
||||
If you don't use any variable that you defined in the program, the compiler will give you compile errors. Try to compile following code, and see what happens.
|
||||
|
||||
package main
|
||||
|
||||
@@ -61,7 +61,7 @@ If you don't use any variable that you defined in the program, compiler will giv
|
||||
|
||||
## Constants
|
||||
|
||||
So-called constants are the values that are determined in the compile time, and you cannot change them during runtime. In Go, you can use number, boolean or string as type of constants.
|
||||
So-called constants are the values that are determined during compile time and you cannot change them during runtime. In Go, you can use number, boolean or string as types of constants.
|
||||
|
||||
Define constants as follows.
|
||||
|
||||
@@ -93,7 +93,7 @@ In Go, we use `bool` to define a variable as boolean type, the value can only be
|
||||
|
||||
### Numerical types
|
||||
|
||||
Integer types including signed and unsigned integer types. Go has `int` and `uint` at the same time, they have same length, but specific length depends on your operating system. They use 32-bit in 32-bit operating systems, and 64-bit in 64-bit operating systems. Go also has types that have specific length including `rune`, `int8`, `int16`, `int32`, `int64`, `byte`, `uint8`, `uint16`, `uint32`, `uint64`. Note that `rune` is alias of `int32` and `byte` is alias of `uint8`.
|
||||
Integer types includ both signed and unsigned integer types. Go has `int` and `uint` at the same time, they have same length, but specific length depends on your operating system. They use 32-bit in 32-bit operating systems, and 64-bit in 64-bit operating systems. Go also has types that have specific length including `rune`, `int8`, `int16`, `int32`, `int64`, `byte`, `uint8`, `uint16`, `uint32`, `uint64`. Note that `rune` is alias of `int32` and `byte` is alias of `uint8`.
|
||||
|
||||
One important thing you should know that you cannot assign values between these types, this operation will cause compile errors.
|
||||
|
||||
@@ -103,11 +103,11 @@ One important thing you should know that you cannot assign values between these
|
||||
|
||||
c := a + b
|
||||
|
||||
Although int has longer length than uint8, and has same length as int32, but you cannot assign values between them. ( ***c will be asserted as type `int` here*** )
|
||||
Although int has a longer length than uint8, and has the same length as int32, you cannot assign values between them. ( ***c will be asserted as type `int` here*** )
|
||||
|
||||
Float types have `float32` and `float64`, and no type called `float`, latter one is default type if you use brief statement.
|
||||
Float types have the `float32` and `float64` types and no type called `float`. The latter one is the default type if using brief statement.
|
||||
|
||||
That's all? No! Go has complex number as well. `complex128` (with a 64-bit real and 64-bit imaginary part)is default type, if you need smaller type, there is one called `complex64` (with a 32-bit real and 32-bit imaginary part). Its form is `RE+IMi`, where `RE` is real part and `IM` is imaginary part, the last `i` is imaginary number. There is a example of complex number.
|
||||
That's all? No! Go support complex numbers as well. `complex128` (with a 64-bit real and 64-bit imaginary part) is the default type, if you need a smaller type, there is one called `complex64` (with a 32-bit real and 32-bit imaginary part). Its form is `RE+IMi`, where `RE` is real part and `IM` is imaginary part, the last `i` is imaginary number. There is a example of complex number.
|
||||
|
||||
var c complex64 = 5+5i
|
||||
//output: (5+5i)
|
||||
@@ -115,7 +115,7 @@ That's all? No! Go has complex number as well. `complex128` (with a 64-bit real
|
||||
|
||||
### String
|
||||
|
||||
We just talked about that Go uses UTF-8 character set. Strings are represented by double quotes `""` or backtracks ``` `.
|
||||
We just talked about how Go uses the UTF-8 character set. Strings are represented by double quotes `""` or backtracks ``` `.
|
||||
|
||||
// sample code
|
||||
var frenchHello string // basic form to define string
|
||||
@@ -126,7 +126,7 @@ We just talked about that Go uses UTF-8 character set. Strings are represented b
|
||||
frenchHello = "Bonjour" // basic form of assign values
|
||||
}
|
||||
|
||||
It's impossible to change string values by index, you will get errors when you compile following code.
|
||||
It's impossible to change string values by index. You will get errors when you compile following code.
|
||||
|
||||
var s string = "hello"
|
||||
s[0] = 'c'
|
||||
@@ -139,7 +139,7 @@ What if I really want to change just one character in a string? Try following co
|
||||
s2 := string(c) // convert back to string type
|
||||
fmt.Printf("%s\n", s2)
|
||||
|
||||
You can use operator `+` to combine two strings.
|
||||
You use the `+` operator to combine two strings.
|
||||
|
||||
s := "hello,"
|
||||
m := " world"
|
||||
@@ -170,7 +170,7 @@ Go has one `error` type for purpose of dealing with error messages. There is als
|
||||
|
||||
### Underlying data structure
|
||||
|
||||
The following picture comes from a article about [Go data structure](http://research.swtch.com/godata) in [Russ Cox Blog](http://research.swtch.com/). As you can see, Go gives blocks in memory to store data.
|
||||
The following picture comes from an article about [Go data structure](http://research.swtch.com/godata) in [Russ Cox Blog](http://research.swtch.com/). As you can see, Go utilizes blocks of memory to store data.
|
||||
|
||||

|
||||
|
||||
@@ -180,7 +180,7 @@ Figure 2.1 Go underlying data structure
|
||||
|
||||
### Define by group
|
||||
|
||||
If you want to define multiple constants, variables or import packages, you can use group form.
|
||||
If you want to define multiple constants, variables or import packages, you can use the group form.
|
||||
|
||||
Basic form.
|
||||
|
||||
@@ -218,13 +218,13 @@ Unless you assign the value of constant is `iota`, the first value of constant i
|
||||
|
||||
### iota enumerate
|
||||
|
||||
Go has one keyword `iota`, this keyword is to make `enum`, it begins with `0`, increased by `1`.
|
||||
Go has one keyword called `iota`, this keyword is to make `enum`, it begins with `0`, increased by `1`.
|
||||
|
||||
const(
|
||||
x = iota // x == 0
|
||||
y = iota // y == 1
|
||||
z = iota // z == 2
|
||||
w // If there is no expression after constants name, it uses the last expression, so here is saying w = iota implicitly. Therefore w == 3, and y and x both can omit "= iota" as well.
|
||||
w // If there is no expression after the constants name, it uses the last expression, so it's saying w = iota implicitly. Therefore w == 3, and y and x both can omit "= iota" as well.
|
||||
)
|
||||
|
||||
const v = iota // once iota meets keyword `const`, it resets to `0`, so v = 0.
|
||||
@@ -237,8 +237,8 @@ Go has one keyword `iota`, this keyword is to make `enum`, it begins with `0`, i
|
||||
|
||||
The reason that Go is concise because it has some default behaviors.
|
||||
|
||||
- Any variable starts with capital letter means it will be exported, private otherwise.
|
||||
- Same rule for functions and constants, no `public` or `private` keyword exists in Go.
|
||||
- Any variable that begins with a capital letter means it will be exported, private otherwise.
|
||||
- The same rule applies for functions and constants, no `public` or `private` keyword exists in Go.
|
||||
|
||||
## array, slice, map
|
||||
|
||||
@@ -248,7 +248,7 @@ The reason that Go is concise because it has some default behaviors.
|
||||
|
||||
var arr [n]type
|
||||
|
||||
in `[n]type`, `n` is the length of array, `type` is the type of its elements. Like other languages, we use `[]` to get or set element values in array.
|
||||
in `[n]type`, `n` is the length of the array, `type` is the type of its elements. Like other languages, we use `[]` to get or set element values within arrays.
|
||||
|
||||
var arr [10]int // an array of type int
|
||||
arr[0] = 42 // array is 0-based
|
||||
@@ -256,22 +256,22 @@ in `[n]type`, `n` is the length of array, `type` is the type of its elements. Li
|
||||
fmt.Printf("The first element is %d\n", arr[0]) // get element value, it returns 42
|
||||
fmt.Printf("The last element is %d\n", arr[9]) //it returns default value of 10th element in this array, which is 0 in this case.
|
||||
|
||||
Because length is a part of array type, `[3]int` and `[4]int` are different types, so we cannot change length of arrays. When you use arrays as arguments, functions get their copies instead of references! If you want to use reference, you may want to use `slice` which we will talk about latter.
|
||||
Because length is a part of the array type, `[3]int` and `[4]int` are different types, so we cannot change the length of arrays. When you use arrays as arguments, functions get their copies instead of references! If you want to use reference, you may want to use `slice`, which we'll talk about later.
|
||||
|
||||
It's possible to use `:=` when you define arrays.
|
||||
|
||||
a := [3]int{1, 2, 3} // define a int array with 3 elements
|
||||
a := [3]int{1, 2, 3} // define an int array with 3 elements
|
||||
|
||||
b := [10]int{1, 2, 3} // define a int array with 10 elements, and first three are assigned, rest of them use default value 0.
|
||||
b := [10]int{1, 2, 3} // define a int array with 10 elements, of which the first three are assigned. The rest of them use the default value 0.
|
||||
|
||||
c := [...]int{4, 5, 6} // use `…` replace with number of length, Go will calculate it for you.
|
||||
c := [...]int{4, 5, 6} // use `…` to replace the length paramter and Go will calculate it for you.
|
||||
|
||||
You may want to use arrays as arrays' elements, let's see how to do it.
|
||||
You may want to use arrays as arrays' elements. Let's see how to do this.
|
||||
|
||||
// define a two-dimensional array with 2 elements, and each element has 4 elements.
|
||||
doubleArray := [2][4]int{[4]int{1, 2, 3, 4}, [4]int{5, 6, 7, 8}}
|
||||
|
||||
// You can write about declaration in a shorter way.
|
||||
// The declaration can be written more concisely as follows.
|
||||
easyArray := [2][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}}
|
||||
|
||||
Array underlying data structure.
|
||||
@@ -282,34 +282,34 @@ Figure 2.2 Multidimensional array mapping relationship
|
||||
|
||||
### slice
|
||||
|
||||
In many situations, array is not a good choice. For example, we don't know how long the array will be when we define it, so we need "dynamic array". This is called `slice` in Go.
|
||||
In many situations, the array type is not a good choice -for instance when we don't know how long the array will be when we define it. Thus, we need a "dynamic array". This is called `slice` in Go.
|
||||
|
||||
`slice` is not really `dynamic array`, it's a reference type. `slice` points to an underlying `array`, its declaration is similar to `array`, but doesn't need length.
|
||||
`slice` is not really a `dynamic array`. It's a reference type. `slice` points to an underlying `array` whose declaration is similar to `array`, but doesn't need length.
|
||||
|
||||
// just like to define array, but no length this time
|
||||
// just like defining an array, but this time, we exclude the length.
|
||||
var fslice []int
|
||||
|
||||
Then we define a `slice`, and initialize its data.
|
||||
|
||||
slice := []byte {'a', 'b', 'c', 'd'}
|
||||
|
||||
`slice` can redefine from exists slices or arrays. `slice` use `array[i:j]` to slice, where `i` is start index and `j` is end index, but notice that `array[j]` will not be sliced, now the length of slice is `j-i`.
|
||||
`slice` can redefine existing slices or arrays. `slice` uses `array[i:j]` to slice, where `i` is the start index and `j` is end index, but notice that `array[j]` will not be sliced since the length of the slice is `j-i`.
|
||||
|
||||
// define a slice with 10 elements which types are byte
|
||||
// define a slice with 10 elements whose types are bytes
|
||||
var ar = [10]byte {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
|
||||
|
||||
// define two slices with type []byte
|
||||
var a, b []byte
|
||||
|
||||
// a points to elements from 3rd to 5th in array ar.
|
||||
// 'a' points to elements from 3rd to 5th in array ar.
|
||||
a = ar[2:5]
|
||||
// now a has elements ar[2],ar[3] and ar[4]
|
||||
// now 'a' has elements ar[2],ar[3] and ar[4]
|
||||
|
||||
// b is another slice of array ar
|
||||
// 'b' is another slice of array ar
|
||||
b = ar[3:5]
|
||||
// now b has elements ar[3] and ar[4]
|
||||
// now 'b' has elements ar[3] and ar[4]
|
||||
|
||||
Notice that differences between `slice` and `array` when you define them. We use `[…]` let Go calculates length but use `[]` to define slice only.
|
||||
Notice the differences between `slice` and `array` when you define them. We use `[…]` to let Go calculate length but use `[]` to define slice only.
|
||||
|
||||
Their underlying data structure.
|
||||
|
||||
@@ -320,10 +320,10 @@ Figure 2.3 Correspondence between slice and array
|
||||
slice has some convenient operations.
|
||||
|
||||
- `slice` is 0-based, `ar[:n]` equals to `ar[0:n]`
|
||||
- Second index will be the length of `slice` if you omit it, `ar[n:]` equals to `ar[n:len(ar)]`.
|
||||
- The second index will be the length of `slice` if omitted, `ar[n:]` equals to `ar[n:len(ar)]`.
|
||||
- You can use `ar[:]` to slice whole array, reasons are explained in first two statements.
|
||||
|
||||
More examples about `slice`
|
||||
More examples pertaining to `slice`
|
||||
|
||||
// define an array
|
||||
var array = [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
|
||||
@@ -339,21 +339,21 @@ More examples about `slice`
|
||||
aSlice = array[3:7] // aSlice has elements d,e,f,g,len=4,cap=7
|
||||
bSlice = aSlice[1:3] // bSlice contains aSlice[1], aSlice[2], so it has elements e,f
|
||||
bSlice = aSlice[:3] // bSlice contains aSlice[0], aSlice[1], aSlice[2], so it has d,e,f
|
||||
bSlice = aSlice[0:5] // slcie could be expanded in range of cap, now bSlice contains d,e,f,g,h
|
||||
bSlice = aSlice[0:5] // slice could be expanded in range of cap, now bSlice contains d,e,f,g,h
|
||||
bSlice = aSlice[:] // bSlice has same elements as aSlice does, which are d,e,f,g
|
||||
|
||||
`slice` is reference type, so one of them changes will affect others. For instance, `aSlice` and `bSlice` above, if you change value of element in `aSlice`, `bSlice` will be changed as well.
|
||||
`slice` is a reference type, so any changes will affect other variables pointing to the same slice or array. For instance, in the case of `aSlice` and `bSlice` above, if you change the value of an element in `aSlice`, `bSlice` will be changed as well.
|
||||
|
||||
`slice` is like a struct by definition, it contains 3 parts.
|
||||
`slice` is like a struct by definition and it contains 3 parts.
|
||||
|
||||
- A pointer that points to where `slice` starts.
|
||||
- length of `slice`.
|
||||
- The length of `slice`.
|
||||
- Capacity, the length from start index to end index of `slice`.
|
||||
|
||||
Array_a := [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
|
||||
Slice_a := Array_a[2:5]
|
||||
|
||||
Underlying data structure of code above as follows.
|
||||
The underlying data structure of the code above as follows.
|
||||
|
||||

|
||||
|
||||
@@ -361,20 +361,20 @@ Figure 2.4 Array information of slice
|
||||
|
||||
There are some built-in functions for slice.
|
||||
|
||||
- `len` gets length of `slice`.
|
||||
- `cap` gets maximum length of `slice`
|
||||
- `len` gets the length of `slice`.
|
||||
- `cap` gets the maximum length of `slice`
|
||||
- `append` appends one or more elements to `slice`, and returns `slice` .
|
||||
- `copy` copies elements from one slice to the other, and returns number of elements were copied.
|
||||
- `copy` copies elements from one slice to the other, and returns the number of elements that were copied.
|
||||
|
||||
Attention: `append` will change array that `slice` points to, and affect other slices that point the same array. Also, if there is not enough length for the slice (`(cap-len) == 0`), `append` returns new array for this slice, at this point, other slices point to the old array will not be affected.
|
||||
Attention: `append` will change the array that `slice` points to, and affect other slices that point to the same array. Also, if there is not enough length for the slice (`(cap-len) == 0`), `append` returns a new array for this slice. When this happens, other slices pointing to the old array will not be affected.
|
||||
|
||||
### map
|
||||
|
||||
`map` is like dictionary in Python, use form `map[keyType]valueType` to define it.
|
||||
`map` is behaves like a dictionary in Python. Use the form `map[keyType]valueType` to define it.
|
||||
|
||||
Let's see some code, the set and get value in `map` is like `slice`, use `key` as agent, but index in `slice` can only be int type, and `map` can use much more than that, `int`, `string`, whatever you want. Also, they are all able to use `==` and `!=` to compare values.
|
||||
Let's see some code. The 'set' and 'get' values in `map` are similar to `slice`, however the index in `slice` can only be of type 'int' while `map` can use much more than that: for example `int`, `string`, or whatever you want. Also, they are all able to use `==` and `!=` to compare values.
|
||||
|
||||
// use string as key type, int as value type, and you have to use `make` initialize it.
|
||||
// use string as the key type, int as the value type, and `make` initialize it.
|
||||
var numbers map[string] int
|
||||
// another way to define map
|
||||
numbers := make(map[string]int)
|
||||
@@ -385,22 +385,20 @@ Let's see some code, the set and get value in `map` is like `slice`, use `key` a
|
||||
fmt.Println("The third number is: ", numbers["three"]) // get values
|
||||
// It prints: The third number is: 3
|
||||
|
||||
`map` is like form in our lives, left side are `key`s, another side are values.
|
||||
|
||||
Some notes when you use map.
|
||||
|
||||
- `map` is disorderly, every time you print `map` will get different results. It's impossible to get value by `index`, you have to use `key`.
|
||||
- `map` doesn't have fixed length, it's a reference type as `slice` does.
|
||||
- `len` works for `map` also, it returns how many `key`s that map has.
|
||||
- It's quite easy to change value through `map`, simply use `numbers["one"]=11` to change value of `key` one to `11`.
|
||||
- `map` is disorderly. Everytime you print `map` you will get different results. It's impossible to get values by `index` -you have to use `key`.
|
||||
- `map` doesn't have a fixed length. It's a reference type just like `slice`.
|
||||
- `len` works for `map` also. It returns how many `key`s that map has.
|
||||
- It's quite easy to change the value through `map`. Simply use `numbers["one"]=11` to change the value of `key` one to `11`.
|
||||
|
||||
You can use form `key:val` to initialize map's values, and `map` has method inside to check if the `key` exists.
|
||||
You can use form `key:val` to initialize map's values, and `map` has built-in methods to check if the `key` exists.
|
||||
|
||||
Use `delete` to delete element in `map`.
|
||||
Use `delete` to delete an element in `map`.
|
||||
|
||||
// Initialize a map
|
||||
rating := map[string]float32 {"C":5, "Go":4.5, "Python":4.5, "C++":2 }
|
||||
// map has two return values. For second value, if the key doesn't exist,ok is false,true otherwise.
|
||||
// map has two return values. For the second return value, if the key doesn't exist,'ok' returns false. It returns true otherwise.
|
||||
csharpRating, ok := rating["C#"]
|
||||
if ok {
|
||||
fmt.Println("C# is in the map and its rating is ", csharpRating)
|
||||
@@ -410,7 +408,7 @@ Use `delete` to delete element in `map`.
|
||||
|
||||
delete(rating, "C") // delete element with key "c"
|
||||
|
||||
As I said above, `map` is a reference type, if two `map`s point to same underlying data, any change will affect both of them.
|
||||
As I said above, `map` is a reference type. If two `map`s point to same underlying data, any change will affect both of them.
|
||||
|
||||
m := make(map[string]string)
|
||||
m["Hello"] = "Bonjour"
|
||||
@@ -419,23 +417,23 @@ As I said above, `map` is a reference type, if two `map`s point to same underlyi
|
||||
|
||||
### make, new
|
||||
|
||||
`make` does memory allocation for built-in models, such as `map`, `slice`, and `channel`), `new` is for types' memory allocation.
|
||||
`make` does memory allocation for built-in models, such as `map`, `slice`, and `channel`), while `new` is for types' memory allocation.
|
||||
|
||||
`new(T)` allocates zero-value to type `T`'s memory, returns its memory address, which is the value of type `*T`. By Go's term, it returns a pointer, which points to type `T`'s zero-value.
|
||||
`new(T)` allocates zero-value to type `T`'s memory, returns its memory address, which is the value of type `*T`. By Go's definition, it returns a pointer which points to type `T`'s zero-value.
|
||||
|
||||
`new` returns pointers.
|
||||
|
||||
Built-in function `make(T, args)` has different purposes from `new(T)`, `make` can be used for `slice`, `map`, and `channel`, and returns a type `T` with initial value. The reason of doing this is because these three types' underlying data must be initialized before they point to them. For example, a `slice` contains a pointer points to underlying `array`, length and capacity. Before these data were initialized, `slice` is `nil`, so for `slice`, `map`, `channel`, `make` initializes their underlying data, and assigns some suitable values.
|
||||
The built-in function `make(T, args)` has different purposes than `new(T)`. `make` can be used for `slice`, `map`, and `channel`, and returns a type `T` with an initial value. The reason for doing this is because the underlying data of these three types must be initialized before they point to them. For example, a `slice` contains a pointer that points to the underlying `array`, length and capacity. Before these data are initialized, `slice` is `nil`, so for `slice`, `map` and `channel`, `make` initializes their underlying data and assigns some suitable values.
|
||||
|
||||
`make` returns non-zero values.
|
||||
|
||||
The following picture shows how `new` and `make` be different.
|
||||
The following picture shows how `new` and `make` are different.
|
||||
|
||||

|
||||
|
||||
Figure 2.5 Underlying memory allocation of make and new
|
||||
|
||||
As for zero-value, it doesn't mean empty value. It's the value that variables are not assigned manually, usually is 0, there is list of some zero-values.
|
||||
Zero-value does not mean empty value. It's the value that variables default to in most cases. Here is a list of some zero-values.
|
||||
|
||||
int 0
|
||||
int8 0
|
||||
|
||||
Reference in New Issue
Block a user