这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
今天把之前课程的笔记和内容整理复习一下
Go编译型语言,工具链将源代码及其依赖转换成机器语言(静态编译)
Go的特点:高性能、自带高并发、静态链接、快速编译、跨平台、有gc
GOROOT是go自带的包,GOPATH是下载的包
Go里面是包(c++的库),package main表示当前是main包,package A表示当前是A包
包的命名通常是GOPATH/src下最后一级目录名(main例外)
import ("fmt")引入其他包
go run main.go 编译链接并直接运行(不产生文件)
go build main.go编译链接产生文件
fmt格式化输入输出包,fmt.Println("hello,world", 1)输出两个
math数学包,math.sin(a)
fmt.Printf("%d %d\n", a, b) 格式化输出,类似c++的printf,%v自动判断类型,%+v显示详细内容,%#v更详细
编译器会在特殊符号后加分号,所以不要乱换行,否则会出错(gofmt工具可以规范格式)
{必须和函数在一行
os包包括和系统的交互
os.Args变量是参数切片,os.Args[0]是命令本身,os.Args[1:len(os.Args)]其余所有参数
exec.Command(...).CombinedOutput()按命令启动子进程并获得子进程输出
buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
if err != nil {
panic(err)//触发panic错误
}
变量
go是强类型语言(编译时就决定变量类型)
可以自动判断变量类型var a = "init"
也可以指定(go的类型都是后缀)var b, c int = 1, 2
s := ""
var s string
var s = ""
var s string = ""
变量定义var a = 1和a := 1一样
短变量声明a:=1只能用在函数内,不能作为包变量(类似全局变量)
常量没有类型const a = 1、const s string = "abc"
变量默认初始化为0或空
可以使用+进行字符串拼接,+=将适当时回收旧字符串,如果数据量大推荐使用strings.Join拼接字符串
s=strings.Join(os.Args[1:], " ")(只在args中间加" ")
自增自减在go里面是语句,c++是表达式,所以i++ i=i-1可以,j=i++不行
for/range/switch/if
只有for循环,{必须和for一行,裸for必须有break退出否则死循环
for j := 7; j < 9; j++{//}
for _, arg := range os.Args[1:] {
s += sep + arg
sep = " "
使用range遍历时产生索引及其对应的元素值,但go不允许无用的局部变量,所以如果局部变量用不上就使用空标识符_
if-else没有(),{必须和if一行
break和continue和c一样
switch a {//}且不需要break就能自动停止当前case,a可以是变量
数组
var a [5]int数组,长度固定且必须在编译时确定
[2]int和[3]int是两种不同的类型,所以不能再赋值成别的类型
a[2] = 100
b :=[5]int{1,2,3,4,5}
var q [3]int = [3]int{1, 2, 3}(其他默认0)
q := [...]int{1, 2, 3}(自动获得长度)
(len(a)返回数组长度)
fmt.Println(b)打印整个数组,也可以直接打印多维数组
c := [2][3]int
a[1:3]取[1,3)的子序列,0和最后len(a)可以省略
slice切片
slice切片底层引用一个数组对象,一个slice包括指针、长度、容量,指针对应底层数组的slice起始元素的地址。容量是到底层数组的结尾,切片操作可以超出长度,不能超出容量。
多个slice可以共享一个底层数组
对于数组months := [...]string{1: "January", /* ... */, 12: "December"}
0处是默认的"",即len(months)==13
months[1:13]就是整个数组的切片
切片可以从数组上切,也可以通过make([]T, len, (cap))创建切片,默认len=cap
s=append(s, "d", "f")通过append追加进slice,注意必须返回给原切片,因为可能发生扩容,扩容时会产生新的slice
copy(dest, src)切片复制
map
make函数创建map:make(map[string]int) 其中[key]value,和c++类似,当不存在key时自动创建并value为0 例如counts[input.Text()]++
遍历map的顺序是随机的
for line, n := range counts {
if n > 1 {
fmt.Printf("%d\t%s\n", n, line)
}
}
delete(counts, "one")删除key
a, ok=counts["unknow"],a取对应的value,ok获得是否存在该key(true/false)
可以map[string]string
循环输入
input := bufio.NewScanner(os.Stdin) 类型是bufio.Scanner,调用input.Scan()读取一行,读取成功返回true和false,input.Text()返回读取的字符串(类似c++的循环读取)
例:统计输入的字符串
func main() {
counts := make(map[string]int)
input := bufio.NewScanner(os.Stdin)
for input.Scan() {
counts[input.Text()]++
}
for line, n := range counts {
if n > 1 {
fmt.Printf("%d\t%s\n", n, line)
}
}
}