sha*_*ner 3 pointers interface go
所以我基本上试图找到最好的方法来达到这样的目的:
package main
import "fmt"
type SomeStruct struct {
}
type SomeInterface interface {
SomeMethodWhichNeedsAPointerReceiver() string
}
func (s *SomeStruct) SomeMethodWhichNeedsAPointerReceiver() string {
return "Well, believe me, I wrote something"
}
func Run(s interface{}) {
// how can I cast s to a pointer here?
casted, ok := (s).(SomeInterface)
if ok {
fmt.Println("Awesome: " + casted.SomeMethodWhichNeedsAPointerReceiver())
return
}
fmt.Println("Fail :(")
}
func SomeThirdPartyMethod() interface{} {
return SomeStruct{}
}
func main() {
x := SomeThirdPartyMethod()
Run(x)
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,在Run方法的类型转换中.我基本上只知道它是interface {}类型,现在我需要调用一个接口方法,它有一个指针接收器.
我目前唯一的解决方案是动态构造一个带有反射的切片,将该元素设置为切片,然后使其成为可压缩的.
这真的是找到解决方案的唯一可能性吗?
在Go中,接口只是一组方法(规范:接口类型).
接口不指定接收器是否为指针.在Go中实现接口是隐含的:没有意图声明.
您需要阅读并理解方法集.引用它的一个重要部分:
任何其他类型的方法集
T包含用接收器类型声明的所有方法T.设置相应的方法指针类型*T是一组与接收器声明的所有方法*T或T(即,它也包含的方法集T).
甲值如果其类型的方法集是接口的超集(接口类型的方法)(其可以是或可以不是一个指针)实现的接口.
在你的例子中:
func (s *SomeStruct) SomeMethodWhichNeedsAPointerReceiver() string{}
Run Code Online (Sandbox Code Playgroud)
SomeMethodWhichNeedsAPointerReceiver()有一个指针接收器,所以type的值SomeStruct不会有这个方法,但是type的值*SomeStruct会.
因此,作为一个后果类型的值SomeStruct 不会实现你的SomeInterface接口(因为它没有一个SomeMethodWhichNeedsAPointerReceiver()方法),但*SomeStruct 确实实现你的SomeInterface,因为它的方法集包含SomeMethodWhichNeedsAPointerReceiver()方法.
由于您创建并使用简单SomeStruct值(而不是指向它的指针),因此类型断言将失败.
如果您使用过a *SomeStruct,那么类型断言就会成功.
修改你的SomeThirdPartyMethod()函数来创建并返回一个*SomeStruct(一个指针),它将按你的预期工作:
func SomeThirdPartyMethod() interface{} {
return &SomeStruct{}
}
Run Code Online (Sandbox Code Playgroud)
或作为替代方案:
func SomeThirdPartyMethod() interface{} {
return new(SomeStruct)
}
Run Code Online (Sandbox Code Playgroud)
在Go Playground尝试一下.
SomeThirdPartyMethod()如果你不能修改这个SomeThirdPartyMethod()函数:首先,它是否意图/要求它返回一个实现的值SomeStruct?如果是这样,那么它的当前实现是错误的,你可以期望它返回一个实现的值,SomeStruct而不必取消引用它(为了获得实现的值SomeStruct).
在这种特定情况下,您还可以尝试为SomeStruct自己键入断言:
if ss, ok := s.(SomeStruct); ok {
fmt.Println(ss.SomeMethodWhichNeedsAPointerReceiver())
}
Run Code Online (Sandbox Code Playgroud)
调用ss.SomeMethodWhichNeedsAPointerReceiver()将自动取消引用ss以获取其地址(这将是用于调用SomeMethodWhichNeedsAPointerReceiver()方法的指针接收器值).
| 归档时间: |
|
| 查看次数: |
792 次 |
| 最近记录: |