青训营笔记 | 第一天

85 阅读6分钟

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。

屏幕截图 2023-05-12 215203.png