GO基础
- init函数与main函数执行顺序
- 越是底层依赖的init函数,越是会优先执行,最后才执行main函数
- 在执行init函数之前,会先定义好各个包的全局变量
- —参考文档
当我们导入其他包时,会先初始化导入的包,而初始化包时,会先加载全局变量,而后从上到下加载init()函数,
当被导入的包的init()函数执行完毕后,执行调用方的全局变量加载,init()函数的顺序加载,之后执行main()函数。
& 是取变量内存地址符号
* 指针变量相关操作 (申明指针变量类型,与获取指针变量的值)
:= 表示自动处理类型申明并赋值
func main() {
var a int= 20
var ip *int
ip = &a
fmt.Printf("a 变量的地址是: %x\n", &a )
fmt.Printf("ip 变量储存的指针地址: %x\n", ip )
fmt.Printf("*ip 变量的值: %d\n", *ip )
}
数组大小不可改变,切片大小可以改变
数组定义: var balance [10] float32
切片定义: var identifier []type
切片的 len cap append copy
for key, value := range oldMap {
newMap[key] = value
}
- map 切片 类java
- 接口 概念类似 面向对象的类
其他基础
- 结构体-参考资料
- go语言支持对结构体指针 直接使用.来访问结构体的成员
- new 关键字对结构体实例化,得到的是结构体的指针
- 对结构体取地址,相当于对该结构体,进行了一次new操作
- 结构体初始化 键值对 、 值的列表
- 指针类型接受者,拿到的是接受者本身,值类型的接受者,拿到的是副本,不会改变接受者
- 嵌套结构体,实现结构体的继承
- byte 就是uint8 (对应ascii编码)
- rune 就是 int32 (对应unicode编码)
- 多模块开发
go work init
踩坑记录
- 路由绑定的控制器方法,首字母必须大写 (go 首字母大写,代表对外部可见)
- 结构体 各项属性定义的后面 `` 就是称为tag 可以通过反射拿出来
- 这套代码的DB 使用函数式样的调用 默认是没有执行连接操作的
- go中一个文件夹为一个包
- go暂不支持默认值
- go不同的响应结构,就要有不同的结构体
- 8000端口占用 获取PID
netstat -ano | findstr "8000"
杀进程 taskkill /PID 16904
- 跨域中间件 需要设置在第一个才生效
- go依赖 多个版本,会不同库
- jwt 目前的新版本 go get -u github.com/golang-jwt/jwt/v4
- 变量只要定义了,就不会是nil 除非定义的是指针
- 单元测试时候,获取yaml配置失败 原因文件路径不对
- go的对象的方法,就是指针的方法
写法学习
- 打印结构体类型 fmt.Printf(“%T\n”, p3) %T
- 打印结构体属性及值 fmt.Printf(“p3=%#v\n”, p3) %#v
- map[string]interface{}{} 创建一个映射 键是string类型 值是interface{}类型 并初始化为空映射
- 一个自由编写响应体示例:map[string]interface{}{“parseToken”: parseToken, “expire”: time.Now().Add(time.Hour * 2).Unix(), “token”: token}
- GORM 结构体"继承" 写法,并指定前缀
gorm:"embedded;embeddedPrefix:author_"
appointment := model.AppointmentDate{}
//初始化空的切片,如果只声明,就会空指针- GO编码规范
- GORM自动生成结构体工具
- 中文GORM手册
- 时间库
go get github.com/golang-module/carbon
- JSON库
go get github.com/json-iterator/go
自动处理输入类型与struct字段类型不一致 需要断言的问题 - GORM 限定关联模型的查询字段
- 函数可变参数曲线救国
可变参数语法糖
结构体默认值
- GO泛型基础
- GO映射基本用法
- iota 常量枚举写法 (只读情况下可用,有写的情况,慎用)
- 工具:JSON转结构体
- 返回error就是抛错
- Context函数 做请求超时的控制,做中止上下文协程控制 以及上下文传值 例如请求中间件
- 模型结构体中,含有非数据库字段 这样写
gorm:"-:all"
表示忽略读写与迁移
var inquiry model.Inquiry
database.Db.Preload("User", func(db *gorm.DB) *gorm.DB {
return db.Select("id,nickname,gender,phone")
}).
Where("id = ?", 1).
Select("id,doctor_id,user_id").
Find(&inquiry)
var userIds []int
database.Db.Model(&model.Inquiry{}).Where("doctor_id = ?", doctor.Id).
Where("status = ?", model.InquiryStatusValid).
Pluck("user_id", &userIds)
sub := database.Db.Model(&model.InquiryMessages{}).
Select("max(id)").
Where("message_type = ?", model.MessageTypeText).
Group("user_id")
database.Db.Model(&model.InquiryMessages{}).
Select("user_id,message,created_at").
Where("id in ?", sub).
Where("doctor_id = ?", doctor.Id).
Where("user_id in (?)", userIds).
Order("created_at desc").
Scan(&latestMsg)
GRPC
安装
- 先安装对应平台的 protoc 安装地址
- 安装go语言插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
- 安装GRPC插件
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
- 上边两个插件,会安装到goPath下的bin目录里面,需要添加环境变量
- 环境检查
protoc --version
protoc-gen-go --version
protoc-gen-go-grpc --version
使用
- 编写 proto 文件 示例 ./study/hello.proto
- 生成go文件
protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative hello.proto
- 安装依赖
go get google.golang.org/grpc
此依赖,包含了 protobuf - 编写服务端代码 实现 SayHello 方法 启动服务
- 编写客户端代码,进行调用
PHP调用Go的grpc服务
- 下载安装 PHP的gRPC扩展和protobuf扩展 (protobuf 扩展没有windows版本,可以不安装,使用下面的composer安装)
生成PHP基础模板文件 protoc --php_out=. ./hello.proto
自己编写client文件 (因为未找到 grpc_php_plugin 命令,就自己编写PHP文件 或者花时间自己编译该命令)- 使用下面docker生成PHP文件
- 安装依赖
composer require grpc/grpc
composer require google/protobuf
- 加载生成的文件到psr-4命名空间
"GPBMetadata\\":"grpc/GPBMetadata/","Study\\":"grpc/Study/"
- 自己测试的,可用的client文件示例 在 项目目录/study/Study/GreeterClient.php
- 测试代码内容 在 项目目录/study/php/client_code.txt
- PHP-grpc参考资料
docker grpc_php_plugin 生成PHP代码的工具
- docker pull llaoj/php-grpc-gen
- 使用说明