Go 语言基础 | 青训营

26 阅读5分钟
  • Go语言特点

    • 高性能、高并发(使用标准库和基于标准库的第三方库)
    • 语法简单、学习曲线平缓(只有for一种循环)
    • 丰富的标准库
    • 完善的工具链
    • 静态链接(编译结果静态链接)
    • 快速编译(最快的编译速度)
    • 跨平台
    • 垃圾回收
  • 使用公司: 字节、腾讯、bilibili等

  • 配置开发环境(安装go语言,配置开发环境):

    • 安装Golang
    • 配置开发环境-集成开发环境
  • 直接运行:go run main.go

  • 生成二进制文件:go build main.go,然后用./main即可运行这个exe文件

  • 基础语法-变量

    • 变量声明的两种方式:
      • var a = "initial",会自动推导变量类型
      • f := float32(e)
    • 常量: const s string = "constant", 常量没有确定的类型,会根据上下文自动确定类型
  • 基础语法-if else(注意没有括号)

if 7%2 == 0{
    fmt.Println("7 is even")
} else{
    fmt.Println("7 is odd")
}
  • 基础语法-循环(go语言只有for循环)
for j := 7;j<9;j++{
    fmt.Println(j)
}
for {
    fmt.Println("这是一个死循环")
}
for n := 0; n<5; n++{
    if n%2 == 0{
        continue
    }
    fmt.Println(n)
}
  • 基础语法-switch(注意:默认不需要break)
a := 2
switch a{
    case 1:
    fmt.Println("one")
    case 2:
    fmt.Println("two")
    case 3:
    fmt.Println("three")
    case 4,5:
    fmt.Println("four or five")
    default:
    fmt.Println("other")
}
// switch功能更加强大,可以在case里面进行逻辑判断
t := time.Now()
switch{
    case t.Hour()<12:
        fmt.Println("It's before noon")
    default:
        fmt.Println("It's after noon")
}
  • 基础语法-数组
var a [5]int    // 一个可以存放5个int元素的数组a
a[4] = 100      //写入某个元素
// 真实代码中比较少用数组,因为其长度固定,用得更多的是切片
  • 基础语法-切片slice
// 切片是一个可变长度的数组,可以在任意时刻更改长度,也有更多操作
s := make([]string, 3)      //用make创建一个切片
s[0] = "a"
s[1] = "b"
s[2] = "c"
len(s)      //切片长度
s = append(s,"d")       //追加元素
s = append(s,"e","f")   //必须把结果赋值为原数组
// slice的原理是存储了长度加容量加一个指向数组的指针,在容量不足时会进行扩容并且返回一个新的slice
c := make([]string, len(s)) 
copy(c,s)

// 切片操作,区别于python,go不支持负数操作
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]
  • 基础语法-map(类似于字典)
m := make(map[string]int)   // 使用make创建map,这里需要两个类型,一个是key的类型,一个是value的类型。
// 使用[]写入或读取key-value对
m["one"] = 1
m["two"] = 2
fmt.Println(m)      //map[one:1 two:2]
fmt.Println(len(m)) //2
fmt.Println(m["one"]) //1
delete(m,"one")     //通过delete删除k-v对
  • 基础语法-range(使用range遍历会返回两个值,第一个为索引,第二个为值)
nums := []int{2,3,4}
sum := 0
for i, num := range nums{       //遍历数组
    sum += num
    if num == 2{
        fmt.Println("index:", i, "num: ", num)
    }
}

m := map[string]string{"a": "A", "b": "B"}
for k, v := range m{            // 遍历map
    fmt.Println(k, v)
}
  • 基础语法-函数
// 注意go里面变量类型是后置的。
func add(a int, b int) int{
    return a + b
}

// go原生支持返回多个值
func exists(m map[string]string, k string) (v string, ok bool){
    v, ok = m[k]
    return v, ok    //第一个值是真正的返回结果,第二个值是错误信息
}
  • 基础语法-指针(相较于C/C++,操作有限)
// 对传入的参数进行修改
func add2(n int){
    n += 2      //传入的是拷贝,并不能实现对n加2
}

func add2ptr(n *int){
    *n += 2
}

func main(){
    n := 5
    add2ptr(&n)
}
  • 基础语法-结构体
// 定义结构体
type user struct{
    name        string
    passward    string
}

func main(){
    a := user{name: "Wang", password: "1024"}  // 初始化
    b := user{"Wang","1024"}
    c := user{name: "Wang"}     //只初始化一部分,数字默认0,字符串默认为空
    var d user      //类型后置
    //使用.访问
    d.name = "Wang"
    d.password = "1024"

    fmt.Println(checkPassword(a,"haha"))
    fmt.Println(checkPassword2(&a,"haha"))
}

func checkPassword(u user, password string) bool {
    return u.password == password
}
// 使用指针可以实现对结构体的修改,避免大结构体的拷贝开销
func checkPassword2(u *user, password string) bool {
    return u.password == password
}
  • 基础语法-结构体方法
type user struct{
    name        string
    passward    string
}
// 在func和函数名之间用括号加上结构体就变成了结构体方法
func (u user) checkPassword(password string)bool{
    return u.password == password
}

func (u *user) resetPassword(password string){
    u.password = password
}

func main(){
    a := user{name: "wang", password: "1024"}
    a.resetPassword("2048")
    fmt.Println(a.checkPassword("2048"))
}
  • 基础语法-错误处理
//
type user struct{
    name        string
    password    string
}
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")
}

func main(){
    u, err := findUser([]user{{"wang", "1024"}}, "wang")
    if err != nil{
        fmt.Println(err)
        return
    }
    fmt.Println(u.name)

    if u, err := findUser([]user{{"wang","1024"}},"li");err != nil{
        fmt.Println(err)
        return
    }else{
        fmt.Println(u.name)
    }
}
  • 基础语法-字符串操作
import(
    "fmt"
    "strings"
)

func main(){
    a := "hello"
    fmt.Println(strings.Contains(a,"ll"))   //判断是否包含子字符串
    fmt.Println(strings.Count(a,"l"))       //字符串计数
    fmt.Println(strings.HasPrefix(a, "he"))
    fmt.Println(strings.HasSuffix(a,"llo"))
    fmt.Println(strings.Index(a, "ll"))     //查找字符串位置 2
    fmt.Println(strings.Join([]string{"he","llo"}, "-"))    //he-llo连接两个字符串
    fmt.Println(strings.Pepeat(a,2))    //hellohello
    fmt.Println(strings.Replace(a,"e","E",-1))      //hEllo
    fmt.Println(strings.Split("a-b-c","-"))     //abc
    fmt.Println(strings.ToLower(a))             //hello
    fmt.Println(strings.ToUpper(a))             //HELLO
    fmt.Println(len(a))                         //5
    b := "你好"
    fmt.Println(len(b))                         //6
}
  • 基础语法-字符串格式化
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.1415926
    fmt.Printf("%.2f\n", f) //3.14, 控制输出小数位数
}
  • 总结:Go语言在很多语法上和C/C++以及python有些类似,这里只是根据第一节课老师的PPT进行了总结,所有例子都自己跑了一遍,但是老师讲的比较快,现在正在跟着《Go语言圣经》继续学习。