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

95 阅读6分钟

本篇笔记主题来自青训营笔记创作的后端实践选题:

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

主要记录了在学习Golang时遇到的相关基础语法,为个人学习记录所用

如有错误,欢迎指正

变量

  • Go语言是一门强类型语言,每一个变量都有它自己的变量类型
  • 常见的变最类型包括 字符串、整型、浮点型、布尔型等
  • go 语言的字符串是内置类型,可以直接通过加号拼接,也能够直接用等于号去比较两个字符串。
  • 在Go语言里面,大部分运算符的使用和优先级都和 C 或者 C++ 类似,这里就不再概述。
  • 下面讲述Go语言里面的变量的声明,在Go语言里面变量的声明有两种方式,一种是var name string = 这种方式来声明变量(声明变量的时候,会自动推导变量的类型),如果有需要,你也可以显式写出变量类型,另一种变量声明形式是a := 1

声明变量:

var a = "test"
var b int = 1
var c string
d := true

常量

  • var 改为const,即为Go语言常量的声明
const e = "test2"
const f int = 2

判断语句

Go语言的if-else与c或者c++类似,不同点是if后面的判断条件不需要括号

if num > 0 {
    return 1
}else if num < 0{
    return -1
}else if num == 0{
    return 0
}

需要注意的是Go语言中的大括号是不换行的,紧跟在条件后面,否则会编译错误

循环语句

  • Go语言中只有for循环,下面为示例:
for{
    fmt.Println("loop")
    break
}
for i:=1; i<3 ;i++{
    fmt.Println(i)
}

switch语句

  • 与c语言的switch不同的是: Go语言的switch语句的判断类型可以为任何类型,判断语句不需要加括号,且每个case间不需要加break
a := 2
switch a{
case 1:
    fmt.Println("one")
case 2:
    fmt.Println("two")
case 3:
    fmt.Println("three")
default:
    fmt.Println("other")
}
t := time.Now()
switch{
case t.Hour()<12:
    fmt.Println("morning")
default:
    fmt.Println("afternoon")
}

数组

  • 数组为一个具有编号且长度固定的元素序列
  • 对于数组可以很方便地通过索引来获得存储的值
var a [5]int
b := [5]int={1,2,3,4,5}
var c [2][3]int

切片(slice)

  • 切片不同于数组,可以任意更改长度,也有更多丰富的操作
  • 如可以用make来创建一个切片,可以像数组一样去取值,使用append来追加元素

注意:使用append时,需要把结果赋值为原数组

(因为slice的原理实际上是有一个指向一个数组的指针,并存储了他的长度和容量,而在进行append操作时,若容量不够,会扩容并返回新的slice)

s := make([]string,3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
s=append(s,"d")

map

  • 类似于其他语言中的哈希或字典,为Go语言内置的一个常用的数据结构
  • map的键值对(key-value)需要两个类型,一个为key的类型,一个为value的类型
  • 可以使用delete删除键值对
m := make(map[string]int)
m["one"]=1
m["two"]=2
delete(m,"one")

range

  • 用于快速遍历某一个容器(如slice或map)
  • range遍历时,会返回两个值,第一个为索引,第二个为对应位置的值,可以用下划线来代替索引的返回值
nums := []int ={1,2,3,4}
sum := 0
for _,num := range nums{
    sum += num
}

函数

  • Golang的函数支持返回多个值。
  • 在实际业务代码中,几乎所有的函数都返回两个值,一个是真正的返回结果,第二值为一个错误信息
func add (a int ,b int) int {
    return a + b
}

在Golang的约定中,需要跨文件调用的函数,函数名需要首字母大写

指针

  • Golang也支持指针,但相比c和c++的指针,支持的操作有限
  • 主要用途为对传入参数进行修改
func addprt(n *int){
    *n += 2
}
​
func main(){
    n:=5
    addptr(&n)
    fmt.Println(n)
}

这里的输出应该为7

结构体

  • 结构体可以理解为带类型的字段的集合

声明形式示例如下:

type user struct{
    name      string
    password  string
}
​
func main(){
    a := user(name:"yutou",password:"123")
    b := user{"yutou","123"}
    c := user{name:"yutou"}
    c.password = "123"
}
  • Golang可以为结构体定义方法,类似于其他语言的类成员函数
func (u user) checkPassword(password string) bool{
    return u.password == password
}

错误处理

  • 在Golang里面符合语言习惯的做法就是使用一个单独的返回值来传递错误信息
  • 不同于Java使用的异常,Golang的处理方式能够很清楚地知道哪个函数返回了错误了,并且能用简单的if else 来处理错误
  • 那么,在函数实现时,通常需要return两个值。如果出错的话,便可以return nil 和一个error ,如果没有的话,就返回原本的结果和nil
func findUser(users []user,name string)(v *user,err error){
    for _,u := range users {
        if u.name == name {
            return &u,nil
        }
    }  
    return nil,errors.New("not found")
}

字符串

  • Golang的标准库strings包中有很多常用的字符串处理工具函数,
  • 如:contains判断一个字符串中是否包含有另一个字符串,count字符串计数,index查找某个字符串的位置,join连接多个字符串,repeat重复多个字符串 ,replace替换字符串
package main
​
import (
    "fmt"
    "strings"
)
​
func main(){
    a:="hello"
    fmt.Println(strings.Contains(a,"ll"))   //true
    fmt.Printf("a = %v\n",a)    //a = hello
}

字符串格式化

  • 在标准库fmt包中有很多字符串格式相关的方法
  • 如,printf类似于c语言中的printf函数,不同的是,在Golang中,你可以很轻松地用%v来打印任意类型的变量,而不需要区分数字字符串。你也可以使用%+v打印详细结果,%#v更详细。

JSON处理

  • Golang中的 JSON操作:对于一个已有的结构体,只要保证每一个字段的第一个字母是大写,也就是公开字段。那么这个结构体就能用JSON.marshaler去序列化,变成一个JSON的字符串。
  • 序列化后的字符串也可以用JSON.unmarshaler 去反序列化到一个空的变量中
  • 默认序列化出来的字符串,他的风格是大写字母开头,而不是下划线。可以使用json tag 的语法去修改输出的 JSON结果里面的字段名。

时间处理

  • 在Golang中,最常用的是用time.now()来获取当前时间,也可以用time.date去构造一个带时区的时间
  • 构造完时间,有多种方法来获取这个时间点的年月日时分秒:如.Year().Month()
  • 也可以用.Sub方法来对两个时间点进行减法,得到一个时间段
  • 在与某些系统交互的时候,常会用到时间戳,可以用.UNIX来获取时间戳

数字解析

  • Golang中,关于字符串和数字类型之间的转换都在strconv这个包下,这个包是 string 和 convert 这两个单词的缩写
  • 我们可以使用ParseFloat或者ParseInt来解析一个字符串
  • 也可以使用Atoi来把一个十进制字符串转成数字,用itoA来把数字转换成字符串
  • 如果输入不合法,那么这些函数会返回error

进程信息

  • 在Golang中,可以使用os.argv来得到程序执行时指定的命令行参数
  • 如:在编译一个二进制文件时,后面接abcd来启动,这样输出的os.argv为一个长度为 5 的 slice,第一个成员为该二进制文件本身的名字。
  • 也可以用so.getenv来读取环境变量