main.go
// mail.go
// 一个 go 程序中只有一个入口,main 包下的 main 函数。
package main
// 引入包。
import (
"apiserver/router"
"errors"
"github.com/gin-gonic/gin"
"log"
"net/http"
"time"
)
// 每个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数(如果有 init() 函数则会先执行该函数)。
func main() {
// Create the Gin engine.
// 以下格式只能在函数内使用。此为定义一个变量。
// Go语言的变量和函数的公有私有靠首字母大小写区分,首字母大写是公有的,小写的私有的。
g := gin.New()
// Go 语言切片是对数组的抽象。Go 数组的长度不可改变,切片为 Go 内置类型,也叫"动态数组",追加元素可能使切片容量增大。
middlewares := []gin.HandlerFunc{}
// Routes.
// router 包是我们自己写的一个包。里面定义了一个 Load 函数。
// Load 函数接收 *gin.Engine 和 ...gin.HandlerFunc 作为实参。
// * 代表变量的指针,实际使用时通过指针引用变量地址使用。
// ... 代表实参是个变长参数(长度不固定)。
// gin 中的 middleware,本质是一个匿名回调函数。这和绑定到一个路径下的处理函数本质是一样的。
// 回调函数(callback function),就是一个应用传递给一个库函数的参数,而这个参数为一个函数。
// 打个比方,住酒店(应用)时需要使用叫醒服务(库函数),需要客人(用户在app上操作)指定叫醒的方法(回调函数)。
// 叫醒的方法里预定义了几个方式(回调函数中的属性),比如"打电话叫醒", "敲门叫醒", "从天花板落水下来"等。
router.Load(
// Cores.
g,
// Middlewares.
middlewares...,
)
// Ping the server to make sure the router is working.
// go 语言通过 goroutine 实现高并发,而开启 goroutine 的钥匙正时 go 关键字。
// 这里实际上是一个匿名 goroutine 函数。
go func() {
if err := pingServer(); err != nil {
log.Fatal("The router has no response, or it might took too long to start up.", err)
}
log.Print("The router has been deployed successfully.")
}()
// 日志模块的基本使用方法。
// 格式化打印的基本使用方法。
log.Printf("Start to listening the incoming requests on http address: %s", ":8080")
log.Printf(http.ListenAndServe(":8080", g).Error())
}