Types 确定var是否为自定义类型
如何确定传递给Func的var是否是我想要的类型 我有一个自定义类型Types 确定var是否为自定义类型,types,go,assertions,Types,Go,Assertions,如何确定传递给Func的var是否是我想要的类型 我有一个自定义类型 type Name string 还有一堆这样的常数 const Fred Name = "fred" 我有一个函数,我需要禁止除自定义类型ex之外的任何其他类型的输入: func MyFunc(name1 Name, name2 Name) (*Person, error) { //bunch of stuff } 如何在func中检查name1和name2不是传递给func的字符串,而是我在type ex中已经定义的
type Name string
还有一堆这样的常数
const Fred Name = "fred"
我有一个函数,我需要禁止除自定义类型ex之外的任何其他类型的输入:
func MyFunc(name1 Name, name2 Name) (*Person, error) {
//bunch of stuff
}
如何在func中检查name1和name2不是传递给func的字符串,而是我在type ex中已经定义的常量:
p, err := MyFunc(Fred,Albert) //What i want
p, err := MyFunc("fred","albert") //What i dont want to happen
如果我不能回答我的问题,我如何才能像Golang中的Enum一样使一个类型具有某种意义,并限制其他ppl使用我定义的类型?您不能创建这种类型的枚举 长版本,有几个选项: 在“类型”上定义验证函数: 然而,这并不能阻止某人使用@peterSO指出的
Name(“fred”).valid()
使用包含私有成员的结构,但它们本身不是“常量”,外部包可以将它们重新分配给无效值:
type Name struct {
n string
}
var (
invalid = Name{}
Mal = Name{"mal"}
Kaylee = Name{"kaylee"}
)
func MyFunc(name1 Name, name2 Name) error {
if name1 == invalid || name2 == invalid {
return errors.New("invalid names")
}
return nil
}
使用数值常量和专用数组,这是唯一一个真正的傻瓜版本,也是最接近真实枚举的版本:
type Name uint8
var names = [...]string{
"Mal",
"Kaylee",
}
func (n Name) valid() bool {
return uint8(n) < uint8(len(names))
}
func (n Name) String() string {
if !n.valid() {
return "invalid"
}
return names[n]
}
const (
Mal Name = iota
Kaylee
)
func MyFunc(name1 Name, name2 Name) error {
if !name1.valid() || !name2.valid() {
return errors.New("invalid names")
}
return nil
}
类型名称uint8
变量名称=[…]字符串{
“马尔”,
“凯莉”,
}
func(n名称)valid()bool{
返回uint8(n)
让您的类型实现一个未导出的接口
type Name string
type Private interface{
private()
}
func (n Name) private() {}
func MyFunc(name1, name2 Private) (*Person, error) {
//bunch of stuff
}
尽管增加了断言接口的运行时开销,但这是一个非常复杂的想法+1尽管如此。@one为了方便起见,我想您也可以使用private()返回名称接口private{private()Name}
。我不是100%确定,但我认为仅仅传递接口本身需要运行时开销,但我可能错了。很抱歉,最后这不是万无一失的,我需要常量来减少堆,但没有通过golint@Eefret我最终编辑了我的答案来导出界面,这应该解决golint警告最后这是正确的做法,我需要的所有值都必须是常量,所以我应用了你最后的建议,其他答案没有通过goLint,也没有作为你最后的建议,谢谢
type Name string
type Private interface{
private()
}
func (n Name) private() {}
func MyFunc(name1, name2 Private) (*Person, error) {
//bunch of stuff
}