• Go常用命令与基础语法


    在这里插入图片描述

    Go常用命令

    先来看看go的命令有哪些:

    The commands are:
    
            bug         start a bug report  #开始反馈bug 
            build       compile packages and dependencies #编译打包
            clean       remove object files and cached files  #移除文件和缓存文件
            doc         show documentation for package or symbol
            env         print Go environment information
            fix         update packages to use new APIs # 更新包下为最新API
            fmt         gofmt (reformat) package sources  # go的格式化 源码
            generate    generate Go files by processing source 
            get         add dependencies to current module and install them
            install     compile and install packages and dependencies
            list        list packages or modules
            mod         module maintenance
            work        workspace maintenance
            run         compile and run Go program
            test        test packages
            tool        run specified go tool
            version     print Go version
            vet         report likely mistakes in packages
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    go bug 命令: 会打开一个网址,来反馈bug,

    go build 命令:会将.go文件打包,打包后的是精简的代码,只包含用到的代码,对于没用到的不会被打包;
    在这里插入图片描述

    go clean 移除打包好的文件
    在这里插入图片描述
    go env 查看go环境设置

    D:\GoData\three>go env
    set GO111MODULE=
    set GOARCH=amd64
    set GOBIN=
    set GOCACHE=C:\Users\Gavin\AppData\Local\go-build
    set GOENV=C:\Users\Gavin\AppData\Roaming\go\env
    set GOEXE=.exe
    set GOEXPERIMENT=
    set GOFLAGS=
    set GOHOSTARCH=amd64
    set GOHOSTOS=windows
    set GOINSECURE=
    set GOMODCACHE=C:\Users\Gavin\go\pkg\mod
    set GONOPROXY=
    set GONOSUMDB=
    set GOOS=windows
    set GOPATH=C:\Users\Gavin\go
    set GOPRIVATE=
    set GOPROXY=https://proxy.golang.org,direct
    set GOROOT=D:\Program Files\Go
    set GOSUMDB=sum.golang.org
    set GOTMPDIR=
    set GOTOOLDIR=D:\Program Files\Go\pkg\tool\windows_amd64
    set GOVCS=
    set GOVERSION=go1.19
    set GCCGO=gccgo
    set GOAMD64=v1
    set AR=ar
    set CC=gcc
    set CXX=g++
    set CGO_ENABLED=1
    set GOMOD=D:\GoData\go.mod
    set GOWORK=
    set CGO_CFLAGS=-g -O2
    set CGO_CPPFLAGS=
    set CGO_CXXFLAGS=-g -O2
    set CGO_FFLAGS=-g -O2
    set CGO_LDFLAGS=-g -O2
    set PKG_CONFIG=pkg-config
    set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=C:\Users\Gavin\AppData\Local\Temp\go-build1709109560=/tmp/go-build -gno-record-gcc-switches
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    go fmt 包名 : 格式化包下所有的代码格式
    在这里插入图片描述

    go install **.go将go文件加入gopath下的bin包中以便可以直接访问;
    这里gopath 是自己指定的,也可以是默认的,这要看自己的设置了;

    系统设置的得gopath环境变量 :
    在这里插入图片描述

    在这里插入图片描述
    go get **包 对当前包添加依赖并安装这些依赖

    go vet 对静态代码做检查
    在这里插入图片描述
    go doc 包名 查看包下的帮助文档(注释)

    在这里插入图片描述

    Go基础语法

    go 变量,常量,自定义类型,包,函数名的命名方式
    必须遵守以下规则:
    1,首字母可以是任意Unicode字符或下划线
    2,首字母外的部分可以是Unicode字符,下划线或者数字
    3,名字的长度没什么限制
    在这里插入图片描述
    理论上可以用汉字来表示变量或者方法名,但是会比较晦涩难懂啊,别这样干!

    go中的关键字

    在这里插入图片描述

    保留字
    在这里插入图片描述

    go中的数据类型跟java中还是有一些差别的,
    int 在64位平台代表的是int64,32位平台代表的是int32,同理unit (无符号)

    使用go 代码查看平台的位数

    func Haha() { //函数
    	fmt.Printf("os arch %s,int size %d\n", runtime.GOARCH, strconv.IntSize)
    }
    
    • 1
    • 2
    • 3

    其他的基本跟java一样,详情可以参考一下之前写的java学习文档;

    变量,常量,字面量

    在这里插入图片描述
    数据类型初始化

    func Hello() {
    	var a string
    	fmt.Println("字符串初始化值" + a)
    	fmt.Println(unsafe.Sizeof(a))
    	var b float32
    	fmt.Println(b)
    	var c struct {
    	}
    	fmt.Println(c)
    	//类型推断
    	var d = 100
    	var e = 100.8
    	var f, gg = 12, 12
    	var h, i = "china", 8
    	fmt.Println(unsafe.Sizeof(d))
    	fmt.Println(unsafe.Sizeof(e))
    	fmt.Println(f + gg)
    	fmt.Println(h)
    	fmt.Println(i)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    函数内部的变量可以通过var声明,也可以通过一下方式声明:
    在这里插入图片描述
    匿名变量: 由下划线表示匿名变量,匿名变量不会占用命名空间,不会分配内存;
    函数内部可以有多个匿名变量,并且也不会冲突
    在这里插入图片描述
    声明多个变量/常量时:

    var x ,xx int 
    var ( //这种也可以
    	name string
    	age int64
    
    )
    
    const ( //常量声明时必须赋值
    	PI float32=3.14
    	E float64=2.71828
    
    )
    
    const (//这种方式表示 下面的值跟上面的一样
    	hh=1000
    	hhh
    	hhhhh
    )
    
    //一些奇怪的形式
    
    func helloW() {
    	const (
    		a = iota //下面的自动增加1
    		b
    		c
    		d
    	)
    	fmt.Println(a)//1
    	fmt.Println(b)//2
    	fmt.Println(c)//3
    	fmt.Println(d)//4
    }
     //那如果期间有别的值:比如
     func helloW2() {
    	const (
    		a = iota //下面的自动增加1
    		b
    		c=30
    		d
    	)
    	fmt.Println(a)//1
    	fmt.Println(b)//2
    	fmt.Println(c)//30
    	fmt.Println(d)//30
    }
     
    func helloWWW() {
    	const (
    		a = iota //下面的自动增加1
    		b=30
    		c=iota
    		d
    	)
    	fmt.Println(a)//0
    	fmt.Println(b)//30
    	fmt.Println(c)//2
    	fmt.Println(d)//3
    }
    
    func helloWWW() {
    	const (
    		a, b = iota + 1, iota + 2 
    		c, d
    		e, f
    	)
    	fmt.Println(a)//1
    	fmt.Println(b)//2
    	fmt.Println(c)//2
    	fmt.Println(d)//3
    	fmt.Println(e)//3
    	fmt.Println(f)//4
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    变量作用域

    变量分为全局变量,局部变量

    全局变量可以用var 来声明,访问的权限一句变量的首字母大小写来判断;

    // 声明全局变量
    var (
    	A     = 3  //大写字母,跨包可访问
    	b     = 12 //小子字母开头,本包可访问
    	Hello = "world"
    	 
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    如果是匿名变量,则不可以外包不能访问;

    // 声明全局变量
    var (
    	A     = 3  //大写字母,跨包可访问
    	b     = 12 //小子字母开头,本包可访问
    	Hello = "world"
    	_="Hello world"
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    如下图:
    在这里插入图片描述
    代码分析:

    在这里插入图片描述
    有一个跟java不同的地方:
    在这里插入图片描述
    所以个对比,就这样吧,人家就这么搞得;
    在这里插入图片描述

    代码块里的变量可以跟外面的变量名一样;

    既然可以冲突,那么全局变量跟局部变量会先使用哪一个呢?

    
    //全局变量只能用var声明
    func Four() string {
    	c := 999 //局部变量,这种只能在方法或者代码块里声明
    	{
    		c := 9090 //可以跟外面的变量冲突
    		haha := "troule"
    		fmt.Println(haha)
    		fmt.Println(c)
    		return haha
    	}
    
    	fmt.Println(c)
    	//fmt.Println(haha) //haha的作用域只在大括号内部
    	return Hello
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    查看如下代码:

    //全局变量
    var (
    	A = 100
    	c = 200
    )
    
    func main() {
    	{//局部变量
    		c := 222
    		fmt.Println(c) //222
    	}
    	fmt.Println(c) //200
    	{//局部变量
    		c := 10000
    		fmt.Println(c)//10000
    	}
    	fmt.Println(c)//200
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    运行结果可以看到, (如果是代码块中的,只在代码块中生效(内部与外部变量声明冲突时----根据作用域来进行实际作用)

    变量之间的比较

    先看一个案例:
    在这里插入图片描述
    在变量aa与bb进行比较时,编译时报错了;

    但是如果换成字面量,就可以

    var (
    	aa=10.0
    	bb=10
    )
    func main() {
    	//fmt.Printf("aa=bb是%t\n",aa==bb)
    
    	fmt.Printf("%t\n",10.0==10)//true
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    其中==只能比较对象地址,不能比较属性值是否相等,如果要比较内容的话
    go提供了一些方法,
    先来看一下go种通过自定义方法来实现比较

    var (
    	aa = 10
    	bb = 10
    	cc = 100000000
    	dd = 100000000
    )
    
    type Person struct { //定义一个结构体
    	name string
    	age  int
    }
    
     
    func PersonToString(name string, age int) *Person {
    	return &Person{ //Person结构体对应的值
    		name: "name",
    		age:  age,
    	}
    }
    func main() {
    
    	fmt.Printf("%t\n", 10.0 == 10)   //字面量
    	fmt.Printf("%t\n", cc == dd)     //变量类型一样
    	per1 := PersonToString("小明", 18) //一个结构体
    	per2 := PersonToString("小明", 18) //一个结构体
    	fmt.Println(per1 == per2)        //比较地址
    	fmt.Println(compare(per1, per2))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    这里有两个小知识点:
    * 和&

    在go种指针是一种类型,指向变量所在的内存单元(这里并不是内存地址,而是值;

    在变量名前加上*字符,比如 *per1,指向变量per1所在的内存单元-----值
    所以当我们使用* 在变量前时,这表示我们取得是变量的值;如下图所示:这是后我们取得是per的值
    在这里插入图片描述
    结果—>>
    在这里插入图片描述

    在变量前加上& 表示获取的是变量的地址-----16进制表示的一个值

    如下面的代码:

    	per1 := PersonToString("小明", 18) //一个结构体
    	per2 := PersonToString("小明", 18) //一个结构体
    
    	fmt.Println(&per1)
    	fmt.Println(&per2)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    go中提供的比较方法,当然这是大佬们早就提供好的,不算是官方的吧,直接拿来用,就不用重复造轮子了!

    首先我们通过 go的基本命令来安装这个包:

    go get -u com/google/go-cmp/cmp 如果链接失败,那么可以尝试改一下go的配置参数:

    这里使用的 Go 版本是 1.19
    将go的代理环境由 set GOPROXY=https://proxy.golang.org,direct
    改为 go env -w GOPROXY=https://goproxy.cn,direct
    记住做好原始参数备份,以免后期不必要的麻烦!!!

    改完之后应该安装cmp包很快!

    下面根据cmp包包装 一下方法:
    如下:

    package main
    
    import (
    	"fmt"
    	"github.com/google/go-cmp/cmp"
    	"reflect"
    )
    
    var (
    	A = 100
    	c = 200
    )
    
    var (
    	aa = 10
    	bb = 10
    	cc = 100000000
    	dd = 100000000
    )
    
    type Person struct { //定义一个结构体
    	Name string
    	Age  int
    }
    
    func NewPerson(name string, age int) *Person {
    	return &Person{ //Person结构体对应的值
    		Name: name,
    		Age:  age,
    	}
    }
    func main() {
    
    	fmt.Printf("%t\n", 10.0 == 10)   //字面量
    	fmt.Printf("%t\n", cc == dd)     //变量类型一样
    	per1 := NewPerson("小明", 18) //一个结构体
    	per2 := NewPerson("小明", 18) //一个结构体
    
    	fmt.Println(&per1)
    	fmt.Println(&per2)
    	fmt.Println(per1)
    	fmt.Println(per2)
    	fmt.Println(*per1)
    	fmt.Println(*per2)
    
    	fmt.Println(per1 == per2)        //比较地址
    	fmt.Println(compare(per1, per2)) //通过自定义方法比较
    
    	fmt.Println(CompareEqual(per1, per2))
    	fmt.Println(CompareDeep(per1, per2))
    
    }
    
    // 编写比较方法
    func compare(p1, p2 *Person) bool {
    	if p1 == p2 {
    		return true
    	}
    	if (p1.Name == p2.Name) && (p1.Age == p2.Age) {
    		return true
    	}
    	return false
    }
    
    //使用工具包中的方法--比较内容
    
    func CompareEqual(p1, p2 *Person) bool {
    	if cmp.Equal(p1, p2) {
    		return true
    	}
    	return false
    
    }
    
    func CompareDeep(p1, p2 *Person) bool {
    
    	if reflect.DeepEqual(p1, p2) {
    		return true
    	}
    	return false
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    注意:
    在这里插入图片描述

    变量的访问:

    当我们在一个go文件中定义了一些变量,

    package first
    
    var (
    	A = 1000
    	a = "hello"
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    我们要在别的包中访问这些变量,我们知道,如果变量首字母为大写,那么可以通过包名.变量名访问,如果变量为小写字母,那么我们在别的包中是没法直接访问的,我们可以通过包名.变量名来访问;

    那要是首字母为小写的:
    我们可以通过调用方法来实现访问---->>注意:该方法要可以被别的包访问到;

    fmt.Println(first.Fun())
    
    • 1

    Go语言中是以package来进行一些访问的划分的;

    简单的说,go中没有具体的文件区分,而是以package来区分的;

  • 相关阅读:
    MCE 产品发表高分文章锦集
    微信小程序备案流程操作详解,值得收藏
    字节面试也会问SPI机制?
    【导航】FreeRTOS学习专栏目录 【快速跳转】
    攻防世界WEB练习区(backup、cookie、disabled_button)
    Python实现FPGA板卡仿真验证方法
    前后端分离-图书价格排序案例、后端返回图片地址显示在组件上(打印图片地址)
    SpringMVC 学习(九)之拦截器
    springBoot + netty搭建高性能 websocket 服务 & 性能测试
    c++ this
  • 原文地址:https://blog.csdn.net/weixin_54061333/article/details/126189991