Go语言基础语法 | 青训营笔记

44 阅读5分钟

简介

Go语言优点

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

实现一个静态文件访问,支持高并发、高性能的服务器:

package main
include (
    "net/http"
)
func main() {
    http.Handle("/", http.FileServer(http.Dir(".")))
    http.ListenAndServe(":8080", nil)
}

为什么使用Go

  1. 最初使用的 Python,由于性能问题换成了 Go
  2. c++ 不太适合在线 Web 业务
  3. 早期团队非 Java 背景
  4. 性能比较好
  5. 部署简单、学习成本低
  6. 内部 RPC 和 HTTP 框架的推广

基础语法

Hello World

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

编译、运行:

go run ./main.go
------------------------
go build ./main.go
./main

变量声明:

var a = "initial"
var b, c int = 1, 2
var d = true
var e float64
f := float32(e)
g := a + "foo"
const s string = "constant"
const h = 5000000
const i = 3e20 / h

if-else:

if num := 7; num % 2 == 0 {
    .....
} else if num < 10 {
    .....
} else {
    .....
}

for循环:

for {
    // 死循环
}
for j := 1; j < 9; j++ {
    if j % 2 == 0 {
        continue
    }
    break
}
i := 1
for i < 100 {
    i = i + 1
}

switch语句(自带break):

package matn
import (
    "fmt"
    "time"
)
func main() (
    a := 2
    switch a (
    case 1:
        fmt.Println("one")
    case 2:
        fmt.Println("two")
    default:
        fmt.Println("other")
    }
    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
fmt.Println(len(a))
b := [5]int{1, 2, 3, 4, 5}
var twoD [2][3]int

切片(可变长度):

s := make([]string, 3)
s[0] = "a"
s = append(s, "d")
c := make([]string, len(s))
copy(c, s)
fmt.Println(s[:2], s[3:], s[1:3])

map(无序):

m := make(map[string]int)
m["one"] = 1
r, ok := m["unknow"]  // 0, false
delete(m, "one")
m2 := make(map[string]int){"one": 1, "two": 2}

range遍历:

arr := [3]int{} 
arr[0] = 1 
arr[1] = 2 
arr[2] = 3 
// index是数组下标,value对应的值 
for index, value := range arr { 
    fmt.Println(index, value) 
} 

m := map[string]int{"one": 1, "two": 2} 
//key是map的key,value是map的value 
for key, value := range (m) { 
    fmt.Println(key, value) 
}

函数:

// 函数名add,参数a, b均为int,返回值为int 
func add(a, b int) int { 
    return a + b 
} 

// 支持多值返回 
func exists(m map[string]int, key string) (v int, ok bool) { 
    v, ok := m[key] 
    return   // 上面已经给出返回v,ok,所以直接return就可以
}

指针

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

n := 5
add2(&n)

结构体:

package main
import "fmt"
func main() {
    // 直接初始化时指定
    user := User{name: "chengyunlai", password: "root"}
    fmt.Println(user)
    // 修改名称
    user.name = "Cheng"
    fmt.Println(user)

    // 定义一个变量再指定属性
    user2 := User{}
    user2.name = "GoLang"

    fmt.Println(checkPassword(&user, "123"))
    fmt.Println(user.checkPassword("123"))
}

type User struct {
    name     string
    password string
}

// 指针可以减少拷贝开销,也可以修改原值
// 指针也是用.访问成员
func checkPassword(u *User, pass string) bool {
    return u.password == pass
}

// 结构体方法(成员函数)
func (u *User) resetPassword(password string) {
    u.password = password
}

func (u *User) resetUserName(userName string) {
    u.name = userName
}

// 不带指针的结构体方法
func (u User) checkPassword(pass string) bool {
    return u.password == pass
}

错误处理

package main

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 // nil为空值
        }
    }
    return nil, errors.New("not found")
}

