Go 语言入门指南 | 青训营

147 阅读6分钟

go语言基础语法

  1. 高性能、高并发
  2. 语法简单、学习曲线平缓
  3. 丰富的标准库
  4. 完善的工具链
  5. 静态链接
  6. 快速编译
  7. 跨平台
  8. 垃圾回收

开发环境

1. 安装go语言

go.dev/ 自行选择对应OS的版本

2. 安装开发环境

① VScode(注意需要安装插件)
② Goland(用的人多,功能也多,建议使用)

基础语法

1. HelloWorld

学一门语言必备的开局代码:

package main  

import "fmt"  
func main() {  
fmt.Println("hello world")  
}

2. 变量

常用数据类型

常用数据类型就是基本类型,常用的字符串、数字类型(整型、浮点型)、布尔类型。

var a = "yzs"  // 字符串
var b int = 2  // 整型
var c = false  // bool类型
var d = 3.14  // 浮点型
e := a + "lq"
fmt.Println(a, b, c, d)
fmt.Println(e)

其他类型

  • 聚合类型:数组和结构体
  • 引用类型:指针、切片、映射、函数和通道
  • 接口类型: 接口interface
  • 复数、字符、nil(未初始化引用)
  • 后面大都有介绍

常量 const

3. if else

关键字 if 是用于测试某个条件(布尔型或逻辑型)的语句

if num := 1; num > 0 {  
fmt.Println("yo!正数")  
} else if num == 0 {  
fmt.Println("yo!0")  
} else {  
fmt.Println("yo!负数")  
}

