接口指针作为函数参数

This most likely stems from a misunderstanding of what interface{} is in go. I have the following code

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
", config.Username)
}

It loads a json configuration into the config variable. I want to make the loadJson function more abstract and accept any struct. I thought the best way to do that would be to accept a *interface{}, however I get the following error when changing the loadJson Signature.

 ./issue.go:30: cannot use config (type *Configuration) as type *interface {} in argument to loadJson:
*interface {} is pointer to interface, not interface

Instead load json should be this

func loadJson(jsonStr []byte, x interface{}}) {
    json.Unmarshal(jsonStr, x)
}

Is interface{} already a pointer? Also the error message doesn't make the most sense to me, isn't configuration a pointer to an interface? Also, if I change json.Unmarshal(jsonStr, x) to json.Unmarshal(jsonStr, &x) it will work perfectly fine still. What is going on here that allows that to work?

Side question but relevant to pointers, why can't I declare a pointer like the commented out line(under main)?

Use interface{} to represent any type including pointers:

func loadJson(jsonStr []byte, x interface{}) {
   json.Unmarshal(jsonStr, x)
}

playground

Although you can assign a Configuration to an interface{}, the memory layout of a Configuration value and an interface{} value are different. Because the memory layouts are different, a pointer to an interface{} cannot be converted to a pointer to a Configuration. The same reasoning applies to a []T and a []interface[}.

It's rare to user a pointer to an interface in Go.

Regarding the side note: You can use a variable declaration and assignment

var config *Configuration
config = new(Configuration)

or you can use a short variable declaration:

config := new(Configuration)

You cannot use declaration and short declaration together because it declares the variable twice.

A pointer to an interface has a different memory layout than a pointer to a Configuration. They are not interchangeable and you can't use *interface{} to represent any pointer. Think of an interface value like a box. The idea is you want to pass the json function a box containing a pointer and not a pointer to a box.

If you want to understand the underlying representation of an interface, see http://research.swtch.com/interfaces.

Is interface{} already a pointer?

No, not in general [1].

What is going on here that allows that to work?

Consider the following type definition:

type Number int

int and Number are now two completely distinct types. You can't use a *int where a *Number is expected; even if they are essentially the same, even memory-wise.

The rule is the same for *Configuration and *interface{}; even if their memory representation was identical (which it isn't).

Why does it work for interface{} then? Because interface-types are special; they are Go's way of doing polymorphism. Any value can be "boxed" in an interface value if it implements said interface.

[1] Under the hood, an interface value sometimes holds a pointer but that's an implementation detail and not relevant here.