преобразование интерфейса: интерфейс{} равен нулю, а не bool

# #go #go-gin

Вопрос:

Я относительно новичок в этом деле.

Я вношу изменения в существующий проект. Мне нужно получить значение элемента, которое может присутствовать в теле HTTP-запроса, и вставить его.

 var returnValues = body.Params["returnValues"].(bool)
delete(body.Params, "returnValues")
 

Я получаю ошибку в первой строке.

преобразование интерфейса: интерфейс {} равен нулю, а не bool

Тело образца:

 {
"Params": {
    "returnValues": true
    }
}
 

Комментарии:

1. Есть ли в вашем коде какая-либо структура json или что-то для декодирования? Куда вы отправили свое тело запроса, чтобы отправить объект?

2. Это означает body.Params , что у карты нет returnValues ключа или он у нее есть, но он равен нулю. Как вы строите body.Params ?

3. «Мне нужно получить значение элемента, которое может присутствовать в теле HTTP-запроса, и вставить его». — Ну, вы получаете ошибку, потому что ее нет . Вы никогда не должны этого делать var v = x.(bool) , если не уверены, что x это содержит bool значение. Если есть случаи, когда это может быть не bool так, то ваша программа выйдет из строя, когда столкнется с этими случаями. Если вы хотите избежать сбоя, используйте идиому «запятая ок», например var v, ok = x.(bool) .

Ответ №1:

Всегда, если вы получаете доступ к карте интерфейсов или нулевых типов по умолчанию и выполняете действия с использованием этой карты, убедитесь, что значение ключа существует на карте, прежде чем использовать его. Если это значение не существует на карте, оно вернет ноль и запаникует с нулевой ссылкой.

 r, ok := body.Params["returnValues"]
    if !ok {
        // returnValues not present in Params map. Handle the scenario
        // and don't continue below 
    }
    var returnValues = r.(bool)
    delete(body.Params, "returnValues")
 

А также, если вы не уверены в типе переменной, к которой вы обращаетесь, используйте утверждение типа и посмотрите, подходит ли ваш тип или нет. Затем, если значение равно null, оно также возвращает значение false для утверждения типа.

 returnValues, ok := body.Params["returnValues"].(bool)
    if !ok {
        // returnValues may not present in Params map. or it is not an 
        // boolean type, handle scenario here
    }
    delete(body.Params, "returnValues")
 

Комментарии:

1. Это все еще может потерпеть ужасную неудачу. Вместо того, чтобы использовать идиому «запятая ок» на карте, в этом случае вы должны использовать ее в утверждении типа.

2. Да, это тоже лучший вариант. Я также добавлю это.