go语言基本结构说明

96 阅读5分钟

变量

变量定义规范
/*
 go中单引号只允许给一个字符使用;
 go变量命名规则:任何需要对外暴露的名字(可以被外部包的代码所使用)必须以大写字母开头;不需要对外暴露的q则应该以小写字母开头,即则对包外是不可见的,但是他们在整个包的内部是可见并且可用的,建议使用驼峰体命名
    首字母根据访问控制原则大写或者小写,但遇到特有名词时,需要遵循以下规则:
    如果变量为私有,且特有名词为首个单词,则使用小写,如 apiClient
    其它情况都应当使用该名词原有的写法,如 APIClient、repoID、UserID
    错误示例:UrlArray,应该写成 urlArray 或者 URLArray
    若变量类型为 bool 类型,则名称应以 Has, Is, Can 或 Allow 开头
 文件名使用下划线的形式。
 go有非常严格的强类型特征
 每个变量在程序中都有一定的作用范围称为作用域。如果一个变量在函数外声明则被认为是全局变量,可以在整个包甚至外部包(变量名以大写字母开头)使用;在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,函数的参数和返回值变量也是局部变量。
*/
​
变量定义和使用
// 变量定义未使用会报错
// 方式一:完整定义----> var 变量名 变量类型 = 初始值
var new_age int = 30  // 完整方式声明变量并赋值
// 方式二:类型推导---->  var 变量名 = 初始值
var age1 = 40
// 方式三:简略声明 --->  变量名 := 初始值
c1 := complex(5, 7)
// 方式四:声明多个的两种方法
var (
        name = "hector"
        age2 = 18
        gender = "male"
    )
name1, age3 := "bili", 18
​
变量类型
// 数字类型:int和int8,int16等的区别就是数值范围不一样,int后边的数值代表二进制数的位,且第一位表示正负。int分平台,在三十二位机器表示int32,六十四位机器表示int64;无符号整型uint// 浮点型:float32、float64的区别就是精度不同。
// 复数:complex(5, 7)分为实部和虚部
// 字符串用双引号和反引号包裹,反引号可支持换行
// 以及bool、数组(array)、切片(slice)、map

常量和iota

// 常量的定义 const 常量名 类型 = 初始值  或者 const 常量名 = 初始值
// iota 自增常量, iota只要不换行就不会自增
    const (
        a = iota
        b = 100
        c
        d = iota  // 每一行都会自增
        )
    fmt.Println(a,b,c,d)  //  0 100 100 3
// iota每换一行都会自增1,无论是否使用

函数基础

/*
go中包是最小单位,同一个包下不能存在相同名的函数
函数调用中实参只有位置参数,没有关键字参数,有几个返回值用几个变量来接受,_表示忽略返回值
    func 函数名(形参 参数类型, 形参 参数类型) (返回值类型) {
        函数体代码和缩进无关
    }
*/func main()  {
    test()
    res := test1(2,5,"gfdg")
    fmt.Println(res)
    res2, _ :=test2(2,9,"wqre","3qwr")
    fmt.Println(res2)
}
​
func test()  {
    fmt.Println("woshitest")
}
​
func test1(a,b int, c string) int {
    fmt.Println(a, b, c)
    d := a + b
    return d
}
​
func test2(a,b int, c,d string) (int, string) {
    e:= a+b
    f:=c+d
    return e,f
}
/*
1、可变长参数:...可以穿的任意长度的参数,变长参数接收到的是切片类型 
func main() {
    test(2,3,5)
}
func test6(a...int) {
    fmt.Println(a)  // [2 4 5]
    fmt.Printf("%T",a)  // []int
}
    
2.1、基本匿名函数(需要定义在函数内部),同时匿名函数也可不执行用变量接受匿名函数
func main()  {
​
    func (){
        fmt.Println("匿名函数")
    }()
    
    res := func(a, b int) int {
        return a +b
    }
    fmt.Println("res的类型是:%T", res)
    fmt.Println(res(2,5))
}
​
2.2、有参数的匿名函数
func(a, b int) {
        fmt.Println(a,b)
    }(1,2)
2.3、带返回值的匿名函数
    sum :=func(a,b int)int{
        return a+b
    }(2,4)
*/// 函数也是一种类型,函数可以当参数传递也可以当做返回值,且函数的类型为func()
func test8() func() {    // 函数做返回值
    name := "test"
    a := func() {
        fmt.Println(name)
    }
    return a
}
​
func test9(x,y int) int {   // 函数做参数
    return x+y
}
func test10(x,y int ,sum func(int, int) int) int {
    return sum(x, y)
}
func main(){
    res := test10(1,2, test9)
    fmt.Println(ret)
}
​
// 匿名函数
func main() {
    ret := test11(1,"sfs")
    q := ret(1,5)
    fmt.Println("必报内函数执行返回值%s", q)      
}
​
func test11(b int, s string) func(c, d int) int {
    name := "hector"
    a := func(c, d int) int {
        fmt.Println(c+d)
        fmt.Println("姓名是%s", name)
        fmt.Println("b:%s, s:%s", b, s)
        return c+d
    }
    return a
}
​
// 类型重命名
type Myfunc func(a, int, func()) (int, func())
​

go path和新版本go moduls区别

GoPath是Golang的工作空间,所有的Go文件,都需要放在GoPath下的src目录下才能够编译运行,所以我提议不要直接配置全局的GoPath目录,否则会非常难以管理所有的Golang项目。我们在项目中使用第三方类库的时候,可以使用go get命令从网下直接拉去第三方类库的包,而拉取下来的包就会直接下载到我们的GoPath目录下的src包下。这样就会导致一个问题我们自己的golang代码与第三方的golang代码管理混乱;同样我们可以给不同的项目设置不同的gopath,这样是可以方便管理但于此同时不同项目使用的依赖会出现下载重复的情况,占用磁盘空间。
为了解决GOPATH的问题,因此官方在1.11开始推出了Go Modules的功能,Go Modules解决方式很像是Java看到Maven的做法。
gomod可以设置三种不同的值:
    auto:默认值,gomod是否启用依赖下面两个条件:
        1、项目目录不在GOPATH/src下
        2、项目中是否含有go.mod文件
    on:使用gomod不去GOPATH下找依赖
    off:不适用gomod,会去GOPATH下寻找依赖
目前1.16版本默认将这个参数设置成on。
初始化mod:go mod init <module name>:<module name>可填可不填,不填的话预设就是默认的文件名称go.mod