如果参数的类型是interface {},那么如何知道是通过指针传递还是通过值传递?

Given any function that takes a parameter of type interface{} how would I know whether or not to pass that parameter with or without & without navigating the source code of the function.

For example if I had a function with this type signature given to me:

func foo(x interface{}, y int) int

Would there be any way to figure out if x was supposed to be passed by value or by pointer?

Here is the snippet from the source:

// DecodeElement works like Unmarshal except that it takes
// a pointer to the start XML element to decode into v.
// It is useful when a client reads some raw XML tokens itself
// but also wants to defer to Unmarshal for some elements.

func (d *Decoder) DecodeElement(v interface{}, start *StartElement) error {
    val := reflect.ValueOf(v)
    if val.Kind() != reflect.Ptr {
        return errors.New("non-pointer passed to Unmarshal")
    }
    return d.unmarshal(val.Elem(), start)
}

It is checking val.Kind() != reflect.Ptr Which means you have to pass the pointer i.e &v.

Its entirely depend on the person who wrote the method or function, so interface{} could be either *ptr or anything but u ve to check that inside your function using reflect.ValueOf(v).Kind() whether the value is a pointer or not and proceeds accordingly.

And little bit about empty interface:

The interface type that specifies zero methods is known as the empty interface:

interface{}

An empty interface may hold values of any type. (Every type implements at least zero methods.)

Empty interfaces are used by code that handles values of unknown type. For example, fmt.Print takes any number of arguments of type interface{}.

Another useful discussion: docs

DecodeElement() and friends have a formal v interface{} whose type is documented in the Unmarshal() function documentation:

Unmarshal parses the XML-encoded data and stores the result in the value pointed to by v, which must be an arbitrary struct, slice, or string.

So to literally answer your question, no, you cannot know without reading the source - if the value you want to pass is a struct proper, you need to indirect. If it is already a pointer to that struct, you do not.

For example:

type Result struct {
    XMLName xml.Name `xml:"Person"`
    Name    string   `xml:"FullName"`
    Phone   string
    Email   []Email
    Groups  []string `xml:"Group>Value"`
    Address
}

var (
    a Result
    b *Result
    c string
)

xmlDecoder.DecodeElement(&a, startElement)
xmlDecoder.DecodeElement(&c, startElement)

but

xmlDecoder.DecodeElement(b, startElement)