接口指针作为函数参数

这很可能源于对 go 中的 interface{} 的误解。{} 我有以下代码


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 函数更抽象并接受任何结构。我认为最好的方法是接受 a *interface{},但是在更改 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)

}

interface{} 已经是一个指针了吗?此外,错误消息对我来说没有意义,配置不是指向接口的指针吗?此外,如果我更改json.Unmarshal(jsonStr, x)为json.Unmarshal(jsonStr, &x)它仍然可以正常工作。这里发生了什么可以让它发挥作用?


附带问题但与指针相关,为什么我不能像注释掉的行(在 main 下)声明一个指针?


慕森王
浏览 235回答 3
3回答

慕少森

使用 interface{} 表示任何类型,包括指针:func loadJson(jsonStr []byte, x interface{}) {   json.Unmarshal(jsonStr, x)}playground尽管您可以将 a 分配Configuration给 an interface{},但Configuration值和interface{}值的内存布局是不同的。由于内存布局不同,指向 an 的指针interface{}不能转换为指向 a 的指针Configuration。在同样的道理也适用于[]T和[]interface[}。在 Go 中用户很少使用指向接口的指针。关于旁注:您可以使用变量声明和赋值var config *Configurationconfig = new(Configuration)或者您可以使用简短的变量声明:config := new(Configuration)不能同时使用声明和短声明,因为它声明了变量两次。

qq_遁去的一_1

interface{} 已经是一个指针了吗?不,一般来说不是[1]。这里发生了什么可以让它发挥作用?考虑以下类型定义:type Number intint并且Number现在是两种完全不同的类型。您不能使用 a *intwhere a*Number是预期的;即使它们本质上是相同的,甚至在记忆方面也是如此。规则是相同的*Configuration和*interface{}; 即使它们的内存表示是相同的(事实并非如此)。为什么它在interface{}那时起作用?因为接口类型是特殊的;它们是 Go 实现多态的方式。如果实现了所述接口,则任何值都可以在接口值中“装箱”。[1] 在幕后,接口值有时包含一个指针,但这是一个实现细节,与此处无关。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go