Как создать нечувствительную к регистру карту в Go?

Я хочу иметь ключевую нечувствительную строку в качестве ключа. Поддерживается ли это языком или я должен сам его создать? спасибо

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

Ответ 1

Изменить: мой первоначальный код на самом деле все еще допускал синтаксис карты и, таким образом, позволял обойти методы. Эта версия более безопасна.

Вы можете "получить" тип. В Go мы просто говорим, заявляем. Затем вы определяете методы своего типа. Для обеспечения требуемой функциональности требуется очень тонкая оболочка. Обратите внимание, однако, что вы должны вызвать get и установить с помощью обычного синтаксиса вызова метода. Невозможно сохранить синтаксис индекса или дополнительный результат ok, который был создан на картах.

package main

import (
    "fmt"
    "strings"
)

type ciMap struct {
    m map[string]bool
}

func newCiMap() ciMap {
    return ciMap{m: make(map[string]bool)}
}

func (m ciMap) set(s string, b bool) {
    m.m[strings.ToLower(s)] = b
}

func (m ciMap) get(s string) (b, ok bool) {
    b, ok = m.m[strings.ToLower(s)]
    return
}

func main() {
    m := newCiMap()
    m.set("key1", true)
    m.set("kEy1", false)
    k := "keY1"
    b, _ := m.get(k)
    fmt.Println(k, "value is", b)
}

Ответ 2

Две возможности:

  • Преобразование в верхний регистр/строчный регистр, если вы вводите набор, гарантированно будет ограничиваться только символами, для которых преобразование в верхний или нижний регистр даст правильные результаты (может быть неверно для некоторых символов Юникода)

  • Преобразовать в случай сложения в Unicode иначе:

Используйте unicode.SimpleFold(rune) для конвертирования руны юникода в случай сброса. Очевидно, что это значительно более дорогостоящая операция, чем простое сопоставление событий в стиле ASCII, но она также более переносима для других языков. Смотрите исходный код для EqualsFold, чтобы узнать, как это используется, включая извлечение рун Unicode из исходной строки.

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