Существуют ли библиотеки go, которые предоставляют возможности ассоциативного массива?

Я ищу способ языка, похожий на "словарь" в python, чтобы облегчить преобразование некоторого кода на Python.

EDIT: Карты работали достаточно хорошо для этого де-dupe приложения. Я смог сконденсировать 1.3e6 дублированные элементы до 2.5e5 уникальных элементов, используя карту с индексом строки из 16 байтов всего за несколько секунд. Код, связанный с картой, был простым, поэтому я включил его ниже. Стоит отметить, что предварительное выделение карты с элементами 1.3e6 ускорило ее всего на несколько процентов:

var m = make(map[string]int, 1300000) // map with initial space for 1.3e6 elements

ct, ok := m[ax_hash]
if ok {
    m[ax_hash] = ct + 1
} else {
    m[ax_hash] = 1
}

Ответы

Ответ 1

Тип карты. http://golang.org/doc/effective_go.html#maps

Существует некоторая разница с python в том, что ключи должны быть набраны, , поэтому вы не можете смешивать числовые и строковые ключи (по какой-то причине я забыл, что вы можете), но они довольно прост в использовании.

dict := make(map[string]string)
dict["user"] = "so_user"
dict["pass"] = "l33t_pass1"

Ответ 2

Чтобы немного рассказать о полученных ответах:

A Go map - типизированная структура данных хэш-карты. Подпись типа карты имеет вид map[keyType]valueType, где keyType и valueType - типы ключей и значений соответственно.

Чтобы инициализировать карту, вы должны использовать функцию make:

m := make(map[string]int)

Неинициализированное отображение равно nil, и если во время выполнения будет прочитана или записана паника.

Синтаксис для хранения значений почти такой же, как при использовании массивов или фрагментов:

m["Alice"] = 21
m["Bob"] = 17

Аналогично, извлечение значений из карты выполняется следующим образом:

a := m["Alice"]
b := m["Bob"]

Вы можете использовать ключевое слово range для перебора по карте с циклом for:

for k, v := range m {
    fmt.Println(k, v)
}

Этот код напечатает:

Alice 21
Bob 17

Извлечение значения для ключа, который не находится на карте, вернет значение типа нулевого значения:

c := m["Charlie"]
// c == 0

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

a, ok := m["Alice"]
// a == 21, ok == true
c, ok := m["Charlie"]
// c == 0, ok == false

Чтобы удалить запись ключа/значения с карты, вы переверните ее и назначьте false в качестве второго значения:

m["Bob"] = 0, false
b, ok := m["Bob"]
// b == 0, ok == false

Вы можете хранить произвольные типы на карте, используя пустой тип интерфейса interface{}:

n := make(map[string]interface{})
n["One"] = 1
n["Two"] = "Two"

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

a := n["One"].(int)
b := n["Two"].(string)

Вы можете использовать переключатель типа для определения типов значений, которые вы вытаскиваете, и обрабатывать их соответственно:

for k, v := range n {
    switch u := v.(type) {
        case int:
            fmt.Printf("Key %q is an int with the value %v.\n", k, u)
        case string:
            fmt.Printf("Key %q is a string with the value %q.\n", k, u)
    }
}

Внутри каждого из этих блоков case u будет иметь тип, указанный в инструкции case; нет явного утверждения типа.

Этот код напечатает:

Key "One" is an int with the value 1.
Key "Two" is a string with the value "Two".

Ключ может быть любого типа, для которого определен оператор равенства, например целые числа, поплавки, строки и указатели. Также можно использовать типы интерфейсов, если базовый тип поддерживает равенство. (Структуры, массивы и срезы не могут использоваться в качестве ключей карты, потому что для этих типов не определено равенство.)

Например, карта o может принимать ключи любого из следующих типов:

o := make(map[interface{}]int)
o[1] = 1
o["Two"] = 2

И это отображает в двух словах.

Ответ 3

Возможно, вы ищете map.