# Map& function

## map type

### Declaration and definition of map

• map is a key value data structure, a reference type data structure, which needs to be initialized
• During initialization, the capacity can be defined or not
• The map must be initialized before it can be used, otherwise it will panic
• Var a map [type of key] type of value
```func defineMap() {
var user map[string]int = make(map[string]int)
user["abc"] = 38
fmt.Printf("user:%v\n",user)
a := make(map[string]int)
a["jack"] = 1001
a["handsome"] = 1002
a["shark"] = 1003
//Get value according to key
fmt.Printf("a[jack]=%v\n",a["jack"])
}```

### The use of Map

• Use len to determine the length of map
• How to determine whether the key specified by the map exists: value, OK: = map [key]
```# User role determination
var whiteUser map[int]bool = map[int]bool {
34123: true,
3456334: true,
1:true,
}

func isWhiteUser(UserId int) bool {
_,ok := whiteUser[UserId]
return ok
}

func main() {
UserId := 1001
if isWhiteUser(UserId) {
fmt.Printf("is white user %v\n",UserId)
}else {
fmt.Printf("is Normal user %v\n",UserId)
}
}```
• Ergodic operation
```func loopMap() {
var m map[string]int
m = map[string]int{
"user01":1001,
"user02":1002,
"user03":1003,
}
for key,val := range m {
fmt.Printf("key:%s,value:%v\n",key,val)
}
}```
• Delete element action
```func delMapkey()  {
var m map[string]int
m = map[string]int{
"user01":1001,
"user02":1002,
"user03":1003,
}
delete(m,"user01")
fmt.Printf("%#v\n",m)
fmt.Println(len(m))
}```
• map is a reference type (very important)
```func yinyongMap() {
a := map[string]int {
"jack":1000,
"rose":1001,
}
a["mike"] = 1003
a["jack"] = 999
b := a
b["mike"] = 1004
a,&a,b,&b)
}```
• Ordered dictionary output (key)
```func youxuMap()  {
var m map[string]int
m = map[string]int{
"alice":1001,
"zhansan":1002,
"uloce":1003,
}
var keys[]string
for key,_ :=range m{
keys = append(keys,key)
}
// Sort alphabetically
sort.Strings(keys)
for _,key := range keys {
fmt.Printf("key:%s,value:%v\n",key,m[key])
}
}```
• Slice of map type (emphasis)
```func mapSlice() {
var s []map[string]int
s = make([]map[string]int,5)
for k,v := range s {
fmt.Printf("index:%d val: %v\n",k,v)
}
//To initialize the map corresponding to slice's index, otherwise panic
s[0]=make(map[string]int,16)
s[0]["abc"] = 100
for k,v := range s {
fmt.Printf("index:%d val: %v\n",k,v)
}
}```

## function

### Function declaration and definition

• Definition: code block with input and output to execute a specified task
```func functionName([parametername type]) [return type] {
functionBody
}```

### classification

• Functions without parameters and return values
```func functionname() {
functionbody
}```
• Multiple return values
```// Multiple return values
func Calc(a,b int) (int,int) {
return a+b,a-b
}
func Calc2(a,b int) (sum,sub int) {
sum = a + b
sub = a - b
// All return values will be reversed by default
return
}

func main() {
sum,sub := Calc(10,20)
fmt.Println(sum,sub)
}```
• Parameters are divided into variable parameters (can not be transmitted) and fixed parameters (must be transmitted)
```func Add(a ...int) int {
//Print variable parameters. Variable parameters are actually slices
fmt.Printf("func args count %d\n",len(a))
var sum int
for index,arg := range a {
fmt.Printf("arg[%d]=%v\n",index,arg)
sum += arg
}
return sum
}

func main() {
fmt.Println(sum)
}```
• defer statement
The function is to delay execution. For example, to open a file, you need to close the file handle. You only need to close the file handle with differ after the function is finished. This reduces the problem that multiple file reads and writes need to be closed multiple times
Multiple defer statements follow the characteristics of stack: first in first out
```func TestDefer() {
defer fmt.Println("hello world")
defer fmt.Println("nihao!")
fmt.Println("dabaojian")

file,err := os.Open("./a.txt")
if err != nil {
fmt.Println("fail to open file",err)
return
}

//defer actual combat
var buf[4096]byte
if errs != nil {
fmt.Println("fail to open file",err)
return
}
// close a file handle
defer file.Close()

return
}```

