走进go语言基础|青训营笔记

32 阅读5分钟

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

走进go语言基础语言

什么是go语言

  1. 高性能、高并发
  2. 语法简单,学习曲线平缓
  3. 丰富的标准库
  4. 完善的工具链
  5. 静态链接
  6. 快速编译
  7. 跨平台
  8. 垃圾回收

go的基础语法

// Hello World

package main

import {
    "fmt"
}

func main() {
    fmt.Println("hello world")
}

go中的变量

变量的声明:

  1. 通过var name type = value的方式
  2. 通过name := value

go中的ifelse

必须加{},没有()

go中的循环

go中循环只有for循环,有{},但是没有()

go中的switch语法

与c/cpp不同的是,switch中case中不需要加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")
}

go中的数组

var a [5]int
a[4] = 100
b := [5]int{1, 2, 3, 4, 5}
var twoD [2][3]int

go中数组的特点是长度固定,而切片的长度是不固定的

go中的切片

go中切片的长度是不固定的,可以追加元素,在追加的时候可能是切片的容量增大。我们可以用make来创建一个切片,可以像数组一样去取值,使用append来追加元素。
在make方法中,有两个形参,一个是用来存放元素的数组类型,另一个是初始化的长度 在append方法中,必须将append的返回值返回给原变量,因为其原理是存储了一个长度、一个容量、一个指向一个数组的指针,在你执行append操作的时候,如果容量不够的话,会扩容并返回新的切片

package main

import "fmt"

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) // [a b c d e f]

 c := make([]string, len(s))
 copy(c, s)
 fmt.Println(c) // [a b c d 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]

 good := []string{"g", "o", "o", "d"}
 fmt.Println(good) // [g o o d]
}

go中的map

数据类型和其他语言相似,由于使用hash算法,map的变量是无序的

package main

import "fmt"

func main() {
 m := make(map[string]int)
 m["one"] = 1
 m["two"] = 2
 fmt.Println(m)           // map[one:1 two:2]
 fmt.Println(len(m))      // 2
 fmt.Println(m["one"])    // 1
 fmt.Println(m["unknow"]) // 0

 r, ok := m["unknow"]
 fmt.Println(r, ok) // 0 false

 delete(m, "one")

 m2 := map[string]int{"one": 1, "two": 2}
 var m3 = map[string]int{"one": 1, "two": 2}
 fmt.Println(m2, m3)
}

go中的range

可以使用range快速遍历go中的数组,切片,map,通道,在数组和切片中返回元素的下标和元素值,在map中返回key-value对。与python相似,不需要的量可以使用下划线代替

go中的函数

如果有多个返回值

func function_name (para_name para_type,...) re_type {

}

go中的指针

与c中相似,存在指针类型,只是*在前指针类型在后,此外取地址符不变

go中的结构体

package main

import "fmt"

type user struct {
 name     string
 password string
}

func main() {
 a := user{name: "wang", password: "1024"}
 b := user{"wang", "1024"}
 c := user{name: "wang"}
 c.password = "1024"
 var d user
 d.name = "wang"
 d.password = "1024"

 fmt.Println(a, b, c, d)                 // {wang 1024} {wang 1024} {wang 1024} {wang 1024}
 fmt.Println(checkPassword(a, "haha"))   // false
 fmt.Println(checkPassword2(&a, "haha")) // false
}

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

func checkPassword2(u *user, password string) bool {
 return u.password == password
}

go中的结构体方法

结构体的属性和结构体的函数是分离的
go中的结构体方法与其他语言的类成员函数相类似 在实现结构体的方法的时候有两种写法,一种是带指针的,另一种是不带指针的。这个他们的区别的话是如果你带指针的话,那么你就可以对这个结构体做修改,如果不带指针,那么你实际上操作的是这个结构体变量的拷贝,你就无法对结构体进行修改

package main

import "fmt"

type user struct {
 name     string
 password string
}

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")) // true
}

go中的字符串操作

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
}

go中的进程信息

在go里面,我们能够用os.Args来得到程序执行的时候的指定的命令行参数。比如我们编译的一一个二进制文件,command。后面接 abcd来启动,输出就是os.Args会是一个长度为 5的slice ,第一个成员代表二 进制自身的名字。我们可以用os.Getenv("PATH")来读取环境变量。

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("-----------")
 fmt.Println(os.Getenv("PATH")) // /usr/local/go/bin...
 fmt.Println("-----------")
 fmt.Println(os.Setenv("AA", "BB"))
 fmt.Println("-----------")

 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
}

go语言的实战案例

生成随机数

与python相同,使用随机数函数前,需要设置随机数种子(虽然两者不设置随机数种子带来的后果不同)

在线字典

Socket5代理服务器