Как функция go map ha sh работает так, что другой тип с "одинаковым" значением приводит к другому ключу? - PullRequest
4 голосов
/ 21 февраля 2020

Я знаю, что значение не одно и то же , поэтому я поставил его в двойные кавычки, я хочу знать, как карта go ha sh работает так, что cusKey и a отличается по типу, результат в ключе отличается.

package main

import (
    "fmt"
)

type key int

const cusKey key = 1
const a int = 1


func main() {
    dic := make(map[interface{}]interface{})
    dic[cusKey] = 5
    dic[a] = 6
    fmt.Println(dic[cusKey])
    fmt.Println(dic[a])
}

вывод

5
6

Как go достичь этого? Все два ключа имеют значение 1.

Я знаю в go, если тип отличается, два значения отличаются. Таким образом, два 1 не идентичны.

Но как на самом деле карта go сделала это? Я попытался выяснить в map.go в источнике, но не могу найти, где go реализует функцию ha sh. Он вычисляет га sh ключей с аннотациями типов?

Ответы [ 2 ]

11 голосов
/ 21 февраля 2020

a и cusKey не могут быть равны, потому что они имеют разные типы. a имеет тип int, а cusKey имеет тип key (базовый тип которого int, но это другой тип).

Go карты требуют ключи должны быть сопоставимы. Spe c: Типы карт:

Операторы сравнения == и != должны быть полностью определены для операндов типа ключа

Тип ключа вашей карты dic - interface{}, это тип интерфейса, и значения интерфейса сравнимы, если Spe c: Операторы сравнения:

  • Значения интерфейса сопоставимы. Два значения интерфейса равны, если они имеют одинаковые значения Dynami c и равные значения Dynami c или оба имеют значение nil.

Значение интерфейса хранит Dynami c тип и значение, схематически это пара "(значение, тип)". Когда сравниваются значения интерфейса, сравнивается и тип, и если они не совпадают, сравнение значений интерфейса даст false. Для получения подробной информации о представлении интерфейса см. Go Структуры данных: Интерфейсы (от Russ Cox) .

Для внутренних данных о карте Go посмотрите Dave Cheney: Как Go среда выполнения эффективно реализует карты (без обобщений) .

7 голосов
/ 21 февраля 2020

Клавиши имеют тип interface{}. Значения интерфейса в Go имеют два поля: дескриптор типа базового значения и указатель на само значение. Поэтому два значения интерфейса с разными базовыми типами не равны, даже если базовые значения будут считаться равными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...