golang环境安装
#运维
此安装方法仅在ubuntu和debian试过
安装
下载
wget https://golang.google.cn/dl/go1.20.5.linux-amd64.tar.gz
小于 1 分钟
#运维
此安装方法仅在ubuntu和debian试过
wget https://golang.google.cn/dl/go1.20.5.linux-amd64.tar.gz
构建echo服务路由时,请求和响应的构建需要注意一点,就是所有请求必须基于一个结构体去表示,所有的入参都要使用结构体去表示,那怕只有一个参数,除非是没有参数的get请求。
首先这样做的好处在于在不看api文档的情况下就可以明确了请求的结构和响应的结构,并且,当其结构入参或者出参的时候需要拓展时,可以通过结构体组合的方式去拓展结构体本身的结构,而不影响原本的请求结构。然后在处理的过程中直接交给Validator去校验参数是否为空。
api包下的请求和响应结构
func (c *Client) connectUDPClient(from, to *net.UDPAddr) *net.UDPConn {
log.Println("start connecting")
conn, err := net.DialUDP("udp", from, to)
if err != nil {
log.Fatalln("UDP connect fail", err)
}
log.Println("Connect success")
return conn
}
在Go中,将数据库连接作为全局变量使用是一个常见的模式,尤其是对于像*gorm.DB这样的数据库句柄。
首先,定义一个全局变量来存储数据库连接。这个变量应该是包级私有的,即不对外暴露,以防止外部包不当地访问或修改这个变量。
package mydatabase
import (
"gorm.io/gorm"
)
var db *gorm.DB
在实践中,golang的包是属于一个上下文的一个作用,文件只是这个包上下文的一个切割 比如,一下是某个控制器的包:
eventsController
eventReg.go
eventsController.go
fetchEventDetail.go
fetchEventReg.go
fetchEvents.go
创建responce结构体
type Response struct {
responce.JsonData
Geocodes []struct {
FormattedAddress string `json:"formatted_address"`
Country string `json:"country"`
Province string `json:"province"`
Citycode string `json:"citycode"`
City string `json:"city"`
District string `json:"district"`
Township []any `json:"township"`
Neighborhood struct {
Name []any `json:"name"`
Type []any `json:"type"`
} `json:"neighborhood"`
Building struct {
Name []any `json:"name"`
Type []any `json:"type"`
} `json:"building"`
Adcode string `json:"adcode"`
Street string `json:"street"`
Number string `json:"number"`
Location string `json:"location"`
Level string `json:"level"`
} `json:"geocodes"`
}
这里以github.com/go-playground/validator/v10为例:
首先安装对应的第三方包:
go get github.com/go-playground/validator/v10
目前go的编写静态方法是一个包对应一个文件,而这个文件里面定义的参数,函数都是该包的静态方法,也就说,go文件里面所定义的以前东西都是包作用域 以这个包作为例子:
package LogUtils
import (
"log"
"os"
)
const (
InfoText = "\033[1;32;40m[info]\033[0m "
WarningText = "\033[1;33;40m[warning]\033[0m "
ErrorPrintText = "\033[1;31;40m[error]\033[0m "
EndPrintText = "\033[1;36;40m[end]\033[0m "
)
var logger *log.Logger
func init() {
logger = log.New(os.Stdout, "[Debug] - ", log.LstdFlags|log.Lshortfile|log.Lmsgprefix)
}
func Info(v ...string) {
logger.Println(InfoText, v)
}
func Warning(v ...any) {
logger.Println(WarningText, v)
}
func ErrorPrint(v ...any) {
logger.Panicln(ErrorPrintText, v)
}
func EndPrint(v ...any) {
logger.Fatalln(EndPrintText, v)
}
go的设计思想是将抽象与实现分离,在实现的时候才将其注入,这样其实就具备了控制反转。看以下例子:
type Logger interface {
Log(message string)
}
type ConsoleLogger struct{}
func (c ConsoleLogger) Log(message string) {
fmt.Println(message)
}
func Process(logger Logger) {
logger.Log("Processing data")
}
func main() {
var logger Logger = ConsoleLogger{}
Process(logger)
}