go语言基础
go语言基础
1 go环境变量
1.1 GO ROOT
类似于快捷方式
1.2 GO PATH
go 命令操作的目录,比如安装的包啥的
GOPATH包含了有哪些结构:
代码解读
复制代码.(GOPATH的路径)
├── bin
├── pkg
└── src
- src存放的是我们的我们项目的源代码(比如:.go .c .h .s等)
- pkg编译时生成的中间文件(比如:.a)
- bin编译后生成的可执行文件
在Golang的项目中,所有的源码都是放在/src中,一般的做法是一个目录一个项目。
1.2.1 全局 path
通用的包
1.2.2 项目 path
项目特有的包,一般会为每个项目单独设置一个项目的path
2 go 变量声明
go导入包,包的名字和目录的名字不要求一致【习惯上还是一致的】
2.1 变量定义
var a int
var b float32
var c, d float64
e, f := 9, 10
var g = "Ricardo"
go中的变量声明,只需要一个 var
关键字,需要将这个变量的类型写在变量名字的后面。允许一次定义多个变量并且同时赋值。
另外一种方式就是使用 :=
,y也就是赋值的符号,不需要写var关键字,go可以自己根据后面的变量值,自己推到出相关变量的类型。
go语言是一个强类型的语言,所有变量都必须要有类型。变量只能存储特定类型的数据。
2.2 匿名变量
标识符为_(下划线)的变量,是系统保留的匿名变量,在赋值后,会被立即释放,称之为匿名变量。其作用是变量占位符,对其变量赋值结构。通常会在批量赋值时使用。
例如,函数返回多个值,我们仅仅需要其中部分,则不需要的使用_来占位
func main() {// 调用函数,仅仅需要第二个返回值,第一,三使用匿名变量占位_, v, _ := getData()fmt.Println(v)
}
// 返回两个值的函数
func getData() (int, int, int) {// 返回3个值return 2, 4, 8
}
2.3 常量
在Golang的常量定义中,使用const
关键字,并且不能使用:=
标识符。
3 判断
在go语言当中,相比于其他语言唯一不一样的就是不需要小括号,大括号还是必须的,比如:
func pow(x, n, lim float64) float64 {if v := math.Pow(x, n); v < lim {return v}return lim
}
go语言还可以在判断条件之前执行一个简单的语句,需要使用 ;
进行分隔。
4 循环
在go中,只有一种循环,for循环
和判断语句一样,for循环也是没有小括号的。
sum := 0for i := 0; i < 10; i++ {sum += i}fmt.Println(sum)
转换成while循环【初始化语句和后置语句排除】:
sum = 0for sum < 100 {sum += sum}
while(true) 循环
for{
}
5 函数
5.1 函数的定义
在Golang的函数定义中,所有的函数都以func
开头,并且Golang命名推荐使用驼峰命名法。
注意,在Golang的函数中,如果首字母是小写,则只能在包内使用;如果首字母是大写,则可以在包外被引入使用。可以理解为,使用小写的函数,是
private
的,使用大写的函数,是public
的。
在Golang的函数定义中,一样可以不接受参数,或者接受多个参数。而在参数的定义过程中,也是按照定义变量的格式,先定义变量名,再声明变量类型。对于函数的返回类型,也是按照这样的格式,先写函数名,再写返回类型:
func add(x int, y int) int {return x + y
}
//变量如果是相同类型的参数,可以省略,上面的可以写成
func add(x, y int) int {return x + y
}
go对于函数的返回值,和c,java不太一样,golang可以返回多个返回值
func swap(a, b string)(string, string){return b, a
}
同时,对于函数的返回值,可以进行命名
func split(sum int) (x, y int) {x = sum * 4 / 9y = sum - xreturn
}
这个可以这样理解,首先在函数的顶部预先定义了一些变量的值,然后空的return
语句默认返回已经定义的变量。
5.2 defer
go的关键字
defer 语句会将函数推迟到外层函数返回之后执行。 推迟调用的函数其参数会立即求值,但直到外层函数返回前该函数都不会被调用。
示例:
func deferFunc() {defer fmt.Println("world")fmt.Println("hello")
}
执行效果:先打印“hello”,然后再打印“world”
可以考虑到的场景是,文件的关闭,或数据库连接的释放等,这样打开和关闭的代码写在一起,既可以使得代码更加的整洁,也可以防止出现开发者在写了长长的业务代码后,忘记关闭的情况。
6 指针
在Golang中,指针的用法和 C 是一样的。同样是用&
取地址,用*
取地址中的值。
但是,与 C 不同,Golang没有指针运算。
7 数组
在Golang中,数组的定义是这样的:
var a [10]int
这样做会将变量 a 声明为拥有 10 个整数的数组。
注意,在Golang中,数组的大小也同样和 C 语言一样不能改变。
7.1 切片
类似于python的切片,是左开右闭的。
num[1:4] //切出下标1到3的元素
func testSplit() {str := [4]string{"aaa","bbb","ccc","ddd",}fmt.Println(str)a := str[0:2]b := str[1:3]fmt.Println(a, b)b[0] = "XXX" //这里是对原数组进行修改,go的切片,并不是拷贝,而是定义新的指针指向了原来数组的内存空间fmt.Println(a, b)fmt.Println(str)
}
go的切片,并不是拷贝,而是定义新的指针指向了原来数组的内存空间,修改切片数组的值,也就是相应的修改了原始数组的值
- 切片并不存储任何数据,它只是描述了底层数组中的一段。
- 更改切片的元素会修改其底层数组中对应的元素。
- 与它共享底层数组的切片都会观测到这些修改。
7.2 make
切片可以用内建函数 make 来创建,这也是你创建动态数组的方式。
在此之前需要解释两个定义,len(长度)和cap(容量)。
len是数组的长度,指的是这个数组在定义的时候,所约定的长度。
cap是数组的容量,指的是底层数组的长度,也可以说是原数组在内存中的长度。
在前文中所提到的切片,如果我定义了一个str[0,0]的切片,此时的长度为0,但是容量依旧还是5。
make 函数会分配一个元素为零值的数组并返回一个引用了它的切片:
a := make([]int, 5) // len(a)=5
要指定它的容量,需向 make 传入第三个参数:
b := make([]int, 0, 5) // len(b)=0, cap(b)=5b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:] // len(b)=4, cap(b)=4
也就是说,make函数可以自定义切片的大小。用Java的话来说,他可以被重载。
有两种形式,如果只有两个参数,第一个参数是数组内元素的类型,第二个参数是数组的长度(此时长度和容量都为5)。
而如果有第三个参数,那么第三个参数可以指定数组的容量,即可以指定这个数组在内存中分配多大的空间。