【发布时间】:2016-05-28 12:06:06
【问题描述】:
我现在在使用 Golang 时遇到了一个轻微的架构问题,这导致我复制/粘贴的代码比我希望的要多。我觉得必须有一个解决方案,所以请让我知道这是否可能:
当我通过interface {}-typed 函数参数传递东西时,我开始收到诸如“预期的结构或切片”等错误......即使我之前传递的是结构或切片。我意识到我可以在该函数中收到它们后手动将它们转换为另一种类型,但是在这样的实例中变得乏味:
本地接口类型 *interface {} 只能从远程解码 接口类型;收到具体类型
...在这种情况下,接收函数似乎需要硬编码才能将所有interface {} 项目转换回它们各自的原始类型才能正常工作,因为接收函数需要知道准确的类型,以便正确处理项目。
有没有办法将 Golang interface {} 类型化的变量动态重新输入到它们的原始类型? 像这样,How to I convert reflect.New's return value back to the original type ... 可能吗?
编辑:为了澄清,基本上,我将&out 传递给一个函数,并且在它到达另一个内部函数调用时它必须是它的原始类型。
示例代码:
// NOTE: This is sort of pseudo-Golang code, not meant to be compiled or taken too seriously.
func PrepareTwoDifferentThings(keyA string, keyB string) {
var somethingA TypeA;
var somethingB TypeB;
loadFromCache(keyA, &somethingA, nil);
loadFromCache(keyB, &somethingB, nil);
fmt.Printf("Somethings: %v, %v", somethingA, somethingB);
}
func loadFromCache(key string, isNew, out interface {}, saveNewData interface {}) {
if err := cache.load(key, &out); err!=nil { // NOTE: Current issue is that this expects "&out" to be `TypeA`/`TypeB` not "interface {}", but I don't want to copy and paste this whole function's worth of code or whatever.
panic("oh no!");
}
if (saveNewData!=nil) {
cache.save(key, saveNewData); // This doesn't seem to care if "saveNewData" is "interface {}" when saving, but later cache fetches above using the "load()" method to an "interface {}"-typed `&out` parameter throw an exception that the "interface {}" type on `&out` does not match the original when it was saved here (`TypeA`/`TypeB`).
}
}
【问题讨论】:
-
你无法在不知道它是什么的情况下转换为原始类型。 Reflect 可以让你动态处理各种类型,但是没有断言就无法获得“真实”的类型。
-
我刚刚发布了一些澄清作为编辑。
-
我目前的解决方法是将闭包传递给函数而不是
interface {}类型属性,并且函数在必要时调用该函数而不会丢失原始变量的类型,因为它在先前的范围内并且从不改变类型。但是,这需要我将代码复制并粘贴到调用此方法的各种实例中,我认为这是不必要的……似乎是保留我找到的类型的唯一方法。 -
然后你需要将它断言回正确的类型。如果您知道需要在编译时调用的函数的签名,那么您就知道需要断言的类型。如果没有,你必须使用反射来完成整个事情。
-
发布代码的相关部分可能会有所帮助。
标签: go