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() // 启动子进程,获取输入输出