GO笔记持续更新

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

go build hello.go   编译文件生成hello.exe可执行文件
go run hello.go     编译,运行命令


同一个目录下,自定义的函数名不能相同
fmt.len()函数:计算字符串的长度(一个汉字占3个字节)
fmt.Scan()函数:输入
fmt.Scanf()函数:格式化输入

1、Windoes下环境配置:
   (1)打开网址下载安装包:https://golang.google.cn/dl/
   (2)使用命令:查看是否安装成功
      go version 查看版本
      go env     查看环境变量
   (3)设置工作空间,Go语言的项目路径
      a、新建文件夹:mygo (我的文件夹位置:C:\mygo\src)
      b、新建环境变量 -> 系统变量:变量名:GOPATH , 变量值:C:\mygo
      c、修改环境变量 -> 用户变量:变量名:GOPATH , 变量值:C:\mygo (如果不存在,就新建)

2、Printf与Println的区别:
   (1)Println:打印并换行
   (2)Printf:格式化输出,printf("a = %d", a)
   (3)格式化输出:
		%c	把输入的数字按照ASCII码相应转换为对应的字符输出
        %d      整型占位符
        %f	浮点数占位符
        %s      字符串占位符
        %T      打印变量的类型
        %v      自动格式匹配输出

3、数据类型
   (1)数字类型:整型(int:有符号整型,uint:无符号整型),浮点型float32、float64
   (2)字符类型:byte,单引号( var a byte = 'a' ),字符串是由一个或多个字符组成的
   (3)字符串类型:string,双引号( var a string = "a" ),字符串的拼接用 + 号
   (4)布尔型:bool
   (5)派生类型:
	a、指针类型(Pointer)
	b、数组类型
	c、结构体类型(struct)
	d、Channel 类型
	e、函数类型
	f、切片类型(动态数组)
	g、接口类型(interface)
	h、Map 类型(字典类型)

4、Go语言中,变量名,常量名,函数名,类型名,语句标号和包名,必须以字母或下划线开头。A和a是两个不同的名字(区分大小写)

5、变量
   (1)变量的声明:关键字 变量名 数据类型( var a int )
   (2)变量的赋值:变量名 = 变量值       ( a = 10 或者 var a int = 10)
   (3)变量的声明与赋值常用方法:
	方式一:
		var a int = 1
		var b float64 = 3.14
	方式二:
		var (
		    a int = 1
		    b float64 = 3.14
		)
        方式三:自动推导(这种形式,只能在函数体内来定义变量,在函数体外会报错)
		方法一:
		    a,b := 1,3.14
		方法二:
  		    var (
		        a = 1
		        b = 3.14
		    )
6、常量
   常量的声明:关键字 变量名 数据类型( const i int = 10)
   iota常量自动生成器,给常量赋值使用,每次调用自动加1,
   const (
        a = iota   // 0
	b = iota   // 1
	c = iota   // 2
   )

7、类型转换:数据类型(变量),int(a), float64(a)

8、运算符
   (1)算术运算符:+, -, *, /, %取余, ++后自增(没有前自增), --后自减(没有前自减)
   (2)关系运算符:==,!=,<, >, <=, >=
   (3)逻辑运算符:与或非,&&, \, !
   (4)位运算符:按位与&,按位或\,异或^,左移<<,右移>>	
   (5)赋值运算符:=,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,\
   (6)其他运算符:&a:变量a的地址,*&a:变量a的地址,所指向内存的值

9、流程控制:if-else语句更适合于对区间(范围)的判断,而switch语句更适合于对离散值的判断
   (1)if语句:
	var a int=3
	if a == 3{//条件表达式没有括号
	    fmt.Println("a==3")
	}

	//支持初始化表达式和条件表达式一起写,用分号分隔
	if b:= 3;b == 3{
	    fmt.Println("b==3")
	}

   (2)if ... else语句:
	if a:=3; a==4{
	    fmt.Println("a==4")
	}else{
	    //左大括号必须和条件语句或else在同一行
	    fmt.Println("a!=4")
	}	

   (3)if ... else if ... else语句:
	if a:=3; a>3 {
	    fmt.Println("a>3")
	} else if a<3 {
	    fmt.Println("a<3")
	} else if a==3 {
	    fmt.Println("a==3")
	} else {
	    fmt.Println("error")
	}

   (4)switch语句:Go里面switch默认相当于每个case最后带有break,匹配成功后不会自动向下执行其他case,而是跳出整个switch,但是可以使用fallthrough强制执行后面的case代码:
       var score int = 90
       switch score {
	  case 90:
	    fmt.Println("A")
	    //fallthrough
	  case 80:
	    fmt.Println("B")
	    //fallthrough
	  case 50,60,70:
	    fmt.Println("C")
	    //fallthrough
	  default:
	    fmt.Println("D")
	}

