Go 强制函数只接受类型,而不接受类型的基础类型

Go 强制函数只接受类型,而不接受类型的基础类型,go,struct,enums,Go,Struct,Enums,如何确保函数只接受定义的类型而不接受此类型的基础类型 我将伪枚举定义如下: 类型方法字符串 var方法=结构{ 获取方法 POST方法 贴片法 }{ 获取:“获取”, 帖子:“帖子”, 补丁:“补丁”, } 并以以下方式使用它们(简化): func getRequest(方法)(*http.Request,错误){ 返回http.NewRequest(字符串(方法),“一些随机路径”,nil) } func main(){ _,\=getRequest(Methods.GET)//这是预期用途

如何确保函数只接受定义的类型而不接受此类型的基础类型

我将伪枚举定义如下:

类型方法字符串
var方法=结构{
获取方法
POST方法
贴片法
}{
获取:“获取”,
帖子:“帖子”,
补丁:“补丁”,
}
并以以下方式使用它们(简化):

func getRequest(方法)(*http.Request,错误){
返回http.NewRequest(字符串(方法),“一些随机路径”,nil)
}
func main(){
_,\=getRequest(Methods.GET)//这是预期用途
_,\=getRequest(“GET”)//为什么允许这样做?
}

为什么编译器不抱怨在需要
方法
类型的地方使用
“GET”
字符串文字? 如何更改代码,以便在需要类型方法的情况下不能使用字符串文字?

“GET”
是一个非类型化常量。如果可以将非类型化常量转换为基础类型,则会将其转换为该类型。在示例中:

 _, _ = getRequest("GET")
这里,
“GET”
的类型是
方法
,而不是
字符串
。不允许出现以下情况:

s:="GET"
getRequest(s)
因为这里,
s
是一个
字符串
,而不是
方法

如果您需要类似枚举的绝对类型安全性,可以尝试以下方法:

type Method struct{v string}

var Methods = struct {
    GET   Method
    POST  Method
    PATCH Method
}{
    GET:   Method{v:"GET"},
    POST:  Method{v:"POST"},
    PATCH: Method{v:"PATCH"},
}

但是,这很难看,通常不值得付出努力。

“为什么编译器不抱怨在需要方法类型的地方使用“GET”字符串文字?”因为语言规范这么说:未类型化的常量被转换。“我如何更改代码,使字符串文字不能在需要类型方法的地方使用?”Buraks方法可以工作,但非常难看。你应该保持代码不变。这是很好的密码。谢谢你,沃尔克!这澄清了很多。在大多数情况下,我可能会按照你的建议继续使用这种方法。谢谢你,Burak!当我需要绝对类型安全性时,我将使用您的方法。完全可以理解,只有一个字段的结构是“强制”枚举的最简单形式。@IvanD请记住,对枚举使用字符串是很好的。在大多数实际情况下,这种类型安全的感知好处通常不会实现。事实上,正如Burak指出的那样,这种类型安全级别不太可能值得付出复杂性和可读性方面的代价。如果你认为你需要这个,我会非常非常仔细地看你在做什么,因为你可能真的不需要它。谢谢你,@Adrian!我同意,在这种情况下,这可能是一种过度使用,因为
http。如果NewRequest
接收到的不是有效的请求类型,如GET、POST等,它将返回一个错误。您将如何处理限制惯用Go中可用作参数的选项的任务?这是“惯用Go”示例的最佳资源是标准库。例如,stdlib就是这样做的: