Pointers 作为函数参数的接口指针
这很可能源于对go中的接口{}的误解。我有以下代码Pointers 作为函数参数的接口指针,pointers,go,Pointers,Go,这很可能源于对go中的接口{}的误解。我有以下代码 type Configuration struct { Username string } func loadJson(jsonStr []byte, x *Configuration}) { json.Unmarshal(jsonStr, x) } func main() { //var config *Configuration config := new(Configuration) file,
type Configuration struct {
Username string
}
func loadJson(jsonStr []byte, x *Configuration}) {
json.Unmarshal(jsonStr, x)
}
func main() {
//var config *Configuration
config := new(Configuration)
file, e := ioutil.ReadFile("config.json")
loadJson(file, config)
fmt.Printf("%s\n", config.Username)
}
它将json配置加载到config变量中。我想让loadJson函数更抽象,并接受任何结构。我认为最好的方法是接受一个*接口{}
,但是在更改loadJson签名时会出现以下错误
./issue.go:30: cannot use config (type *Configuration) as type *interface {} in argument to loadJson:
*interface {} is pointer to interface, not interface
相反,加载json应该是这样的
func loadJson(jsonStr []byte, x interface{}}) {
json.Unmarshal(jsonStr, x)
}
接口{}已经是指针了吗?此外,错误消息对我来说也没有什么意义,配置不是指向接口的指针吗?另外,如果我将json.Unmarshal(jsonStr,x)
更改为json.Unmarshal(jsonStr,x)
,它仍然可以正常工作。这里发生了什么事情让它起作用
附带问题但与指针相关,为什么我不能声明一个指针,比如注释掉的行(在main下) 指向接口的指针与指向配置的指针具有不同的内存布局。它们是不可互换的,并且不能使用*接口{}来表示任何指针。将接口值想象成一个方框。其思想是希望向json函数传递一个包含指针的框,而不是指向框的指针
如果要了解接口的底层表示,请参阅。使用接口{}表示任何类型,包括指针:
func loadJson(jsonStr []byte, x interface{}) {
json.Unmarshal(jsonStr, x)
}
尽管可以将配置
分配给接口{}
,但配置
值和接口{}
值的内存布局是不同的。由于内存布局不同,无法将指向接口{}
的指针转换为指向配置的指针。这个
关于旁注:您可以使用变量声明和赋值
var config *Configuration
config = new(Configuration)
或者您可以使用:
不能同时使用声明和短声明,因为它声明变量两次
接口{}已经是指针了吗
不,不是一般意义上的[1]
这里发生了什么事情让它起作用
考虑以下类型定义:
type Number int
int
和Number
现在是两种完全不同的类型。您使用*int
,其中需要一个*Number
;即使它们本质上是相同的,甚至是记忆方面的
规则与*配置
和*接口{}
相同;即使它们的内存表示是相同的(事实并非如此)
那么为什么它适用于接口{}
?因为接口类型是特殊的;他们是Go的方法。如果接口实现了上述接口,则任何值都可以“装箱”到接口值中
[1] 在后台,接口值有时包含指针,但这是一个实现细节,在这里不相关。尝试json.Unmarshal(jsonStr,*x)
。
type Number int