10、循环语句
   (1)for循环
	var i,sum int

	for i = 1; i <= 10; i++ {
	    sum+=i
	}
	fmt.Println("sum=",sum)
   (2)for ... range
	关键字 range 会返回两个值,第一个返回值是元素的数组下标(key),第二个返回值是元素的值(value):

	s := "abc"
	// a.打印key, value值
	for key, value := range s{ // 支持string/array/slice/map
	    fmt.Println(key, value)
	}
        // b.只打印键值key
	for key := range s{
	    fmt.Println(key)
	}
	for key, _ := range s{
	    fmt.Println(key)
	}
        // c.只打印value值
	for _, value := range s{
	    fmt.Println(value)
	}
   (3)for循环嵌套:外层循环一个,内层循环一周
      var i,j int
      for i = 0; i < 5; i++ {
         for j = 0; j < 5; j++ {
            fmt.Println(i,j)
         }
      }
      在循环里面有两个关键操作break和continue,break操作是跳出当前循环,continue是跳过本次循环 
   (4)goto语句只能跳转到当前函数内定义的标签:
	func main() {
	    for i := 0; i < 5; i++{
		for{
		    fmt.Println(i)
		    gotoLABEL//跳转到标签LABEL,从标签处,执行代码
		}
	    }

	    fmt.Println("thisistest")

	LABEL:
	    fmt.Println("itisover")
	}


11、数组
  (1)数组定义:(数组定义不使用会报错,定义了数组就得用它)
    关键字 数组名 [数组长度] 数组元素类型 
    var    arr    [10]      int
  (2)数组赋值:var arr [2]int 
    1、通过下标来进行赋值
      arr[0] = 6
      arr[1] = 7
      arr[2] = 8
    2、for循环完成数组的赋值与输出
      for i := 0; i < len(a); i++ {
          a[i] = i + 1
      }
      // 数组输出
      for i,data := range a {
          //fmt.Println("下标:",i)
          fmt.Println("元素值:",data)
      }
  (3)数组初始化:在定义数组时就可以对其赋值
    1、全部初始化, 
        var a [5]int = [5]int{1,2,3,4,5}
    2、自动推导,   
        b := [5]int{1,2,3,4,5}
    3、部分初始化,没有初始化的部分 默认为0,  
        c := [5]int{1,2,3}
    4、指定某个元素初始化, 
        d := [5]int{2:10, 4:20}
    5、通过初始化确定长度,
        f:=[...]int{1,2,3}

make()函数的作用,给切片,字典等初始化,在内存中开辟一块空间
12、切片(slice):可以将切片理解成"动态数组",建议,以后开发中使用切片来代替数组
(1)切片与数组的定义很相似(在我看来把数组的长度10去掉,数组就变成了切片,这样就导致了切片的长度不固定)
	数组定义:var arr [10]int    # 数组定义完,长度是固定的,不能使用append()来追加元素
	切片定义:var sli []int      # 切片的长度是不固定的,可以使用append()来追加元素
(2)切片的初始化(给切片在内存中开辟一个空间)
    方式一:定义完成后直接进行初始化
        var sli []int = []int{1,2,3,4,5}
        var sli = []int{1,2,3,4,5}
        sli := []int{1,2,3,4,5}
    方式二:使用make()函数初始化切片,可以自定义切片的长度和容量
        // 声明一个切片,未初始化前没有内存空间,所以为nil(nil切片不能直接赋值),返回值为空切片
        var sli []string
        // 初始化切片(初始化切片的长度和容量),初始化以后就有了自己的内存空间,所以不是nil(非nil切片可以直接赋值),返回值为空切片
        sli = make([]string, 5, 10)
        // 此时可以给切片直接赋值
        sli[0] = "我"
        sli[1] = "爱"
        sli[2] = "你"
    make()函数在切片中的使用:
        make(切片类型, 长度, 容量)
        var sli []int = make([]int, 5, 10)
        var sli = make([]int, 5, 10)
        sli := make([]int, 5, 10)
        # 长度是已经初始化赋值的空间,len(sli)计算切片,数组,字符串等的长度
        # 容量是已经开辟的总空间,包括已经初始化的空间和空闲的空间,cap(sli)计算切片的容量
