Go 语言基础语法| 青训营

102 阅读5分钟

Go语言也有与其它语言不同的地方,因此,在此专门写一篇笔记记录我总结的Go语言基础语法知识和特殊用法。

基础语法

在 Go 程序中,一行代表一个语句结束。每个语句不需要像 C 家族中的其它语言一样以分号 ;结尾,因为这项工作Go 编译器会自动完成。如果你就是想多个语句写一行,那就需要用;分隔了,如下图:

image.png

实际并不鼓励这么做,你在GoLand这么做它会自动纠正你
注释

这个就和C语言一样了
// 单行注释
/*
多行注释
*/

变量声明

Go语言是一个强类型语言,每个变量都有它自己的变量类型
你可以这样初始化
var a = "initial" 编译器会根据上下文自动判断变量类型
你也可以这样:
var b, c int = 1, 2 //这里显式声明变量b和c是int类型
var e float64 //不赋初值就得声明变量类型
f := float32(e) // := 是带变量类型声明的赋值

字符串操作

go中的字符串可直接通过 + 拼接
fmt.Println("Hello " + "World")
// 输出 Hello World
Go 语言中使用 fmt.Sprintf 或 fmt.Printf 格式化字符串并赋值给新串:

  • Sprintf 根据格式化参数生成格式化的字符串并返回该字符串。
  • Printf 根据格式化参数生成格式化的字符串并写入标准输出。
    // %d 表示整型数字,%s 表示字符串
    var stockcode=123
    var enddate="2020-12-31"
    var url="Code=%d&endDate=%s"
    var target_url=fmt.Sprintf(url,stockcode,enddate)
    fmt.Println(target_url)
    输出:
    Code=123&endDate=2020-12-31

条件判断语句

if-else

go里的if判断是没有()的,且必须跟 {}
关系运算符和逻辑运算符与C/C++一致
关系运算符:==, >, <, !=, >=, <=
逻辑运算符:&&(与), ||(或), !(非)

num := 9
if num < 0 {  
    fmt.Println(num, "is negative")  
} else if num < 10 {  
    fmt.Println(num, "has 1 digit")  
} else {  
    fmt.Println(num, "has multiple digits")  
}

输出:
9, has 1 digit

switch

与C/C++不同的是,go的switch是不需要break的,执行完这个case它就跳出,这样switch 就能很好地替代长else if语句了

t := time.Now()  
switch {  
    case t.Hour() < 12:  
        fmt.Println("It's before noon")  
    default:  
        fmt.Println("It's after noon")  
}

根据现在时间判断当前是上午还是下午

循环语句

go语言只有for循环

经典写法,和C/C++的区别就是没有条件()了吧

for j := 7; j < 9; j++ {  
    fmt.Println(j)  
}

输出:
7
8

无条件for就是死循环了,靠break跳出循环

for {  
    fmt.Println("loop")  
    break  
}

输出:
loop

还有就是替代while的for方式了

for i <= 3 {  
    fmt.Println(i)  
    i = i + 1  
}

输出:
1
2
3

数组

go语言数组的声明方式为: var arrayName [size]dataType 例:var a [5]int
数组的初始化方式:
var b = [5]int{1, 2, 3, 4, 5} 或 b := [5]int{1, 2, 3, 4, 5}
如果想自动分配大小,使用...替代数组长度:
balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

切片

切片是实际中更为常用的数组形式,它的长度是可变的通过append添加元素
你可以通过定义一个未指定大小的数组作为切片: var identifier []type
也可以通过make()函数定义切片: s := make([]string, 3)
s[0] = "a"
s[1] = "b" //s = ["a","b"]
s = append(s, "d") //s = ["a","b","d"]
s = append(s, "e", "f") //s = ["a","b","d","e","f"]
切片初始化:s :=[] int {1,2,3 }
切片的截取:和Python类似,就是不能用负数。
从1号下标截取到2下标:s[1:2]
从头截取到3下标:s[:3]
从1下标截取到尾:s[1:]

map字典

Map 是一种无序的键值对的集合。

Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。

Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,遍历 Map 时返回的键值对的顺序是不确定的。

在获取 Map 的值时,如果键不存在,返回该类型的零值,例如 int 类型的零值是 0,string 类型的零值是 ""。

Map 是引用类型,如果将一个 Map 传递给一个函数或赋值给另一个变量,它们都指向同一个底层数据结构,因此对 Map 的修改会影响到所有引用它的变量。

可以使用内建函数 make 或使用 map 关键字来定义 Map:

map_variable := make(map[KeyType]ValueType, initialCapacity)

例:m2 := map[string]int{"one": 1, "two": 2}
m := make(map[string]int)
m["one"] = 1
m["two"] = 2

r, ok := m["unknow"]查找字典m中是否存在key为"unknow"的,如果有r=对应值,ok=true,否则r=0,ok=false

range遍历

在go中可以使用range遍历切片、map
range 遍历切片返回: 索引,值,不需要索引可以使用下划线忽略
如果是rangemap返回到就是:key,value

nums := []int{2, 3, 4}
for i, num := range nums {  
    sum += num  
    if num == 2 {  
        fmt.Println("index:", i, "num:", num) // index: 0 num: 2  
    }  
}
m := map[string]string{"a": "A", "b": "B"}  
for k, v := range m {  
    fmt.Println(k, v) // b 8; a A  
}

函数

go中定义函数:
func 函数名(变量名 变量类型, ...) 函数返回类型{
函数体
}
当然go函数支持多返回值,在实际开发中也确实需要,一般我们会选择返回真实值与错误信息

// 变量类型后置 返回多个值 真正结果,错误信息  
func exists(m map[string]string, k string) (v string, ok bool) {  
    v, ok = m[k]  
    return v, ok  
}

指针

与C/C++类似,n *int 就定义了一个int类型的指针,&就是取地址符

结构体

结构体定义:

type 结构体名 struct {
属性名 属性类型
member definition
...
member definition
}

结构体声明:

变量名 := 结构体名 { key1: value1, key2: value2..., keyn: valuen}
或者按照属性定义顺序,按顺序初始化value

结构体访问属性: 变量名.属性名

在go里面可以为结构体定义一些方法。有一点类似于面向对象的类成员函数。
如下面的checkPassword的实现,从一个普通函数,改成类结构体方法。这样就可以通过u.checkPassword(xx)去调用。
具体的实现方式就是在函数名前加(变量名 结构体名).实现方式也有带指针与不带指针的,带指针的就是可以修改传入结构体变量的成员值

type user struct {  
    name string  
    password string  
}  
  
func (u user) checkPassword(password string) bool {  
    return u.password == password  
}  
  
func (u *user) resetPassword(password string) {  
    u.password = password  
}  
  
func main() {  
    a := user{name: "wang", password: "1024"}  
    a.resetPassword("2048")  
    fmt.Println(a.checkPassword("2048")) // true  
}