Golang简介
- 高性能、高并发
- 语法简单、学习曲线平缓
- 丰富的标准库
- 完善的工具链
- 静态链接
- 快速编译
- 跨平台(除了常用平台,还能在奇奇怪怪的平台上运行,如路由)
- 垃圾回收(类似jvm回收)
目前字节跳动已经全面拥抱了go语言,在市场上的使用率大厂较多。
入门
Golang安装
Golang官网:Golang官网 Golang中国镜像:Go语言中文网 开发环境:Goland
hello world
main包是Golang中的入口
在这个程序中,main函数调用了fmt.Println输出helloworld。
import会自动添加所需要的FMT包。
package main
import (
"fmt"
)
func main() {
fmt.Println("hello world")
}
变量
go语言是一门强类型语言,每一个变量都有它自己的变量类型。
go语言的字符串可以直接用加号拼接,也可以直接用等于号比较。
go语言的变量有两种声明方式,如var name string = ""或 name := ""。
常量就是将var改成const,不过常量没有确定的类型,会根据上下文自动确认类型。循环
go中没有while循环,直接for{}就是一个死循环。
循环可以通过break或continue来跳出或继续循环。
if-else
go语言的if-else和其他语言类似,不同的是if后面没有括号,但是必须接上大括号,不能像c或c++一样写成一行。
switch
switch同样也是不需要括号,而且go语言中不需要加break。
go语言的switch可以使用任意的变量类型。
数组
数组的长度是固定的,所以一般使用的是切片
切片
切片可以任意更改长度,通过make来创建一个切片。
使用append来追加元素。
使用append的话,必须将append的结果赋值为原数组。 因为切片的原理是存储了长度、容量和一个指向数组的指针,如果容量不够的话,会扩容并返回一个新的切片。map
map在其他语言里面可能叫做哈希或者字典。
map可以用make来创建,第一个类型是key的类型,第二个类型是value的类型。
可以使用delete从里面删除键值对。
golang的map是完全无序的,遍历时按照随机顺序遍历。
range
range遍历会返回两个值,第一个值是索引,第二个值是对应位置的值,如果不需要索引或者值的话,可以用下划线忽略。
函数
go语言中函数的参数是后置的。 可以返回多个值,在实际业务代码中返回的第一个值是真正的返回结果,第二个值是错误信息。
下面的第一个函数尝试将n+2,但是实际上传入的参数只是一份n的拷贝,所以如果需要对值本身进行修改的话,需要将类型写成指针类型,为了类型匹配,会在值前面加上一个&符号。
package main
import "fmt"
func add2(n int) {
n += 2
}
func add2ptr(n *int) {
*n += 2
}
func main() {
n := 5
add2(n)
fmt.Println(n) // 5
add2ptr(&n)
fmt.Println(n) // 7
}
结构体
结构体是带类型的字段的集合,和java中的类相似。 构造一个结构体变量的时候需要传入每个字段的初始值,也可以用键值对的方式去指定初始值。
结构体方法
结构体方法类似于其他语言中的类成员函数,具体的写法是将构造一个结构体放在函数名称的前面。 这样就可以通过struct.method()直接调用方法。
错误处理
go语言中可以简单的用if-else来处理错误。
在函数实现的时候,如果发生了错误,就返回一个nil和一个error。如果正常运行,就返回正常的值和一个nil。
字符串操作
strings包中常用的字符串工具函数
package main
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
}。
字符串格式化
FMT包中字符串格式相关的方法。
go语言中的占位符只需要用%v来打印任意类型的变量。
%+v打印详细结果。
%#v则更详细。
package main
import "fmt"
type point struct {
x, y int
}
func main() {
s := "hello"
n := 123
p := point{1, 2}
fmt.Println(s, n) // hello 123
fmt.Println(p) // {1 2}
fmt.Printf("s=%v\n", s) // s=hello
fmt.Printf("n=%v\n", n) // n=123
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}
f := 3.141592653
fmt.Println(f) // 3.141592653
fmt.Printf("%.2f\n", f) // 3.14
}
JSON处理
对于一个已有的结构体,只需要保证每个字段的第一个字母大写,这个结构体就可以通过JSON.marshaler去序列化。
序列化之后的字符串也可以用JSON.unmarshaler去反序列化到一个空的变量。
时间处理
获取当前时间:time.now()
对两个时间进行减法:.sub()
获取时间戳:.Unix()
package main
import (
"fmt"
"time")
func main() {
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语言中关于字符串和数字类型之间的转换都放在STR conv这个包下,全称是string convert。
string转float:strconv.ParseFloat()
string转int:strconv.ParseInt() //第二个参数为0默认转换为十进制。
十进制字符串转成数字:Atoi
数字转为字符串:itoA
package main
import (
"fmt"
"strconv")
func main() {
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f) // 1.234
n, _ := strconv.ParseInt("111", 10, 64)
fmt.Println(n) // 111
n, _ = strconv.ParseInt("0x1000", 0, 64)
fmt.Println(n) // 4096
n2, _ := strconv.Atoi("123")
fmt.Println(n2) // 123
n2, err := strconv.Atoi("AAA")
fmt.Println(n2, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax
}
进程信息
package main
import (
"fmt"
"os" "os/exec")
func main() {
// go run example/20-env/main.go a b c d
fmt.Println(os.Args) // [/var/folders/8p/n34xxfnx38dg8bv_x8l62t_m0000gn/T/go-build3406981276/b001/exe/main a b c d]
fmt.Println(os.Getenv("PATH")) // /usr/local/go/bin...
fmt.Println(os.Setenv("AA", "BB"))
buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
if err != nil {
panic(err)
}
fmt.Println(string(buf)) // 127.0.0.1 localhost
}
没看懂。
更换字典引擎
更换成火山翻译,但是resp返回的结构体不知道怎么截出来,就直接返回了extra。