如何惯用地检查接口是 Go 中的两种类型之一
How to idiomatically check that an interface is one of two types in Go
假设我有一个函数接受一个非常广泛的接口,它可以包装(?)或描述许多不同的类型,例如 int64
、float64
、string
,如以及其他接口。但是,此特定函数只想与浮点数和整数交互,并且 return 任何其他基础具体类型都会出错。
在 Go 中执行此操作的惯用方法是什么?
在 int
或 float64
和 return 默认情况下出错的情况下,我是否应该使用 switch 语句而不执行任何操作?这对我来说似乎很奇怪,因为那些箱子都是空的。
例如
type BoardInterface interface{
doThing()
}
type customInt int
type customFloat float64
func (i customInt) doThing() {}
func (f customFloat) doThing() {}
// Other methods for different types here...
func getThing(i BoardInterface) error {
// i could be string, int, float, customInterface1, customInterface2...
// but we want to assert that it is int or float.
switch t := i.(type) {
case customInt:
// Do nothing here?
case customFloat:
// Do nothing here?
default:
return fmt.Errorf("Got %v want float or int", t)
}
// Do something with i here now that we know
// it is a float or int.
i.doThing()
return nil
}
理想情况下,您的 BoardInterface
应该包含您想要使用 i
的所有行为,这样您就可以通过 [=] 中列出的方法与 i
进行“交互” 11=]。这样,i
中包含的具体类型应该无关紧要。如果编译器允许传递一个值,你保证它实现 BoardInterface
.
如果由于某种原因不可行(或不可能),您提出的解决方案很好。您可以通过在简单的 case
中列出所有允许的类型来简化它,并且无需声明 t
,您可以像这样使用 i
:
switch i.(type) {
case customInt, customFloat:
default:
return fmt.Errorf("Got %T want customInt or customFloat", i)
}
(注意我在错误消息中使用了 %T
,因为在这种情况下它提供的信息更多。)
假设我有一个函数接受一个非常广泛的接口,它可以包装(?)或描述许多不同的类型,例如 int64
、float64
、string
,如以及其他接口。但是,此特定函数只想与浮点数和整数交互,并且 return 任何其他基础具体类型都会出错。
在 Go 中执行此操作的惯用方法是什么?
在 int
或 float64
和 return 默认情况下出错的情况下,我是否应该使用 switch 语句而不执行任何操作?这对我来说似乎很奇怪,因为那些箱子都是空的。
例如
type BoardInterface interface{
doThing()
}
type customInt int
type customFloat float64
func (i customInt) doThing() {}
func (f customFloat) doThing() {}
// Other methods for different types here...
func getThing(i BoardInterface) error {
// i could be string, int, float, customInterface1, customInterface2...
// but we want to assert that it is int or float.
switch t := i.(type) {
case customInt:
// Do nothing here?
case customFloat:
// Do nothing here?
default:
return fmt.Errorf("Got %v want float or int", t)
}
// Do something with i here now that we know
// it is a float or int.
i.doThing()
return nil
}
理想情况下,您的 BoardInterface
应该包含您想要使用 i
的所有行为,这样您就可以通过 [=] 中列出的方法与 i
进行“交互” 11=]。这样,i
中包含的具体类型应该无关紧要。如果编译器允许传递一个值,你保证它实现 BoardInterface
.
如果由于某种原因不可行(或不可能),您提出的解决方案很好。您可以通过在简单的 case
中列出所有允许的类型来简化它,并且无需声明 t
,您可以像这样使用 i
:
switch i.(type) {
case customInt, customFloat:
default:
return fmt.Errorf("Got %T want customInt or customFloat", i)
}
(注意我在错误消息中使用了 %T
,因为在这种情况下它提供的信息更多。)