Go语言基础语法 | 青训营

124 阅读6分钟

Go语言基础语法 | 青训营

Go的基本语法概念

  • 包(Packages):Go程序由包组成,每个文件都属于一个包。包是代码的组织单位,用于提供可重用的功能。
  • 导入(Imports):使用import关键字导入其他包。导入的包可以使用其中的函数、类型和变量。
  • 函数(Functions):使用func关键字定义函数。函数可以有参数和返回值。
  • 变量(Variables):使用关键字var声明变量。Go是一种静态类型语言,变量的类型在声明时确定。
  • 常量(Constants):使用关键字const声明常量。常量是不可修改的值。
  • 控制流程(Control Flow):Go语言支持常见的控制流程结构,如条件语句(if-else),循环语句(for),以及跳转语句(break、continue和return)。
  • 数据类型(Data Types):Go语言提供了基本数据类型,如整数类型(int、int8、int16等)、浮点数类型(float32、float64)、布尔类型(bool)、字符串类型(string)等。
  • 数组(Arrays)和切片(Slices):数组是具有固定长度的数据结构,切片是对数组的动态长度的抽象。
  • 结构体(Structs):结构体是一种自定义的复合数据类型,用于组合不同类型的值。
  • 指针(Pointers):指针是保存变量内存地址的变量。可以通过指针来访问变量的值或修改变量的值。
  • 方法(Methods):Go语言支持在结构体上定义方法,方法是一种与特定类型关联的函数。
  • 接口(Interfaces):接口定义了一组方法的集合。实现了接口中所有方法的类型被称为该接口的实现类型。
  • 并发(Concurrency):Go语言内置了并发编程的支持,通过goroutine和channel来实现并发操作。

hello world

package main // 表示这个文件是入口文件

import ( // 导入标准库中的fmt包,输入输出格式化字符串
    "fmt"
)

func main(){ // main函数
    fmt.Println("hello world") // 输出
}

运行项目

go run 项目名字
或
go build 项目名字
./项目名字

Go是强类型语言 字符串是内置类型,可以通过+直接进行拼接,可以用==比较字符串 声明变量

var a = "initial"var b, c int = 1, 2
或
g := a + "foo"

声明常量

const h = 30000
或
const s string = "constant"

常量没有确定的类型,会根据使用的上下文自动确定类型 if-else 与C++不同:1、if后面的条件没有括号;2、if后面的语句必须加大括号 for Go只有for循环 死循环

for {
    ...
}

有边界条件的循环

for j := 7; j < 9; j++ {
    fmt.Println(j)
}

break跳出循环;continue继续循环 switch-case 与C++不同:1、switch后面的变量不需要加括号;2、case默认都有break;3、变量类型可以是字符串或者结构体

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可以取代任意的if-else

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
a[4] = 100
fmt.Println(a[4], len(a))
b := [5]int{1, 2, 3, 4, 5}
fmt.Println(b)
var twoD [2][3]int
for i := 0; i < 2; i++ {
    for j := 0; j < 3; j++ {
        twoD[i][j] = i + j
    }
}
fmt.Println("2d: ", twoD)

slice切片 长度可变 用make创建切片

s := make([]string, 3)
s[0] = "a"

用append添加元素

s = append(s, "d")

用copy复制切片

c := make([]string, len(s))
copy(c, s)

输出

fmt.Println(s[2:5]) // 输出s[2] s[3] s[4]
fmt.Println(s[:5]) // 输出s[0] s[1] s[2] s[3] s[4]

map 随机顺序 用make创建

m := make(map[string]int) // key是string类型,value是int类型
m["one"] = 1
m["two"] = 2
fmt.Println(m) // map[one:1 two:2]
fmt.Println(m["one"]) // 1
r, ok := m["unknow"]
fmt.Println(r, ok) // 0, false

用delete删除

delete(m, "one")

range 快速遍历slice和map 遍历数组时,返回两个值:索引和值

nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {
    sum += num
    if num == 2 {
        fmt.Println("index: ", i, "num: ", num) // index: 0 num: 2
    }
}
fmt.Println(sum) // 9

