Go 语言入门指南:基础语法和常用特性解析(下) | 豆包MarsCode AI刷题

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

前两天刚学完了切片如何操作,今天继续学习GO语言的基础语法

映射

映射是Go语言中的一种内置的数据结构,类似于其他语言中的字典或哈希表 使用make来创建空map 第一个类型指定为string, 而第二个类型指定为int。可以通过方括号对键值对进行写入和读取。通过delete可以删除键值对。

go 复制代码
  m := make(map[string]int)
	m["one"] = 1
	m["two"] = 2
	fmt.Println(m)           // map[one:1 two:2]
	fmt.Println(len(m))      // 2
	fmt.Println(m["one"])    // 1
	fmt.Println(m["unknow"]) // 0

   //读取键值对的第二种方式, 通过ok来判断是否存在, 不存在的就是0 ok为false
	r, ok := m["unknow"]
	fmt.Println(r, ok) // 0 false

	delete(m, "one")

	m2 := map[string]int{"one": 1, "two": 2}
	var m3 = map[string]int{"one": 1, "two": 2}
	fmt.Println(m2, m3)

range

使用range可以快速遍历数组、切片和映射,

遍历数组或切片时,它会返回每个元素的索引和值。如果不需要索引,可以忽略它。而遍历映射时,则会返回键值对

go 复制代码
 nums := []int{2, 3, 4}
	sum := 0
	for i, num := range nums {
		sum += num
		if num == 2 {
			fmt.Println("index:", i, "num:", num) // index: 0 num: 2
		}
	}
	fmt.Println(sum) // 9

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

函数

在Go语言的业务中,函数通常会返回多个值,比如第一个值返回函数的结果,第二个值则返回错误信息, 并且函数对输入的参数都是后知的。

go 复制代码
func add(a int, b int) int {
	return a + b
}

func add2(a, b int) int {
	return a + b
}

func exists(m map[string]string, k string) (v string, ok bool) {
	v, ok = m[k]
	return v, ok
}

指针

相比C和C++, GO语言的指针操作空间比较有限,但也能正常使用

go 复制代码
func add2(n int) {
	n += 2
}

func add2ptr(n *int) {
        // 根据n的指针获取n的值 让它加2
	*n += 2
}

func main() {
	n := 5
	add2(n)
	fmt.Println(n) // 5
	add2ptr(&n) // 将n的指针传入函数
	fmt.Println(n) // 7
}

结构体

定义结构体, 可以通过以下方式对结构体进行赋值

go 复制代码
type user struct {
	name     string
	password string
}
a := user{name: "wang", password: "1024"}
	b := user{"wang", "1024"}
	c := user{name: "wang"}
	c.password = "1024"
	var d user
	d.name = "wang"
	d.password = "1024"

结构体方法

顾名思义, 专属于结构体的方法,就不需要每次调用的时候都把结构体传进去了。 在函数名称前面加一个括号() 在里面定义结构体,就能使得一个函数变成类成员函数。

go 复制代码
func (u user) checkPassword(password string) bool {
	return u.password == password
}

func (u *user) resetPassword(password string) {
	u.password = password
}
a := user{name: "wang", password: "1024"}
a.resetPassword("2048")

错误处理

在Go语言中,错误是通过在函数里面的err来显示的 当需要把错误结结果显示时,可以采用erros.New方法

go 复制代码
// 在函数里面加一个err返回值
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")
}
// 当err存在时, 进行处理
u, err := findUser([]user{{"wang", "1024"}}, "wang")
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(u.name) // wa

字符串操作

在GO语言的标准库strings包里,有非常多的字符串操作函数,可以通过以下方法对字符串进行操作:

go 复制代码
import (
	"fmt"
	"strings"
)

func main() {
	a := "hello"
	fmt.Println(strings.Contains(a, "ll"))                // true
	fmt.Println(strings.Count(a, "l"))                    // 2
	fmt.Println(strings.HasPrefix(a, "he"))               // true
	fmt.Println(strings.HasSuffix(a, "llo"))              // true
	fmt.Println(strings.Index(a, "ll"))                   // 2
	fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // he-llo 创建一
	fmt.Println(strings.Repeat(a, 2))                     // hellohello
	fmt.Println(strings.Replace(a, "e", "E", -1))         // hEllo
	fmt.Println(strings.Split("a-b-c", "-"))              // [a b c]
	fmt.Println(strings.ToLower(a))                       // hello
	fmt.Println(strings.ToUpper(a))                       // HELLO
	fmt.Println(len(a))                                   // 5
	b := "你好"
	fmt.Println(len(b)) // 6 为什么这里有6个字节 因为utf-8 一个汉字3个字节 所以在这里的长度就是6了。
}

