Por favor, explique &, y * punteros en GoLang

Recientemente comencé a aprender GoLang. Ha habido varias instancias en las que el compilador arroja un error cuando intento pasar variables como argumentos dentro de las funciones Go. A veces he podido depurar esto usando un puntero delante de la variable. Ambos &, y * punteros parecen borrar el error. Sin embargo, me gustaría entender por qué. Me pregunto cuál es la diferencia entre &, y *, y cuándo se debe usar cada uno. ¡Gracias!

func (ctx *NewContext) SendNotification(rw http.ResponseWriter, req *http.Request, p httprouter.Params) {

    decoder := json.NewDecoder(req.Body)

    var u User

    if err := decoder.Decode(&u); err != nil {
        http.Error(rw, "could not decode request", http.StatusBadRequest)
        return
    }
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta