有没有办法将字符串或错误作为泛型参数?

package controller

import (
    "fmt"
    "net/http"

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

type ServerError[T fmt.Stringer] struct {
    Reason T `json:"reason"`
}

func ResponseWithBadRequest[T fmt.Stringer](c *gin.Context, reason T) {
    c.AbortWithStatusJSON(http.StatusBadRequest, ServerError[T]{Reason: reason})
}

上面的代码包含一个帮助器函数,它try 用一个包含一个通用字段的json来响应http请求,我希望它是stringerror.

但当我try 输入字符串时:

string does not implement fmt.Stringer (missing method String)

我觉得这很有趣.

我试着把T fmt.Stringer改成T string | fmt.Stringer:

cannot use fmt.Stringer in union (fmt.Stringer contains methods)

我理解的原因是,Golang中的string是一个没有任何方法的原始数据类型,我想知道是否有可能做到这一点的方法.


Update:

正如@nipuna在 comments 中指出的那样,error也不是Stringer.

推荐答案

有没有办法将字符串或错误作为泛型参数?

不是的.如前所述,您正在寻找的约束是~string | error,这是不起作用的,因为带有方法的接口不能在联合中使用.

error确实是与Error() string方法的接口.

处理这一问题的明智方法是放弃泛型,将Reason定义为string:

type ServerError struct {
    Reason string `json:"reason"`
}

你可以在这里找到更多细节:Golang Error Types are empty when encoded to JSON.Tl;dr是error无法不应该直接编码为JSON;无论如何,您最终都必须提取它的字符串消息.

最后,您将对字符串执行类似的操作:

reason := "something was wrong"
c.AbortWithStatusJSON(http.StatusBadRequest, ServerError{reason})

类似这样的错误:

reason := errors.New("something was wrong")
c.AbortWithStatusJSON(http.StatusBadRequest, ServerError{reason.Error()})

Go相关问答推荐

难以为多个平台添加Go Bazel构建选项

一种基于时间的Golang函数节制器

错误.如果它包含切片,则返回FALSE

为什么Slices包中的函数定义Slice参数的类型参数?

如何在围棋中从多部分.Part中获取多部分.文件而不保存到磁盘?

在nixos上找不到XInput2.h头文件的包

在整个SQL事务中将使用上下文作为默认设置吗?

在 go 中,将接收器 struct 从值更改为指针是否向后兼容?

使用 Golang 获取目录磁盘使用情况

Go 中如何调用测试函数?

当图像是对象数组的元素时,如何显示存储为页面资源的图像?

具有嵌套重复的正则表达式

此代码如何生成内存对齐切片?

函数调用中的类型参数panic

GRPC 反向代理混淆 GRPC 和 GRPC-Web

httprouterhttp.HandlerFunc() 是如何工作的?

Golang:每个键具有多个值的映射

Golang 有类似 C++ 的 decltype 的东西吗?

gob 解码器仅返回数组中的第一个元素

如何获得Ent中数字列的总和