Какое значение принимает возвращаемое значение, если чего-то нет на карте? - PullRequest
0 голосов
/ 27 октября 2018

Хорошо, в соответствии с этим:

Как проверить, содержит ли карта ключ в ходу?

if val, ok := m["foo"]; ok {
    //do something here
}

это нормально, но почему мы можемне делать это:

val, ok := m["foo"]

if val == nil {   // cannot compare val to nil

}

Я получаю ошибку компиляции, говорящую, что я не могу сравнить val с nil, но тогда какое значение имеет val?С чем его можно сравнить, чтобы определить, существует он или нет?

тип m похож на:

type m map[string]struct{}

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

Спецификация языка программирования Go

Индексные выражения

Для карты типа M: если карта равна нулю или не содержит такой entry, a [x] является нулевым значением для типа элемента M.

Нулевое значение

Когда для переменной выделено хранилище, либо через объявление или вызов нового, или когда создается новое значение, либо через составной литерал или вызов make, и никакой явной инициализации при условии, что переменной или значению присваивается значение по умолчанию. Каждый элемент такой переменной или значению присваивается нулевое значение для ее типа: false для логических значений, 0 для числовых типов, "" для строк и nil для указатели, функции, интерфейсы, срезы, каналы и карты.


Спецификация языка программирования Go

Составные литералы

Составные литералы создают значения для структур, массивов, срезов и карты и создавать новое значение каждый раз, когда они оцениваются. Они состоят типа литерала, за которым следует список элементов в скобках. Каждому элементу может предшествовать соответствующий ключ. За Структурные литералы применяются следующие правила:

Литерал может опускать список элементов; такой буквальный оценивает нулевое значение для его типа.

Для вашего примера введите struct{}, опустите список элементов из составного литерала, struct{}{}, для нулевого значения.

Например,

package main

import "fmt"

func main() {
    m := map[string]struct{}{}
    val, ok := m["foo"]
    fmt.Printf("%T %v\n", val, val)
    if val == struct{}{} {
        fmt.Println("==", val, ok)
    }
}

Детская площадка: https://play.golang.org/p/44D_ZfFDA77

Выход:

struct {} {}
== {} false

Спецификация языка программирования Go

Объявления переменных

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

Если дан список выражений, переменные инициализируются с выражения, следующие правилам для назначений. В противном случае каждый переменная инициализируется нулевым значением.

Если тип присутствует, каждой переменной присваивается этот тип. Иначе, каждой переменной присваивается тип соответствующей инициализации значение в присвоении.

В вашем примере вы можете объявить переменную типа struct{} без начального значения, которая будет инициализирована нулевым значением для типа struct{}.

Например,

package main

import "fmt"

func main() {
    m := map[string]struct{}{}
    val, ok := m["foo"]
    fmt.Printf("%T %v\n", val, val)
    var zeroValue struct{}
    if val == zeroValue {
        fmt.Println("==", val, ok)
    }
}

Детская площадка: https://play.golang.org/p/_XcSCEeEKJV

Выход:

struct {} {}
== {} false
0 голосов
/ 27 октября 2018

Вы, безусловно, можете сделать то, что вы сделали выше. Сравнение с nil зависит от типа значения, которое вы имеете на карте. Если его interface{}, вы можете сравнить его с нулем:

m := map[string]interface{}{}

val, _ := m["foo"]

if val == nil {
    fmt.Println("no index")
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...