func main() {
    if u, err := findUser([]user{{"wang""1024"}}, "wang"); err != nil {
        fmt.PrintIn(err) // not found
        return
    } else {
        fmt.Printin(u.name)
    }
}

字符串操作

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, "lo"))               // true
    fmt.Println(strings.Index(a, "ll"))                   // 2
    fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // he-llo
    fmt.Println(strings.Repeat(a, 2))                     // hellohello
    // If n < 0, there is no limit on the number of replacements.
    fmt.Println(strings.Replace(a, "l", "L", 1))  // heLlo
    fmt.Println(strings.Replace(a, "l", "L", -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(a))                           // 5
}

字符串结构化

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.PrintIn(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.PrintIn(f)             // 3.141592653
    fmt.Printf("%.2f\n", f)    // 3.14
}

JSON处理

package main
import (
    "encoding/json"
    "fmt"
)

// 要求结构体的变量首字母为大写
type User struct {
    Name string `json:"name"` // 当转json时指定key的名称
    Age  int    `json:"age"`
}

func main() {
    user := User{Name: "Chengyunlai", Age: 24}
    fmt.Println(user) //{Chengyunlai 24}
    // 转json
    res, err := json.Marshal(user)
    fmt.Println(res)         // [123 34 78 97 ...] (乱七八糟数字)
    fmt.Println(string(res)) //{"Name":"Chengyunlai", "Age":24}
    fmt.Println(err)
    // 反序列化
    user2 := User{}
    json.Unmarshal(res, &user2)
    fmt.Println(user2) //{Chengyunlai 24}
}

时间处理

package main

import (
    "fmt"
    "time"
)

func main() {
    now := time.Now()
    fmt.Println(now)   // 2023-05-12 17:32:12.0876215 +0800 CST m=+0.005319101

    // 构造时间
    t1 := time.Date(2023, 05, 12, 17, 32, 0, 0, time.UTC)
    t2 := time.Date(2023, 05, 12, 18, 32, 0, 0, time.UTC)
    fmt.Println(t1)   // 2023-05-12 17:32:00 +0000 UTC

    // 方法
    fmt.Println(t1.Year(), t1.Month(), t1.Day(), t1.Hour(), t1.Minute())
    fmt.Println(t1.Format("2006-01-02 15:04:05"))   // 2023-05-12 17:32:00
    diff := t2.Sub(t1)
    fmt.Println(diff)                           // 1h 0m 0s
    fmt.Println(diff.Minutes(), diff.Seconds()) // 60 3600

    t3, err := time.Parse("2006-01-02 15:04:05", "2023-05-12 17:39:00") // 字符串解析
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(t3)
    // 获取时间戳
    fmt.Println(now.Unix()) // 168388446
}

数字解析

package main

import (
    "fmt"
    "strconv"
)

func main() {
    f, _ := strconv.ParseFloat("1.01545", 64)  // 64位
    f, _ := strconv.ParseInt("111", 2, 64)     // 字符串表示是二进制
    fmt.Println(f) // 7
    f, _ := strconv.ParseInt("0x1000", 0, 64)     // 自动推测进制
    fmt.Println(f) // 4096

    n, _ := strconv.Atoi("123")
    fmt.Println(n) // 转数字
    
    n, err := strconv.Atoi("AAA")
    fmt.Println(n, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax
}

进程信息

package main

import (
    "fmt"
    "os"
    "os/exec"
)

func main() {
    // go run 这个程序 a b c d
    fmt.Println(os.Args) // 获取命令行参数 [C:\Users\12579\AppData\Local\Temp\go-build3318116271\b001\exe\main.exe a b c d]

    fmt.Println(os.Getenv("PATH")) // 获取环境变量
    fmt.Println(os.Setenv("AA","BB")) // 写入环境变量

    println("----")
    buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput() // 命令行执行
    if err != nil {
        panic(err)  // 抛出异常
    }
    fmt.Println(string(buf))
}