json 返回的值如下
有值的情况下
"nobility": {
"name": "",
"image": "",
"desc": ""
}
无值的情况下是
"nobility": {}

我该怎么定义

这个和泛型看起来没什么关系。struct 就是

type T struct {
Nobility struct {
Name string json:"name"
Image string json:"image"
Desc string json:"desc"
} json:"nobility"
}

不下发等于赋默认值

pastebin.com/6mC3Pn6W 根据你的需求情况选择一种就可以了

 nobilityInfo T.Nobility
 money := getMoney(val.Id, val.Gender)
 for _, value := range nobility {
 if money >= value.StartCoin && money <= value.EndCoin {
 nobilityInfo = T.Nobility{
 value.Name,
 pkg.AppSetting.QiniuUrl + value.Image,
 value.Desc,
 }
 break
 }
 }
 if val.Gender == 2 && val.NobilityClose == 2 {
 nobilityInfo = struct {}{}
 }

类似于这种我该怎么赋值
上边报错了

type Im struct{

 Nobility T `json:"nobility"`
 Time int `json:"time"`
 IsGoddess bool `json:"is_goddess"`
}
type T struct {
 Nobility struct {
 Name string `json:"name"`
 Image string `json:"image"`
 Desc string `json:"desc"`
 } `json:"nobility"`
}

我代码是这样的

json tag 里面加个 omitempty

比如我返回的值是下边的 json

{
 "code": 200,
 "data": [
 {
 "id": 1,
 "nobility": {
 "name": "",
 "image": "",
 "desc": ""
 },
 "time": 0,
 "is_goddess": false
 },

 ],
 "msg": "ok"
}

我想要的效果是如果 nobility 任何一项为空,则就是空对象

{
 "code": 200,
 "data": [
 {
 "id": 1,
 "nobility": {}, //上边的转化成这样
 "time": 0,
 "is_goddess": false
 },

 ],
 "msg": "ok"
}

type T struct {
Nobility struct {
Name string json:"name,omitempty"
Image string json:"image,omitempty"
Desc string json:"desc,omitempty"
} json:"nobility,omitempty"
}

加 ,omitempty ,这样你把这个结构转 JSON ,默认值就会不下发,比如 nil 0 "" false

我按你的方式写,我不知道怎么给 Nobility 这个 struct 赋值了。

类似于 4 楼的问题

我明白你的意思了,谢谢大家了。

再请教个问题,
我是通过 supervisor 来守护 go
我通过 supervisorctl stop program 关闭程序
然后再重启的时候,报接口被占用的错误
2023/01/11 22:38:38 listen: listen tcp :8000: bind: address already in use

我已经配置了优化退出,还是出问题。

package main

import (
"context"
"log"
"net/http"
"os"
"os/signal"
"time"

"github.com/gin-gonic/gin"
)

func main() {
router := gin.Default()
router.GET("/", func(c *gin.Context) {
time.Sleep(5 * time.Second)
c.String( http.StatusOK, "Welcome Gin Server")
})

srv := &http.Server{
Addr: ":8080",
Handler: router,
}

go func() {
// 服务连接
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()

// 等待中断信号以优雅地关闭服务器(设置 5 秒的超时时间)
quit := make(chan os.Signal)
signal.Notify(quit, os.Interrupt)
<-quit
log.Println("Shutdown Server ...")

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
log.Println("Server exiting")
}

为啥不把 ListenAndServe 放在外面,Shutdown 放 go func 里面

这块是 gin 的官方 demo ,我直接搬过来了

5s 会不会太长了

我设置成 1s,随后启动了 go 服务,然后通过 lsof -i:8000 查看 pid
执行 kill -Hup pid
这时候程序退出了,但是 8000 端口依然被监听。
代码中监听了一下信号
signal.Notify(quit, os.Interrupt, syscall.SIGQUIT, syscall.SIGHUP)

找到个好东西

json to go
mholt.github.io/json-to-go/

从结构中删除字段或将其隐藏在 JSON 响应中
这个文章比较好

cloud.tencent.com/developer/ask/sof/76384

端口被占用的话 1.看看是不是别的进程占用了 2. 思考一下进程结束了端口真的被释放了吗?

抱歉 没看清除是 supervisor 维护的。supervisor 重启应该要杀 pid 吧?不是太了解这个。可能没有真的结束进程