是谁 2024 年才开始学 go?哦,原来是我
结构体
type Person struct {
name string
age int32
}
person := Person{
name: "Name",
age: 3
}
数组
arr := []int32{1, 2, 3}
arr[1] = 200
// push
arr = append(arr, 4, 5)
// unshift
arr = append([]int32{-1, 0}, arr...)
// pop
arr = arr[0 : len(arr) - 1]
// shift
arr = arr[1:]
遍历
// go 语言钟可以用多个变量接收多个值
for index, item := range arr {
fmt.Println(index, item)
}
// 如果有些返回的值是无用的,可以用 _ 占位
for _, item := range arr {
fmt.Println(item)
}
函数
// 以下函数接收类型为 int32 的两个参数,并返回 3 个类型为 int32 的值
func add(a, b int32) (int32, int32, int32){
return a, b, a + b
}
a, b, result := add(1, 2)
错误处理
// 没有问题:result, ok := test()
result, error := test()
if error != nil {
// 处理错误
return
}
指针
type A struct {
b int32
}
func main(){
a := 1
example(&a)
b := A{b: 1}
example2(&b)
}
func example(a *int) {
*a = 2
fmt.Println(a)
}
func example2(a *A){
(*a).b = 2
fmt.Println("test:", a)
}
类方法
比如 ts 中定义一个 arr.push 之类的方法
class Array {
private arr: number[];
constructor(arr: number[]) {
this.arr = arr;
}
push() {
// ....
}
}
在 go 语言中可以这样实现
type Array[T any] interface {
push(args ...T) int
forEach(callback func(item T, index int, array []T))
}
type ArraySt[T any] struct {
array []T
}
// 结构体绑定方法要在外面写
// go 语言中不存在 this,是用接收器实现的
func (arrSt *ArraySt[T]) push (args ...T) int {
arrSt.array = append(arrSt.array, args...)
return len(arrSt.array)
}
func (arrSt *ArraySt[T]) forEach (args ...T){
for index, item := range arrSt.array {
callback(item, index, arrSt.array)
}
}
func main(){
var arr Array[int32] = &ArraySt[int32]{
[]int32{1, 2, 3}
}
len := arr.push(4, 5)
fmt.Println(len)
arr.forEach(func(item int32, index int, arr []int32) {
fmt.Println(item, index, arr)
})
}
map
type Test struct {
a int
b int
}
test := Test{
a: 1,
b: 2,
}
func main(){
// ket type 是 any,value type 是 int32
var m map[any]int32
m = map[interface{}]interface{}{
"a": 1,
1: 2,
test: 3
}
a := m["a"]
b := m[1]
c := m[test]
fmt.Println(a)
m["a"] = 100
}
其他 tips
“” → 字符串,’’ → 字符
开头大写的变量才能被包外访问
Gin 基础
假设有学生数据如下:
type Student struct {
Id int64 `json:"id"`
Name string `json:"name"`
Age int32 `json:"age"`
Courses []string `json:"courses"`
}
Students := []Student{
{
Id: 1,
Name: "Mike",
Age: 15,
Courses: []string{"Java", "JS"}
}
}
可以编写后端代码形式如下:
package main
import (
"github.com/gin-gonic/gin"
)
// 解决跨域问题
func Cors () gin.HandlerFunc {
return func(c *gin.Context){
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Headers", "Content-Type")
c.Header("Access-Control-Allow-Methods", "GET,POST")
if c.Request.Method == "OPTIONS" {
c.JSON(http.StatusOK, "")
c.Abort()
return
}
c.Next()
}
}
func main(){
r := gin.Default()
r.Use(Cors())
r.GET("students", func (c *gin.Context){
c.JSON(http.StatusOK, gin.H {
"code": 0,
"msg": "ok",
"data": data.students
})
})
r.GET("/student/:id", func(c *gin.Context){
id, _ := strconv.ParseInt(c.Param("id"), 10, 64)
for _, s := range data.Student {
if s.Id === id {
c.JSON(http.StatusOK, gin.H {
"code": 0,
"msg": "ok",
"data": s,
})
}
}
})
r.POST("/delete", func (c *gin.Context){
var body PostBody
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(400, gin.H{
"code": 1,
"msg": err.Error(),
})
return
}
for i, s := range data.Students {
if s.Id == body.Id {
target := data.Students[i]
data.Students = append(data.Students[:i], data.Students[i + 1:]...)
c.JSON(http.StatusOK, gin.H{
"code": 0,
"msg": "ok",
"data": target
})
return;
}
}
c.JSON(http.StatusOK, gin.H{
"code": 1,
"msg": "Invalid student ID",
})
})
r.POST("/edit", func (c *gin.Context){
var body data.Student
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(400, gin.H{
"code": 1,
"msg": err.Error(),
})
return
}
for i, s := range data.Students {
if s.Id == body.Id {
data.Student[i] = body;
c.JSON(http.StatusOK, gin.H{
"code": 0,
"msg": "ok",
"data": s.Id
})
return;
}
}
c.JSON(http.StatusOK, gin.H{
"code": 1,
"msg": "Invalid student ID",
})
})
if err := r.Run(":3000"); err != nil {
fmt.Println("Server error")
}
}
参考:https://www.bilibili.com/video/BV1EC411p7AK 一款更适合前端宝宝的 go 入门视频