go - Go 接口在方法之间强制执行相同的参数类型(但可以是任何类型)
问题描述
我敢肯定,标题令人困惑,但很难描述我的意思。
我想创建一个有两种方法的 Go 接口;第一个返回一个值,第二个接受一个值。我想确保方法 1 返回与方法 2 接受的类型相同的类型,而不指定类型是什么(除了它是一个结构)。例如:
type MyInterface interface {
Method1() MyType
Method2(MyType) error
}
whereMyType
可以是任何类型(结构),只要它在方法 1 和方法 2 中都相同。
有没有办法在 Go 中做到这一点?
编辑:
根据@iLoveReflection 的回答,我尝试了以下方法:
package main
type MyInterface interface {
GetType() interface{}
UseType(input interface{})
}
type MyImplementation struct{}
type MyType struct {
}
func (i MyImplementation) GetType() MyType {
return MyType{}
}
func (i MyImplementation) UseType(input MyType) {
return
}
func test(input MyInterface) {
return
}
func assertArgAndResult() {
var v MyImplementation
v.UseType(v.GetType())
}
func main() {
test(MyImplementation{})
}
所以基本上,我指定了一个接口MyInterface
(MyImplementation
assertArgAndResult()
正在按预期工作,并确保MyImplementation
满足要求。但是,我在函数中得到一个编译错误main()
:
cannot use MyImplementation literal (type MyImplementation) as type MyInterface in argument to test:
MyImplementation does not implement MyInterface (wrong type for GetType method)
have GetType() MyType
want GetType() interface {}
解决方案
将以下函数添加到包中,以确保在编译时输入和输出类型匹配:
func assertArgAndResult() {
var v MyInterface
v.Method2(v.Method1())
}
只要不调用该函数,该函数就不会包含在可执行文件中。
没有编译时检查可以确保它MyType
是问题中指定的结构类型。
reflect 包可用于完全检查类型类型。
// checkItf returns true of the interface value pointed to by
// pi has Method1 with some return type T and Method2 with
// argument type T.
func checkItf(pi interface{}) bool {
t := reflect.TypeOf(pi)
if t.Kind() != reflect.Ptr {
return false // or handle as error
}
t = t.Elem()
if t.Kind() != reflect.Interface {
return false // or handle as error
}
m1, ok := t.MethodByName("Method1")
// Method1 should have no outputs and one input.
if !ok || m1.Type.NumIn() != 0 || m1.Type.NumOut() != 1 {
return false
}
// Method2 should have one input and one output.
m2, ok := t.MethodByName("Method2")
if !ok || m2.Type.NumIn() != 1 || m2.Type.NumOut() != 1 {
return false
}
e := reflect.TypeOf((*error)(nil)).Elem()
s := m1.Type.Out(0)
// The type must be a struct and
// the input type of Method2 must be the same as the output of Method1 and
// Method2 must return error.
return s.Kind() == reflect.Struct &&
m2.Type.In(0) == s &&
m2.Type.Out(0) == e
}
像这样称呼它:
func init() {
if !checkItf((*MyInterface)(nil)) {
panic("mismatched argument and return time son MyInterface")
}
}
推荐阅读
- java - 显示所有 Firebase 身份验证用户?
- highcharts - 为什么向下钻取 x 轴点与相应的条不匹配?
- javascript - 在 Autodesk Forge Viewer 中恢复到以前的材质
- java - 在 Hibernate 上连接任何类型映射的查询
- c - C中的大小写可变宏
- python - 如何将自定义训练的 PyTorch 模型集成到 OpenCV 的 dnn 模块中?
- javascript - javascript 和 jquery 无法正常工作我的 php 页面?
- python - 使用openpyxl将二维列表的元素插入到excel中
- elasticsearch - Elasticsearch:找出主分片的运行节点名称?
- python - 有没有办法在 MongoDB 中从 INT 创建 ObjectID?