### Common built-in functions

• Close: used to close the channel
• len: used to calculate length
• new: used to allocate memory, mainly used to allocate value types; for example, int, struct, which returns pointers
• make: mainly used for memory allocation or initialization, mainly used for chan, map, slice
• append: mainly used to add elements to the array, slice
• panic and recover: for error handling

### Variables and scopes

• global variable
• Local variable (function internal definition) (define [if, for] in statement block)
• Variable visibility: private if the initial is lowercase, and public if the initial is uppercase

### Anonymous function

Definition: function without name

• Use with defer (closure: anonymous function without parameters)
```func TestDefer() {
defer fmt.Println("hello world")
defer fmt.Println("nihao!")
fmt.Println("dabaojian")

file,err := os.Open("./a.txt")
defer func(){
if file !=nil {
file.Close()
}
}()
var buf[4096]byte
if errs != nil {
fmt.Println("fail to open file",err)
return
}

return
}```
• Anonymous functions with parameters
```func TestDefer() {
defer fmt.Println("hello world")
defer fmt.Println("nihao!")
fmt.Println("dabaojian")

file,err := os.Open("./a.txt")

defer func(f *os.File) {
if f != nil {
f.Close()
}
}(file)

var buf[4096]byte
if errs != nil {
fmt.Println("fail to open file",err)
return
}

return
}```
• Function as an argument
• Important point: the variable parameter is actually a slice, the second prompt
```func calc(op func(args ...int)int,op_args ...int) int{
result :=op(op_args...)
fmt.Printf("result %d\n",result)
return result
}

func main() {
calc(func(args ...int)int{
var sum int
for i:=0;i<len(args);i++{
sum += args[i]
}
return sum
},1,2,3,4,5)
calc(func(args ...int)int{
var sub int
for i:=0;i<len(args);i++{
sub -= args[i]
}
return sub
},1,2,3,4,5)

}```
• Variable parameter example (2)
```func add(args ...int)int{
var sum int
for i:=0;i<len(args);i++{
// Once again, it is proved that the variable parameters are slices
sum += args[i]
}
return sum
}
func main() {
}
```
• Closure: an entity (Abstract) composed of a function and its related reference environment. Anonymous functions refer to an external variable
When a closure is called by a reassignment, the calculation is restarted
```func Adder() func(int) int {
//Closure, define external x, default is 0
var x int
return func(d int) int {
// Reference and operate on the X of the external environment to change the value of the external x
x += d
return x
}
}

func main() {
fmt.Println(f(1))
fmt.Println(f(20))
fmt.Println(f(300))
fmt.Println("========Dividing line======")
// The next step is to verify that the closure recall restores the external references
fmt.Println(f2(1))
fmt.Println(f2(20))
fmt.Println(f2(300))
}```

#### Closure exercises

• accumulation
```// base as global variable
func add(base int) func(int) int {
return func(i int) int {
base += i
return base
}
}

func main() {
fmt.Println(tmp1(1),tmp1(2))
fmt.Println(tmp2(1),tmp2(2))
}```
```func makeSuffixFunc(suffix string) func(string) string {
return func(name string) string {
//Determine whether the name contains suffix
if !strings.HasSuffix(name,suffix) {
return name+suffix
}
return name
}
}

func main() {
func1 := makeSuffixFunc(".bmp")
func2 := makeSuffixFunc(".jpg")
fmt.Println(func1("test"))
fmt.Println(func2("test"))
}```
• Computational coverage
```func calcs(base int) (func(int) int,func(int)int) {
base += i
return base
}

sub := func(i int) int{
base -= i
return base
}
}

func main() {
f1,f2 := calcs(10)
fmt.Println(f1(1),f2(2))
fmt.Println(f1(3),f2(4))
fmt.Println(f1(5),f2(6))
fmt.Println(f1(7),f2(8))

}
```

Tags: Go

Posted on Tue, 17 Mar 2020 12:19:57 -0400 by Bikkebakke