如何确定传递给我的Func的var实际上是否是我想要的Type?
我有自定义类型
type Name string
和一堆那种类型的常量
const Fred Name = "fred"
我有一个func,我需要禁止除我的自定义类型ex以外的任何其他类型的输入:
func MyFunc(name1 Name, name2 Name) (*Person, error) {
//bunch of stuff
}
我如何在我的func中检查name1和name2是不是传递给func的字符串,而是仅在我的类型ex中定义的const:
p, err := MyFunc(Fred,Albert) //What i want
p, err := MyFunc("fred","albert") //What i dont want to happen
如果无法回答我的问题,我怎么能像Golang中的Enum那样做一个意味着什么的类型并限制其他人使用我定义的类型
答案 0 :(得分:4)
让你的类型实现一个未导出的界面
type Name string
type Private interface{
private()
}
func (n Name) private() {}
func MyFunc(name1, name2 Private) (*Person, error) {
//bunch of stuff
}
答案 1 :(得分:1)
短版?你不能创造那种限制性的枚举。
长版本,选项很少:
在"类型":
上定义验证功能func (n Name) valid() bool { //private method
switch n {
case Mal, Kaylee: //all the valid constants
return true
}
return false
}
然而,这并不能阻止某人像@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
}