Это 15-й день моего участия в Gengwen Challenge.Подробности о мероприятии, пожалуйста, проверьте:Обновить вызов
Инкапсуляция кода — бесконечная задача, но иногда инкапсуляция может вызывать проблемы. Этот документ документирует людей в инкапсуляцииhttp
А иnil
Судить по соответствующим вопросам.
что такое ноль
nil
Встроенная переменная, используемая для представления нулевого значения и только указателя,channel
, методы, интерфейсы,map
и срезы могут быть назначены какnil
.
buildin/buildin.go
:
// nil is a predeclared identifier representing the zero value for a
// pointer, channel, func, interface, map, or slice type.
var nil Type // Type must be a pointer, channel, func, interface, map, or slice type
// Type is here for the purposes of documentation only. It is a stand-in
// for any Go type, but represents the same type for any given function
// invocation.
type Type int
код проблемы
Код ниже - это то, что у меня естьhttp.Post
инкапсуляция метода
func (r *Request) Post(endpoint string, params *url.Values, body io.Reader, headers map[string]string, cookies map[string]string) (resp *http.Response, err error) {
url := fmt.Sprintf("%s%s", r.BaseURL, endpoint)
var req *http.Request
req, err = http.NewRequest(http.MethodPost, url, body)
if err != nil {
return
}
r.setRequest(req, params, headers, cookies)
resp, err = r.Client.Do(req)
return
}
Затем при использовании следующим образом:
var body *bytes.Reader
body = nil
resp, err = req.Post(endpoint, nil, body, nil, nil)
В это время будет ошибка нулевого указателя, и, наконец, после долгого расследования обнаружено, чтоhttp.NewRequest
Ошибка нулевого указателя возникает в:
Анализ ошибок
Базовая реализация указателей и интерфейсов состоит из двух частей: данных и типа. Когда указатели и интерфейсы явно назначаютсяnil
, и данные, и типnil
, но когда указателю или интерфейсу присваивается значение, тип которого не nil, а данные имеют значение nil, результат сравнения с nil будет ложным.
Изменить код
использоватьreflect.ValueOf(body).IsNil()
судитьbody
Пусто:
func (r *Request) Post(endpoint string, params *url.Values, body io.Reader, headers map[string]string, cookies map[string]string) (resp *http.Response, err error) {
url := fmt.Sprintf("%s%s", r.BaseURL, endpoint)
var req *http.Request
if reflect.ValueOf(body).IsNil() {
req, err = http.NewRequest(http.MethodPost, url, nil)
} else {
req, err = http.NewRequest(http.MethodPost, url, body)
}
if err != nil {
return
}
r.setRequest(req, params, headers, cookies)
resp, err = r.Client.Do(req)
return
}