一、基础(一)

1.多个形参同一个类型,前面的参数可省略,只在最后写一个类型就可以。

func add(x, y int) int {...}
形参为int x, int y

2.同Python,函数可以返回多个返回值

func swap(x, y string) (string, string){
	return y, x
}

main中调用:a, b := swap("oh", "baby")

3.可以命名返回值
没有参数的return语句会返回已命名的返回值。

var i inti, j int = 1, 10k := 3go, python, c++ := true, false, "no!"

6.常量可以是字、字符串、布尔值、数值。不能用:=声明。
如,const name = ‘柴犬’

二、基础(二)

1、for循环

一种是和c语言一样的用法:

for i:= 1; i<=10; i++ {
	fmt.Print(i, " ")
}

i := 1
for ; i<=10;{
}

一种是for range用法:
for range对字符串、数组、切片等进行迭代输出元素

for key,value := range nums{
	fmt.Println(key, value)
} 

for _,value :=range nums{
	fmt.Println(value)
}

2.defer

defer用来推迟调用
defer语句会将函数推迟到外层函数返回之后执行。
推迟调用的函数会立即求值,但直到外层函数返回之前该函数都不会被调用。

func main() {
	defer fmt.Println("world")

	fmt.Println("hello")
}
输出:hello world

defer栈
推迟的函数会被压入到一个栈中。当外层函数返回时,被推迟的函数会按照后进先出的顺序调用。

func main(){
	for i:=1; i<=10; i++ {
		defer fmt.Print(i, " ")
	}
	fmt.Println("counting...")
}
输出:
counting...
10 9 8 7 6 5 4 3 2 1

3.go指针

指针保存了值的内存地址。
var p *int 默认初值为nil
i:= 22
p = &i

func main(){
	i, j := 22, 100

	p := &i //间接引用/重定向
	fmt.Println( *p ) //22
	*p = 9 
	fmt.Println(i)//9

	p = &j 
	*p = *p /365
	fmt.Println( j )//0
}

4.结构体

一个结构体(struct)就是一组字段(field)。
用花括号{}赋值。

type Ocr struct {
	uid int
	fid int
	content string 
}

func main(){
	o1 := Ocr{1000001, 01, "995与生活"}

	fmt.Println(o1)
}

输出:
{1000001 1 995与生活}

5.数组

var a [2]string
a[0] = “hello”
a[1] = “world”

week := [6]int{1,2,3,4,5,6,7}

6.切片 比数组更常用

week[0:2]

7.range?? 没搞懂

8.map 键值映射

map[键类型]值类型
func main() {
	animal := make(map[string]int)//make生成空间

	animal ["猫"] = 2
	animal ["狗"] = 5
	animal ["猪"] = 1
	fmt.Println(animal )
	delete(animal, "猪")
	fmt.Println(animal)
	fmt.Println(animal["狗"])
}
进阶(一)

1.flag包

参数处理功能: 接收命令行参数,并将参数传递到代码中的变量。

https://blog.csdn.net/boling_cavalry/article/details/87901677

由以下代码可见,将命令行输入的参数传递到代码中的变量主要有两种方式:
第一种:StringVar和IntVar等方法,第一个参数是变量的地址;
第二种:String和Int等方法,将入参的值存入一个变量中,再将此变量的地址作为返回值返回;

func init() {
package main

import (
  "flag"
  "fmt"
)

//声明变量用于接收命令行传入的参数值
var (
  name string
  age int
  address *string
  id *int
)

func init() {
  //通过传入变量地址的方式,绑定命令行参数到string变量
  flag.StringVar(&name,   //第一个参数:存放值的参数地址
                 "name",  //第二个参数:命令行参数的名称
                "匿名",    //第三个参数:命令行不输入时的默认值
                "您的姓名") //第四个参数:该参数的描述信息,help命令时会显示
  
  //通过传入变量地址的方式,绑定命令行参数到int变量
  flag.IntVar(&age,        //第一个参数:存放值的参数地址
              "age",       //第二个参数:命令行参数的名称
              -1,          //第三个参数:命令行不输入时的默认值
              "您的年龄")   //第四个参数:该参数的描述信息,help命令时会显示
  
  //和前面两个变量的获取方式不同,这个api没有传入变量地址,而是把命令行参数值的地址返回了
  address = flag.String("address", //第一个参数:命令行参数的名称
                           "未知",     //第二个参数:命令行不输入时的默认值
                          "您的住址")   //第三个参数:该参数的描述信息,help命令时会显示

  id = flag.Int("id", //第一个参数:命令行参数的名称
                           -1,     //第二个参数:命令行不输入时的默认值
                          "身份ID")   //第三个参数:该参数的描述信息,help命令时会显示
}

func main() {
  //处理入参
  flag.Parse()

  //入参已经被赋值给各个变量,可以使用了
  fmt.Printf("%s您好, 您的年龄:%d, 您的住址:%s, 您的ID:%d\n\n", name, age, *address, *id)

  fmt.Println("---遍历有输入的参数(开始)---")

  //Visit方法会遍历有输入的参数,flag.Flag可以将参数的名称、值、默认值、描述等内容取到
  flag.Visit(func(f *flag.Flag){
    fmt.Printf("参数名[%s], 参数值[%s], 默认值[%s], 描述信息[%s]\n", f.Name, f.Value, f.DefValue, f.Usage)
  })
  fmt.Println("---遍历有输入的参数(结束)---\n")

  fmt.Println("---遍历所有的参数(开始)---")
  //VisitAll方法会遍历所有定义的参数(包括没有在命令行输入的),flag.Flag可以将参数的名称、值、默认值、描述等内容取到
  flag.VisitAll(func(f *flag.Flag){
    fmt.Printf("参数名[%s], 参数值[%s], 默认值[%s], 描述信息[%s]\n", f.Name, f.Value, f.DefValue, f.Usage)
  })
  fmt.Println("---遍历所有的参数(结束)---\n")
}

注意

1、go可以i++,不可以++i