Day1 go语言基础 | 青训营笔记

65 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

一 go语言语法基础

1.1 声明

  • go的变量声明用var,常量用const。
  • go可以一次性声明多个变量
  • go声明的变量,如果没有赋值,则都是默认初始值
  • 变量有string,byte,int,float32/64,bool等类型
  • 在用var声明变量时,编译器会根据值自动推导,也可以指定类型。
// 定义
var a = 1	// 单个变量定义
var b, c	// 多个变量定义
var d int = 10 // 定义时声明类型
var e string // 只声明不赋值,必须指定类型

const a = 10
const a int = 10

1.2 循环

go语言中只有一种循环——for循环。for循环一共有3种使用方法:

  1. 当while使用;
  2. 标准的c/c++/java模式;
  3. 死循环
func main() {
	i := 1
	// while循环
	for i <= 3 {
		fmt.Println(i)
		i = i + 1
	}
	// 经典循环
	for j := 7; j <= 8; j++ {
		fmt.Println(j)
	}
	// 死循环
	for {
		fmt.Println("loop")
		break
	}
}

1.3 if-else

go的if-else与c/c++/java基本一样,就是条件不需要小括号括起来,而且条件后面的内容必须用大括号括起来。

除此以外,go的if还能像for一样初始化变量。这个变量的生命周期在if - else的块周期一样

func main() {
	// 只有if
	if 7%2 == 0 {
		fmt.Println("7 is even")
	}
	// 初始化
	if num := 19; num < 0 {
		fmt.Println(num, "is negative")
	} else if num < 10 {
		fmt.Println(num, "is less than 10")
	} else {
		fmt.Println(num, "has multiple digits")
	}
}

1.4 switch

go的switch相较于c++的会丰富很多。首先,它只会执行case里面的代码,不需要每个case结束后就break。

其次switch后面跟的可以是任意值,只要满足case的条件就行。

然后case还可以当作if一样,在前面添加条件

func main() {
	i := 2
	switch i {
	case 1:
		fmt.Println("one")
	case 2:
		fmt.Println("two")
	case 3:
		fmt.Println("three")
	}
	// 选择多个
	switch time.Now().Weekday() {
	case time.Saturday, time.Sunday:
		fmt.Println("it is the weekend")
	default:
		fmt.Println("it is a weekday")
	}

	// 非==判断
	t := time.Now()
	switch {
	case t.Hour() < 12:
		fmt.Println("it is before noon")
	default:
		fmt.Println("it is after noon")
	}
}

1.5 数据结构

go常用的数据结构有:数组,切片,字典

数组很简单,定义如下,用法跟c++一样的。

var a [4]int
var b [4]int{1, 2, 3, 4}

切片可以看作是变长数组

用make函数定义切片,用append给切片添加元素

slice的切片操作:左闭右开

func main() {
    s := make([]string, 3)
    s[0] = "a"
	s[1] = "b"
	s[2] = "c"
	fmt.Println("get:", s[2])   // c
	fmt.Println("len:", len(s)) // 3
	s = append(s, "d")
	s = append(s, "e", "f")
    fmt.Println(s[2:5]) // [c d e]
	fmt.Println(s[:5])  // [a b c d e]
	fmt.Println(s[2:])  // [c d e f]
}

字典,就是c++中的map和Java中的HashMap,同样用make创建,也可以像切片那样用{key: value}的形式创建。

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

在利用key获取value的时候,map返回两个值,第一个是实际的值,第二个是一个bool类型的量,表示是否存在该key。我们可以利用这个bool判断map中是否存在该key

1.6 函数

go的函数命名是 func Name(para Type) (返回值) {函数体}。go的函数相比于c++有以下特点

  • 可以返回多个值
  • 可以为返回值命名
  • 相同类型的参数可以简写
func add(a int, b int) int {
	return a + b
}

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

1.7 结构体

go中的结构体有点像其他的语言里面的类。结构体里面定义数据类型。

type user struct {
	name     string
	password string
}

结构体的方法叫接收器,类似于类的成员函数。在func的后面加一个结构体的声明表明该方法是这个结构体的接收器。接收器的结构体对象一般有两种:值和指针。如果是值,就无法改变结构体的变量值。

func (u user) checkPassword(password string) bool {
	return u.password == password
}

1.8 字符串操作

字符串处理的包主要有两个:strings和strconv

strings包主要的一些功能

strings.Contains(a, "ll"))                // 包含字符串
strings.Count(a, "l")) 					  // 统计字符串出现次数
strings.HasPrefix(a, "he"))               // 是否是前缀
strings.HasSuffix(a, "llo"))              // 是否是后最
strings.Index(a, "ll"))                   // 索引
strings.Join([]string{"he", "llo"}, "-")) // 连接
strings.Repeat(a, 2))                     // 重复
strings.Replace(a, "e", "E", -1))         // 替换
strings.Split("a-b-c", "-"))              // 切分
strings.ToLower(a))                       // 转大写
strings.ToUpper(a))                       // 转小写

strconv主要是字符串转换

1.9 json处理

将struct转化为json字符串。从json字符串生成结构体

json.Marshal(struct) ([]byte, error) 将结构体解析成json字符串

json.Unmarshal([]byte, struct) 从json字符串中解析struct,注意这里的结构体要传地址,不然值传递是修改不了的。

二 项目

2.1 猜数字

**需求:**生成一个[0, 100)的随机数,让用户猜这个数。程序会给出用户每次猜的结果是大还是小。

算法实现很简单就不说了,下面谈一下几个需要注意的问题。

首先是随机数,go的随机函数在math/rand这个包下面,使用随机函数的时候需要先设置随机种子,一般是以当前时间来设置。否则每次重新运行程序后随机的数字是一样的。

然后是输入的问题。用户输入是从控制台输入的,也就是标准输入os.Stdin。我们可以先利用stdin构造一个输入流,然后不断的从这个流里面读数据。就是样例代码里的写法。

除了这种复杂的写法,fmt包还提供了类似于c的scanf这种输入,可以直接从控制台输入。需要注意的是,这里要加个\n换行读掉输入的空行,否则在for里面用fmt.Scanf会把最后输入的回车也当作一次输入。

func main() {
	rand.Seed(time.Now().UnixMilli())
	num := rand.Intn(100)

	for {
		var number int
		fmt.Scanf("%d\n", &number)

		if number < num {
			fmt.Println("小了")
		} else if number > num {
			fmt.Println("大了")
		} else {
			fmt.Println("猜对了")
			break
		}
	}
}

2.2 翻译小程序

需求:用go实现一个单词翻译的程序。能将单词作为命令行参数输入,程序输出单词的中文含义。

主要的实现思路是用go发送翻译请求给翻译网站,然后解析返回的数据。

将请求转换成go代码:curlconverter.com/go/

根据服务器返回的json生成struct oktools.net/json2go

我们要做的只有:

  • 利用os.Arg[1]读取main函数的参数,并作为需要翻译的单词
  • 解析返回的数据,并找到翻译结果的字段打印出来即可