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

73 阅读5分钟

Go语言入门指南|后端青训营

1 Go语言特性

Go语言(Golang)是一种开发高效、性能优越的编程语言,由Google开发。其在系统编程、网络编程。并发编程等方面具有许多特性。

1.简洁易读

Go语言拥有简洁而清晰的语法,减少了冗余的符号和复杂的结构,使代码更易于阅读和维护。

2.静态类型和类型推导

Go是静态类型语言,但它也支持类型推导,这意味着在大多数情况下,你不需要显式指定变量的类型,编译器会根据赋值的值来推导出合适的类型。

3.垃圾回收

Go具有自动内存管理,内置垃圾回收机制,可以自动识别和回收不再使用的内存,降低了内存管理的负担。

4.内置并发支持

Go在语言级别提供了并发支持,使并发编程变得更加容易。标准库中的并发原语和工具可以帮助开发者处理并发任务。

5.接口

Go中的接口是一种描述类型行为的方式,而不需要指定类型是如何实现这些行为的。这种特性促进了代码的解耦和灵活性。

2 Go语言基础语法

1.变量定义

	var b, c int = 1, 2
	var d = true
	var e float64
	f := float32(e)
	g := a + "night"

习惯了C/C++开发的程序员第一次编写Go语言的程序多半会不太适应。正如上文所说,Go语言会自动推导变量类型,多数情况下不需要指定变量类型。

比如第二行定义了一个bool类型的变量d,我们就可以直接将d的值写在等于号后而没有加上bool的关键字,以至于看起来像是对d赋值而不是在定义变量。 定义变量有两种常见形式:

  1. var name string = " "
  2. 变量 := 值

使用第二种方式时一定要加上“:”,这非常重要。

2.输出“fmt”

Go语言使用Print函数必须要提前导入“fmt”的包

import "fmt"

Go语言的输出函数有多种形式,区别是打印结果的详细程度不同。

  fmt.Printf("p=%v\n", p)  // p={1 2}
	fmt.Printf("p=%+v\n", p) // p={x:1 y:2}
	fmt.Printf("p=%#v\n", p) // p=main.point{x:1, y:2}

3.循环

Go语言中只有一种循环类型,就是for循环。

package main

import "fmt"

func main() {

	i := 1
	for {
		fmt.Println("loop")
		break
	}
	for j := 7; j < 9; j++ {
		fmt.Println(j)
	}

	for n := 0; n < 5; n++ {
		if n%2 == 0 {
			continue
		}
		fmt.Println(n)
	}
	for i <= 3 {
		fmt.Println(i)
		i = i + 1
	}
}

循环条件中的三个部分都可以省略,在没有任何条件的情况下就是死循环。

4.数组与切片

s := make([]string, 3)
	s[0] = "a"
	s[1] = "b"
	s[2] = "c"
	fmt.Println("get:", s[2])
	fmt.Println("len:", len(s))

	s = append(s, "d")
	s = append(s, "e", "f")
	fmt.Println(s)

	c := make([]string, len(s))
	copy(c, s)
	fmt.Println(c)

	fmt.Println(s[2:5])
	fmt.Println(s[:5])
	fmt.Println(s[2:])

代码的运行结果如下

get: c
len: 3
[a b c d e f]
[a b c d e f]
[c d e]
[a b c d e]
[c d e f]

5.map

在其他编程语言中被称为哈希或者字典,map是实际使用过程中最频繁用到的数据结果。

m := make(map[string]int)
	m["one"] = 1
	m["two"] = 2

6.错误抛出

在Go语言里符合习惯的做法就是使用一个单独的返回值来传递错误信息。

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")
}

在这个函数中指定了返回值中有一个错误参数,当结果为真时,error返回值为nil。如果函数结果为假时,error的返回值就不是nil,此时就会打印“not found”。

7.时间

now := time.Now()
	fmt.Println(now) // 2022-03-27 18:04:59.433297 +0800 CST m=+0.000087933
	t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
	t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
	fmt.Println(t)                                                  // 2022-03-27 01:25:36 +0000 UTC
	fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) // 2022 March 27 1 25
	fmt.Println(t.Format("2006-01-02 15:04:05"))                    // 2022-03-27 01:25:36
	diff := t2.Sub(t)
	fmt.Println(diff)                           // 1h5m0s
	fmt.Println(diff.Minutes(), diff.Seconds()) // 65 3900
	t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
	if err != nil {
		panic(err)
	}
	fmt.Println(t3 == t)    // true
	fmt.Println(now.Unix()) // 1648738080

这段代码演示了如何使用 Go 语言的时间包 time 来解析时间字符串并进行比较。下面我会逐步解释代码的不同部分。

  1. time.Parse 函数用于解析一个时间字符串,它接受两个参数:时间格式和要解析的时间字符串。在这里,时间格式是 "2006-01-02 15:04:05",这是一个特殊的日期和时间格式,用于 Go 语言的时间解析。然后,函数尝试将提供的时间字符串 "2022-03-27 01:25:36" 解析为时间对象。

  2. 如果解析过程中没有发生错误,那么解析后的时间对象会被存储在变量 t3 中。如果解析出错,err 不为空,panic 函数将会抛出一个运行时异常。

  3. fmt.Println(t3 == t) 用于比较解析后的时间对象 t3 是否等于之前的时间对象 t。在这里,如果 t3t 的值相等,则打印结果为 true,否则为 false

  4. fmt.Println(now.Unix()) 打印当前时间(now)的 Unix 时间戳。Unix 时间戳是从 1970 年 1 月 1 日开始计算的秒数。