为了账号安全,请及时绑定邮箱和手机立即绑定

接口指针作为函数参数

接口指针作为函数参数

Go
慕森王 2021-08-23 16:24:50
这很可能源于对 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 下)声明一个指针?
查看完整描述

3 回答

?
慕少森

TA贡献2019条经验 获得超9个赞

使用 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 *Configuration

config = new(Configuration)

或者您可以使用简短的变量声明:


config := new(Configuration)

不能同时使用声明和短声明,因为它声明了变量两次。


查看完整回答
反对 回复 2021-08-23
?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

interface{} 已经是一个指针了吗?

不,一般来说不是[1]

这里发生了什么可以让它发挥作用?

考虑以下类型定义:

type Number int

int并且Number现在是两种完全不同的类型。您不能使用 a *intwhere a*Number是预期的;即使它们本质上是相同的,甚至在记忆方面也是如此。

规则是相同的*Configuration*interface{}; 即使它们的内存表示是相同的(事实并非如此)。

为什么它在interface{}那时起作用?因为接口类型是特殊的;它们是 Go 实现多态的方式。如果实现了所述接口,则任何值都可以在接口值中“装箱”。

[1] 在幕后,接口值有时包含一个指针,但这是一个实现细节,与此处无关。


查看完整回答
反对 回复 2021-08-23
  • 3 回答
  • 0 关注
  • 231 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信