这是我参与「第五届青训营 」伴学笔记创作活动的第1天,今天学习了Goland的基础语法。
Goland的语言特性
优势
1.1 可直接编译成机器码
1.2 不依赖其他库,使用标准库即可满足大部分开发需求
1.3 直接运行即可部署
1.4 在编译的时候就可以检测出隐藏的问题
语法
变量声明
var v_name int//声明整形变量v_name,默认为0 可以声明全局变量
var v_name = value //自行判断变量类型 可以声明全局变量
v_name := value//省略var,自动类型匹配,v_name变量不能先被声明,不然报错 不可以声明全局变量
:=自动类型匹配不能用于全局变量声明,会报错,另外, num := 1 这个num不能已经被声明,不然会报重复声明的错误
多变量声明
var x,y int
var (
a int
b int
)
常量
使用const关键字
显式声明
const num int = 10
隐式声明
const num = 1
多常量声明
const(
a=1
b=1
)
利用的隐式声明,可以不用一个一个去声明常量
iota 自增长 iota只能配合const()一起
const (
a, b = iota + 1, iota + 2 //逐行累加,也就是这一行iota=0
c, d //iota=1,保持上面的规则
e, f
g, k = iota + 2, iota + 3 //更改规则
i, l
)
iota可以省略赋值操作,按照每行递增的规则,第一行的iota为0 第二行为1,可以中途改变规则
循环
i := 1
for { //相当于while(true)
fmt.Println("loop")
break
}
for j := 7; j < 9; j++ {
fmt.Println(j)
}
for n := 0; n < 5; n++ {
if n%2 == 0 {
continue
}
fmt.Println(n)
}
for i <= 3 {
fmt.Println(i)
i = i + 1
}
使用for{}就相当于一个while循环,需要自己打断循环,
for n := 0; n < 5; n++普通的for循环,
i:=1 for i<3{i=i+1}结合了条件判断 ,当条件不满足时退出
条件判断
if 7%2 == 0{
fmt.Println(1)
}else {
fmt.Println(2)
}
当满足条件时会执行相应的语句,否则会向下判断寻找else if或者else 在判断
switch
a := 2
switch a {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
case 4, 5:
fmt.Println("four or five")
default:
fmt.Println("other")
}
和大多数语言的switch差不多,不过不需要在每种情况下有break,默认只执行当前case操作
数组
var a [5]int //默认为0
a[4] = 100 //赋值操作
有个需要注意的点,比如有 func f([4]int){}就代表只能传入长度为4的整形数组
slice
slice1 := []int//声明为切片
slice1 = make([]int 2,4)//长度,容量,容量可以省略
//容量省略 容量=长度
//
slice1.append(slice1,2)//追加内容,当长度小于容量时,正常添加,当长度大于容量时,容量翻倍
fmt.Printf(",slice=%v", slice1)//打印信息
fmt.Printf(",slice=%#v", slice1)//打印详细信息
//打印容量
fmt.Printf("cap=%d,slice=%v",cap(slice1) slice1)//打印信息
//
不一样的是,func f([]int){}可以传入任意长度的整形数组 cap([]int)可以测量出数组的容量,容量与长度不同,容量是一开始就分配好的空间,但是len只使用了其中的一部分,当长度不够时,append()会把len扩大,直到len等于cap,cap扩容为2*cap
map
开辟空间三种方式
//1
var mymap map[int]string
myMap=make(map[string]string,10)//分配数据空间
//2
myMap:=make(map[int]string)
//3
myMap:=make(map[int]string){
1:"1",//注意逗号
2:"2",
}
defer
作用:
释放占用的资源
捕捉异常
输出日志
如果一个函数有多个defer,安装 后进先出 顺序执行
defer 和 return 的执行顺序
用于返回后执行一系列操作
range
nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {//下标,值
sum += num
if num == 2 {
fmt.Println("index:", i, "num:", num) // index: 0 num: 2
}
}
//遍历map
m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
fmt.Println(k, v) // b 8; a A
}
//遍历key
for k := range m {
fmt.Println("key", k) // key a; key b
}
range能够依次取出容器里的元素,对于map不是按照存入顺序,而是map里的相对顺序
函数
func 函数名(参数列表) 返回值{}//可以返回多个返回值
func add(a int, b int) int {
return a + b
}
//传入map,根据key取出 返回value和状态码
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
go的函数语法和其他语言不同,返回值在后面,而且可以一次返回多个返回值,如果有多个返回值,第一个用于返回需要的返回值,第二个返回错误,不用像Java等抛出
point 指针
p := &num
只有在函数中传入变量的指针才能对其修改
如果将一个变量传入函数,只有传入变量的地址才能够修改,
struct
type user struct {
name string
password string
}
//无法修改user
func setPassword4(u user, password string) {
u.password = password
}
//可以修改user
func setPassword3(u *user, password string) {
u.password = password
}
//相当于user内置函数
func (u *user) resetPassword(password string) {
u.password = password
}
而且在struct里不能过声明结构函数,只能通过func (u *user) resetPassword(password string) 这种方式来为一个结构体编写一个方法
时间
now := time.Now()
匿名变量
var input string
//有两个返回参数,但是其中一个不使用,用_代替
_, err := fmt.Scanf("%s\n", &input)
当一个返回参数用不上,另一个参数要用上时,以为go不允许没被使用的元素存在,所以这个时候匿名变量的作用就体现出来了,可以通过语法要求