4. for

  • 左花括号{必须与 for 处于同一行。

  • Go语言中的 for 循环与C语言一样,都允许在循环条件中定义和初始化变量,唯一的区别是,Go语言不支持以逗号为间隔的多个赋值语句,必须使用平行赋值的方式来初始化多个变量。

  • Go语言的 for 循环同样支持 continue 和 break 来控制循环,但是它提供了一个更高级的 break,可以选择中断哪一个循环,比如break 外层循环

    for {
    fmt.Println("我是死循环(啥条件也不写)")
    break
    }
    for num := 1; num <= 10; num++ {
    fmt.Println("最熟悉的循环来咯")
    fmt.Println("这三部分哪块都可以不写")
    }

5. switch

不需要通过 break 语句跳出当前 case 代码块以避免执行到下一行

t := time.Now()  
switch {  
case t.Hour() <= 12:  
fmt.Println("上午好")  
default:  
fmt.Println("下午好")  
}

6. 数组

与java.c++声明变量类似,不过go语言将变量类型放在后面

var a [5]int  
a[0] = 3  
b := [5]int{1, 2, 3, 4, 5}  
fmt.Println(b)  
var twoD [2][3]int  
for i := 0; i < 2; i++ {  
for j := 0; j < 3; j++ {  
twoD[i][j] = 100 + i + j  
}  
}  
fmt.Println(twoD) 

打印结果
[1 2 3 4 5]
[[100 101 102] [101 102 103]]

7. 切片

我觉得切片可以理解为一种动态数组,并且切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大

s := make([]string, 3)  
s = append(s, "a")  
fmt.Println(s[1:4])  
good := []string{"g", "o", "o", "d"}  
fmt.Println(good)

打印结果
[ a]
[g o o d]

8. 映射map

map与java中的map类似,即map 是无序的,遍历 map 时返回的键值对的顺序是不确定的

s := make(map[int]string)  
s[0] = "ck"  
s[1] = "cs"  
s[2] = "yzs"  
fmt.Println(s)  
r, ok := s[3]  
fmt.Println(r, ok)  
delete(s, 0)

打印结果
map[0:ck 1:cs 2:yzs]
 false

9. range

range 关键字用于 for 循环中迭代数组、切片或集合的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对。

m := map[string]string{"a": "A", "b": "B"}  
for k, v := range m {  
fmt.Println(k, v)  
}  
for k := range m {  
fmt.Println("key ", k)  
}

打印结果
a A
b B
key a
key b

10. 函数func

函数声明返回类型也在参数列表后面,并且Go 函数可以返回多个值。

func main() {  
v, ok := exists(map[string]string{"a": "A"}, "a")  
fmt.Println(v, ok)  
}  
func exists(m map[string]string, k string) (v string, ok bool) {  
v, ok = m[k]  
return v, ok  
}

打印结果:
A true

11. 指针

指针这块与c++语言的指针有点类似,并且Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址,这点与c++也一样。

func add(n ***int**) {  
*n += 2  
}  
func main() {  
n := 5  
add(**&n**)  
fmt.Println(n)  
}

12. 结构体

结构体是由一系列具有相同类型或不同类型的数据构成的数据集合,具体使用与c++类似,不同的是go的变量类型在后。

type user struct {  
name string  
address string  
}  

func main() {  
a := user{name: "ck", address: "山东省"}  
b := user{name: "cs", address: "辽宁省"}  
fmt.Println(a)  
fmt.Println(b)  
}

打印结果:
{ck 山东省}
{cs 辽宁省}

13. 结构体方法

接上一个结构体

func (u user) checkAddress(add string) bool {  
return add == u.address  
}

14. 错误处理

Go 语言通过内置的错误接口提供了非常简单的错误处理机制。

func findDig(a []int, key int) (b int, err error) {  
for i := range a {  
if i == key {  
return i, nil  
}  
}  
return -1, errors.New("查询失败,未找到该元素")  
}  
func main() {  
a := []int{1, 2, 3, 4, 5}  
b, err := findDig(a, 6)  
fmt.Println(b, err)  
}<br>

打印结果
-1 查询失败,未找到该元素

15. 字符串操作

strings有很多方法提供,java也是提供一些方法判断。

a := " hello"  
fmt.Println(strings.Contains(a, "ll"))  
fmt.Println(strings.Count(a, "l"))  
fmt.Println(strings.HasPrefix(a, "he"))  
fmt.Println(strings.HasSuffix(a, "llo"))  
fmt.Println(strings.Index(a, "ll"))  
fmt.Println(strings.Join([]string{"he", "llo"}, "-"))  
fmt.Println(strings.Repeat(a, 2))  
fmt.Println(strings.Replace(a, "l", "L", 1))  
fmt.Println(strings.Split("a-b-c", "-"))  
fmt.Println(strings.ToLower(a))  
fmt.Println(strings.ToUpper(a))  
fmt.Println(len(a))  
b := "你好"  
fmt.Println(len(b))

*打印结果*:
true
2
false
true
3
he-llo
hello hello
heLlo
[a b c]
hello
HELLO
6
6

16. 字符串格式化

%v按值的本来值输出
%+v在 %v 基础上,对结构体字段名和值进行展开
%#v输出 Go 语言语法格式的值

17. JSON

可以使用Marshal 函数来将 Go 对象转换为 JSON, 可以使用Unmarshal 函数来将JSON转换为Go对象。

type Book struct {  
Title string  
Author string  
Year int  
}  

func main() {  
book := Book{Title: "西游记", Author: "吴承恩", Year: 1560}  
b, err := json.Marshal(book)  
fmt.Println(string(b), err)  
var journey Book  
err = json.Unmarshal(b, &journey)  
fmt.Println(journey)  
fmt.Printf("%#v\n", journey)  
}<br>
*打印结果*:<br>
{"Title":"西游记","Author":"吴承恩","Year":1560} <'nil> <br>
{西游记 吴承恩 1560}<br>
main.Book{Title:"西游记", Author:"吴承恩", Year:1560}

JSON-to-Go: Convert JSON to Go instantly (mholt.github.io)

18. 时间处理

主要需要注意的就是标准时间,go语言的诞生时间,2006-01-02 15:04:05,简称612345;

now := time.Now()  
fmt.Println(now) //2023-07-25 14:39:35.5371747 +0800 CST m=+0.011981601  
t := time.Date(2022, 7, 25, 10, 25, 36, 0, time.UTC)  
t2 := time.Date(2022, 7, 27, 11, 30, 36, 0, time.UTC)  
fmt.Println(t) // 2022-07-25 10:25:36 +0000 UTC  
fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) // 2022 July 25 10 25  
fmt.Println(t.Format("2006-01-02 15:04:05")) // 2022 July 25 10 25  
diff := t2.Sub(t)  
fmt.Println(diff) // 49h5m0s  
fmt.Println(diff.Minutes(), diff.Seconds()) // 2945 176700  
fmt.Println(time.Parse("2006-01-02 15:04:05", "2023-07-25 14:40:25")) //2023-07-25 14:40:25 +0000 UTC <nil>

"2006-01-02 15:04:05" 标准Format时间

19. 数字解析

使用strconv提供字符串和数值类型的相互转换,其实是stringcovert的缩写,常用的函数包括下面实例中的,还有一些append、Format系列函数等。

a, _ := strconv.ParseInt("123", 10, 64)  
b, _ := strconv.ParseFloat("1.234", 64)  
c, _ := strconv.ParseInt("0x1000", 0, 64)  
d, _ := strconv.Atoi("145")  
fmt.Println(a, b, c, d)

20.进程信息

使用os的函数查看一些系统级别的信息,比如查看系统环境变量。

fmt.Println(os.Args)  
// F:\go\go1.20.6\bin\go.exe build -o C:\Users\User\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_helloworld_go.exe F:\go\Project\HelloWorldProject\helloworld.go #gosetup  
fmt.Println(os.Getenv("PATH"))  
// 系统环境变量