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()。