字符串格式化

字符串的格式化是这样的,println函数打印了会自动换行 而print函数则不会自动换行

scss 复制代码
	fmt.Println(p)    // {1 2}
	fmt.Printf("s=%v\n", s)  // s=hello

与C语言类似,但在这里%V是值的默认格式,会打印出后面用于替换的变量。

拓展:

%+v:这是值的扩展格式,它不仅会打印变量的值,还会打印出字段的名称。

%#v:这是值的Go语法格式,它会打印出变量的值,并且包括类型信息。对于结构体,它会显示完整的类型名称和字段名称。

JSON处理

在GO语言中,对于一个结构体而言,只要保证每个字段的首字母为大写,那么结构体就能用json.Marshal函数进行序列化

go 复制代码
buf, err := json.Marshal(a) //在这里, a是一个自定义的结构体, 并且每个字段首字母都是大写。

序列化以后会变成一个JSON字符串,不能直接打印看到它的值,需要进行反序列化才能看到。当然也可以通过在结构体中定义json的tag来对序列化后的字符串字段进行自定义:

go 复制代码
type userInfo struct {
	Name  string
	Age   int `json:"age"` //加了json的tag 序列化以后不是Age 
        //而是age 也可以用`-`标签来忽略这个字段
}

时间处理

在GO语言中,标准库time包中,定义了time.now方法可以快速获取当前时间。

css 复制代码
now := time.Now()

同时,与其他语言的time不一样的是,它的Format用的是一个确定的时间 同时可以用parse来反解析成time类型

css 复制代码
t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
fmt.Println(t.Format("2006-01-02 15:04:05"))
t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
fmt.Println(now.Unix()) //这是获得时间戳的函数

数字解析

在GO语言中,字符串和数字的转换大多方法集中在标准库的strconv包中,常用的有parsefloat, parseint, atoi, itoa四种方法

parsefloat :针对的是float类型的字符串

parseint :可以按照指定的进制进行转换

atoi :则是快速将字符串转换为数字

itoa :则是快速将数字转换为字符串

进程信息

使用OS包中,有几个方法很方便查看进程信息

less 复制代码
fmt.Println(os.Args) // 获得命令参数
fmt.Println(os.Getenv("PATH")) 
fmt.Println(os.Setenv("AA", "BB"))
buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()

通过Getenv和Setenv管理和查看进程变量

使用exec.command 执行了外部命令, 在/etc/host下搜索包含字符串"127.0.0.1"的行, 之后通过CombinedOutput()方法来捕获命令的输出

学习总结:

从入门学到现在,发现GO和市面上大部分语言差不多,不过也有自己的特性,感觉比python和java要难一点。但总体来说还是能够学会的,

Go语言的语法简洁,没有过多的复杂性,代码清晰和易于维护。它的表达力强,能够在少量的代码中实现复杂的逻辑,这对于大型项目的开发来说是一个巨大的优势。加油,我会继续学习

相关推荐
FOFO4 小时前
青训营笔记 | HTML语义化的案例分析: 粗略地手绘分析juejin.cn首页 | 豆包MarsCode AI 刷题
青训营笔记
滑滑滑2 天前
后端实践-优化一个已有的 Go 程序提高其性能 | 豆包MarsCode AI刷题
青训营笔记
柠檬柠檬2 天前
Go 语言入门指南:基础语法和常用特性解析 | 豆包MarsCode AI刷题
青训营笔记
用户967136399652 天前
计算最小步长丨豆包MarsCodeAI刷题
青训营笔记
用户52975799354723 天前
字节跳动青训营刷题笔记2| 豆包MarsCode AI刷题
青训营笔记
clearcold3 天前
浅谈对LangChain中Model I/O的见解 | 豆包MarsCode AI刷题
青训营笔记
夭要7夜宵4 天前
【字节青训营】 Go 进阶语言:并发概述、Goroutine、Channel、协程池 | 豆包MarsCode AI刷题
青训营笔记
用户336901104444 天前
数字分组求和题解 | 豆包MarsCode AI刷题
青训营笔记
dnxb1234 天前
GO语言工程实践课后作业:实现思路、代码以及路径记录 | 豆包MarsCode AI刷题
青训营笔记