Go 语言入门指南:基础语法和常用特性解析 | 青训营

110 阅读4分钟

Go 语言入门指南:基础语法和常用特性解析

1 基础语法

1.1 变量

变量的使用方式:

1)指定变量类型,并且赋值

var num int = 18

2)指定变量类型,但是不赋值,使用默认值

var num2 int

3)没有写变量类型,根据=后面的值判断变量类型(自动类型推断)

var num3="Tom"

4)省略var,使用:=

sex:="male"

可以声明多个变量

var n1,n2,n3 int

也可以同时赋值

var a,b,c=1,"Jerry",3.5

全局变量可以写一次性声明

var{
    m=20
    n="Davi"
}

1.2 数据类型

go是强类型语言

基本数据类型:数值型(整数、浮点数)、字符型(byte)、布尔型、字符串

派生数据类型:指针、数组、结构体、管道、函数、切片、接口、map

1)指针

  • 号用于指定变量是作为一个指针
var ip *int        /* 指向整型的指针*/

2)数组

声明语法:var arrayName [size]dataType

var numbers [5]int

使用初始化列表初始化数组:

var numbers = [5]int{1, 2, 3, 4, 5}

使用:=来声明并初始化数组

numbers := [5]int{1, 2, 3, 4, 5}

3)结构体

定义语法如下:

type struct_variable_type struct {
   member definition
   member definition
   ...
   member definition
}

定义了结构体以后,相应的变量声明语法:

variable_name := structure_variable_type {value1, value2...valuen}
或
variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}
​

4)管道

5)函数

定义语法如下:

func function_name( [parameter list] ) [return_types] {
   函数体
}

例:

func getNum(number int) int{
    return number
}

6)切片

切片是对数组的抽象,与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

使用make创建切片,这里 len 是数组的长度并且也是切片的初始长度。

slice1 := make([]type, len)

切片初始化:

①直接赋值

s :=[] int {1,2,3 } 

②引用数组arr

s := arr[startIndex:endIndex] 
s := arr[startIndex:] 
s := arr[:endIndex] 

③也可以通过一个切片初始化另一个切片

s1 := s[startIndex:endIndex] 

7)接口

定义接口:

type interface_name interface {
   method_name1 [return_type]
   ...
   method_namen [return_type]
}

例:

type act interface{
    say()
    listen()
}
​
type Person struct{
​
}
type Dog struct{
​
}
​
func (p Person) say(){
    fmt.Println("A person says something.")
}
func(d Dog) listen(){
    fmt.Println("A dog listens.")
}
​
func main(){
    var p act
    var d act
    p=new(Person)
    d=new(Dog)
    p.say()
    d.listen()
}

8)map

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

使用make来声明map

map_variable := make(map[KeyType]ValueType, initialCapacity)
// 使用字面量创建 Map
m := map[string]int{
    "apple": 1,
    "banana": 2,
    "orange": 3,
}
// 获取键值对
v1 := m["apple"]
v2, ok := m["pear"]  // 如果键不存在,ok 的值为 false,v2 的值为该类型的零值
// 修改键值对
m["apple"] = 5
// 获取 Map 的长度
len := len(m)
// 遍历 Map
for k, v := range m {
    fmt.Printf("key=%s, value=%d\n", k, v)
}
// 删除键值对
delete(m, "banana")

可以使用字面量创建map;获取可直接使用name[key];获取长度可用len()函数;删除可用delete(map_name,key)函数。

1.3 流程控制

条件语句

①if

②if-else

③switch

Switch后没有小括号,默认不写break,常用来替代多个if else。

④select

select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。

注意:go没有三目运算符

循环

只有for循环

2 常用特性解析

2.1 错误处理

go利用defer+recover来捕获error

func get_err{
   defer func(){
        err:=recover()
        if err!=nil{
        fmt.Println("error:",err)
        }
    }() 
    ……//可能有error的代码
}
func main(){
    get_err()
}

在最后添加括号,表示匿名函数的调用

自定义错误可以调用errors包下的New函数,返回error类型

import{
    "fmt"
    "errors"
}
func get_err()(err error){
    xxx//可能存在error的代码
    if 存在error{
        return errors.New("xxx")
    }else{
        return nil
    }
}

2.2 高级特性

go还有一些高级特性:

探究 Go 的高级特性之 【处理1分钟百万请求】 - 掘金 (juejin.cn)

探究 Go 的高级特性之【Go中的信号处理】 - 掘金 (juejin.cn)

本文介绍了信号处理的两种方法,一种是注册信号处理函数,另一种是使用Shutdown()方法。

探究 Go 的高级特性之【对象比较】 - 掘金 (juejin.cn)

本文介绍了在go中如何比较两个对象是否相同。

reflect.DeepEqual可以递归比较任意类型的值。

可以使用json.Marshal将两个对象序列化成JSON字符串,然后比较两个字符串是否相等。(但此方法比较效率低)

可以编写递归函数比较,但本文中递归函数也调用了DeepEqual()。

探究 Go 的高级特性之 【捕获panic:Gin框架中的recover中间件】 - 掘金 (juejin.cn)

探究 Go 的高级特性之 【Go项目中HTTP Error处理方法和实践】 - 掘金 (juejin.cn)