遍历map时,返回两个值:key和value

m := map[string]stirng{"a": "A", "b": "B"}
for k, v := range m {
    fmt.Println(k, v) // b 8; a A
}
for k := range m {
    fmt.Println("key", k) // key a; key b
}

函数 变量类型后置

func add(a int, b int) int {
    return a + b
}

可以返回多个值,先返回真正的结果,再返回错误信息

func exists(m map[string]string, k string) (v string, ok bool) {
    v, ok = m[k]
    return v, ok // ok表示是否存在
}

指针 对常用的参数进行修改

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

func main() {
    n := 5
    add2ptr(&n)
    fmt.Println(n) // 7
}

struct结构体 声明

type user struct{
    name string
    password string
}

初始化

a := user{name: "wang", password: "1024"}
或
b := user{"wang", "1024"}
或
var d user
d.name = "wang"
d.password = "1024"

指针

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

fmt.Println(checkPassword(&a, "1024")) // true

结构体方法

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

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

a.resetPassword("2048")
fmt.Println(a.checkPassword("2048")) // true

错误处理 在函数返回值中加error类型的变量

import {
    "errors"
    "fmt"
}

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

u, err := findUser([]user{{"wang", "1024"}}, "wang")
if err != nil {
    fmt.Print(err)
}

字符串

import {
    "strings"
}

a := "hello"
strings.Contains(a, "ll") // 是否包含, true
strings.Count(a, "l") // 计数, 2
strings.HasPrefix(a, "he") // 是否是前缀, true
strings.HasSuffix(a, "llo") // 是否是后缀, true
strings.Index(a, "ll") // 查找某个字符串的位置, 2
strings.Join([]string{"he", "llo"}, "-") // 连接多个字符串, he-llo
strings.Repeat(a, 2) // 重复多个字符串, hellohello
len(a) // 字符串长度, 5, 中文可能对应多个字符

字符串格式化

s := "hello"
n := 123
p := point{1, 2}
fmt.Println(s, n) //打印多个变量并换行
fmt.Printf("s=%v\n", s) // %v可以表示任意类型的变量, s=hello
fmt.Printf("p=%v\n", p) // p={1 2}
fmt.Printf("p=%+v\n", p) // %+v表示更加详细的结果, p={x:1 y:2}
fmt.Printf("p=%#v\n", p) // %#v表示更加详细的结果, p=main.point{x:1 y:2}
f := 3.1415
fmt.Printf("%.2f\n", f) // 保留两位小数, 3.14

json处理 结构体的每个变量首字母都是大写时,可以json序列化,成为16进制的编码,也可以反序列化

import { "encoding/json" "fmt" } type userInfo struct { Name string Age int json:"age" Hobby []string }

func main() { a := userInfo{Name: "wang", Age 18, Hobby: []string{"Golang", "Typescript"}} buf, err := json.Marshal(a) if err != nil { panic(err) } fmt.Println(buf) // {123 34 78 97...} fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","Typescript"]} var b userInfo err = json.Unmarshal(buf, &b) if err != nil { panic(err) } fmt.Printf("%#v\n", b) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang","Typescript"}} }

时间处理

import { "fmt" "time" }

func main() { now := time.Now() 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.Year(), t.Month(), t.Day()) // 2022 March 27 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(now.Unix()) // 时间戳, 1648738080 }

数字解析

import { "fmt" "strconv" }

f, _ := strconv.ParseFloat("1.234", 64) fmt.Println(f) // 1.234

n, _ := strconv.ParseInt("111", 10, 64) // 10进制(0表示自动推测),返回精度是64位的整数 fmt.Println(n) // 111

n2, _ := strconv.Atoi("123") fmt.Println(n2) // 123

进程信息

import { "fmt" "os" "os/exec" }

fmt.Println(os.Args) // 获取命令行参数,返回目录+项目名字+后面跟的参数 fmt.Println(os.Getenv("PATH")) // 获取环境变量 fmt.Println(os.Setenv("AA", "BB")) // 修改环境变量 buf, err exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput() // 启动子进程,获取输入输出