(3)获取切片的元素
	sli := []int{1,2,3,4,5}
	方式一:通过下标直接获取,sli[0], sli[1], sli[2] ...
	方式二:使用range方式输出:
		for key,value := range sli {
		    fmt.Println(value)
		}
(4)切片截取
	sli := []int{6,7,8,9,10}
	s := sli[1:3]		[起点下标:终点下标]
		打印结果 ==> [7 8](包括起点的值,不包括终点的值,长度为3-1=2,长度即取出的数据的个数)
	总结:
		sli := []int{6,7,8,9,10}
		s1 := sli[1:]               [7 8 9 10]
		s2 := sli[:4]               [6 7 8 9]
		s3 := sli[1:3]              [7 8]
		s4 := sli[1:3:4]            [7 8]

		sli[zero:]	        zero下标往后所对应的元素,包含zero所对应的元素
		sli[:end]	        end下标往前所对应的元素,不包含end所对应的元素
		sli[zero:end]	    索引位置zero到end所对应的元素,包括起点的值,不包括终点的值
		sli[zero:end:max]	第三个参数定义的是截取后获得切片的容量,可以随便定义,生成切片的长度len=high-zero,容量cap=max-zero,s4容量是4,只不过有一块区域是空闲的。
(5)append()函数
	# 初始化切片
	sli := []int{1,2,3}
	# 通过append函数向切片中追加数据
	sli = append(sli,5,6,7)
	fmt.Println(sli)
	最终输出结果为:[1 2 3 5 6 7]
(6)copy()函数:将第二个切片里面的元素,拷贝到第一个切片中
	基本语法:copy(切片1,切片2)
		将slice1切片中两个元素拷贝到slice2元素中相同的位置,而slice1中原有的元素被替换掉,在进行拷贝时,拷贝的长度为两个slice中长度较小的长度值
			slice1 := []int{1, 2}
			slice2 := []int{6, 6, 6, 6, 6}
			copy{slice2, slice1}
			打印结果: [1 2 6 6 6]

			slice1 := []int{1, 2}
			slice2 := []int{6, 6, 6, 6, 6}
			// 位置对调
			copy{slice1, slice2}
			打印结果: [6 6]
			
13、字典(map)
(1)定义字典:使用map关键字
    var dict map[键(key)的类型]值的类型
    var dict map[int]string
(2)字典的初始化(给字典在内存中开辟一个空间)
    方式一:定义完成后直接进行初始化
        dict := map[int]string{ 1:"小丁", 2:"小红" }
    方式二:使用make()函数初始化字典,make(map[int]string)
        // 声明一个字典,未初始化前没有内存空间,所以为nil(nil切片不能直接赋值),返回值为空字典
        var dict map[string]string
        // 初始化字典,初始化以后就有了自己的内存空间,所以不是nil(非nil的字典可以直接赋值),返回值为空字典
        dict = make(map[string]string)
        // 此时可以给字典直接赋值
        dict [ "France" ] = "巴黎"
        dict [ "Italy" ] = "罗马"
        dict [ "Japan" ] = "东京"
    make()函数在字典中的使用:make(map[int]string)
(3)获取字典的元素:map是无序的,我们无法决定它的返回顺序,所以,每次打印结果的顺序有可能不同
    方法一:直接通过键获取值
        dict := map[int]string{ 1:"小丁", 2:"小红" }
        fmt.Println(dict[1])
        fmt.Println(dict[2])
    方法二:通过循环遍历的方式输出
        dict := map[int]string{ 1:"小丁", 2:"小红" }
        for key,value := range dict {
            fmt.Println(key)
            fmt.Println(value)
        }
(4)delete()函数:
    # 删除map中的某个元素:根据字典中的键,删除对应的元素
    dict := map[int]string{ 1:"小丁", 2:"小红" }
    # 删除key=1的value值
    delete(dict,1)
(5)查看元素在集合中是否存在
	dict := map[int]string{ 1:"小丁", 2:"小红" }
	value, ok := dict [ "1" ]
	# 第一个返回值为key所对应的value, 第二个返回值为key是否存在的条件,存在ok为true
	if (ok==true) {
	    fmt.Println("key存在", value)
	} else {
		fmt.Println("key不存在")
	}
	
14、指针:指针是用来存储变量在内存中的地址,可以理解为,指针就是用来专门存地址的变量
  (1)指针声明格式如下:(一个指针变量通常缩写为 ptr)
    关键字 指针变量名  *指向值的类型
    var ip *int           /* 指向整型*/
    var fp *float32       /* 指向浮点型 */
  (2)指针赋值
    方式一:(变量地址赋值给指针)
      # 声明变量
      var a int= 20
      # 声明指针
      var ip *int
      # 指针赋值(变量地址赋值给指针)
      ip = &a
    方式二:(通过new()函数来赋值)
      # 声明指针
      var p *int
      # 把new()创建的内存空间地址赋值给指针p
      p = new(int)   # new(int)作用就是创建一个整型大小(4字节)的空间
      # 操作指针所指向的内存值
      *p = 60
      fmt.Println(*p)
    实例解析
    # 声明变量a, a在内存中开辟了一块空间,a的值,a的地址
    var a int= 20
    # 声明一个指针,用来存储变量在内存中的地址
    var ip *int
    # 指针变量存储的是a的地址,指针赋值
    ip = &a  (取地址符&,放到一个变量前就会返回变量的内存地址)
    # 获取指针,指向的值
    fmt.Printf("*ip 变量的值: %d\n", *ip )
    # 可以直接操作所指向的值
    *ip = 66
  (3)指针数组:一个数组中存储的都是指针(也就是地址),也就是一个存储了地址的数组。
    # 指针数组定义
    var p [2] *int
    # 数组赋值
    var i int = 10
    var j int = 20
    p[0] = &i
    p[1] = &j
    # 打印指针
    fmt.Println(p)
    fmt.Println(p[0])
    fmt.Println(*p[0])
  (4)值传递和引用传递
    值传递:传递的是变量在内存中的值
    引用传递:传递的是变量在内存中的地址
    
15、结构体(struct):存储同一类型数据或不同类型数据的集合
 Go 语言中的「结构体」相当于其他语言中的「类」或「对象」的东西,
 Go 语言中没有类」或「对象」;
	(1)定义结构体Student:(使用关键词type和struct)
		type Student struct {
		    id int
			name String
			sex byte
			age int
		}
	(2)定义好结构,就可以用它了,用它来声明变量(Student1),语法格式如下:
        方法一:
            var Student1 Student = Student{1, "小红", 'w', 18}
            Student1 := Student{1, "小红", 'w', 18}
        方法二:(忽略的字段为 0 或 空)
            var Student1 Student = Student{name: "小丁", age: 20}
            Student1 := Student{name: "小丁", age: 20}
	(3)访问结构体成员,结构体.成员名(Book1.title)
		package main

		import "fmt"
		# 1、定义结构体
		type Books struct {
			title string
			author string
			book_id int
		}
		func main() {
			# 2、声明变量 Book1 为 Books 类型
			var Book1 Books
			# 2、声明变量 Book2 为 Books 类型
			var Book2 Books

			# 3、结构体初始化(变量赋值)
			Book1.title = "Go教程"
			Book1.author = "kai"
			Book1.book_id = 6495407

			Book2.title = "Python教程"
			Book2.author = "zhao"
			Book2.book_id = 6495700
		}
		(4)结构体数组:
		type Student struct {
            id int
            name String
            age int
		}
		# 结构体数组
		student := []Student{
			Student{
				10,
				"小红",
				18,
			},
			Student{
				11,
				"小乙",
				20,
			},
			Student{
				12,
				"小丁",
				20,
			},
		}
		# 通过循环的方式,将结构体数组中的每一项进行输出。
		for i := 0; i<len(student); i++ {
			fmt.Println(student[i].name)
		}
		# 结构体struct 类似于类
16、go函数定义,格式如下:
func funcName(input1 type1, input2 type2) (output1 type1, output2 type2) {
    // 这里是处理逻辑代码
    // 返回多个值
    return value1, value2
}















 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页