2011-11-09 5 views
9

Próbuję utworzyć mapę w Go, która jest kluczowana przez duże liczby całkowite. Effective Go wyraźnie mówi, że:Skomplikowane typy danych jako klucze na mapach w Go

Struktury, tablice i plasterki nie mogą być używane jako klucze map, ponieważ równość nie jest zdefiniowana dla tych typów.

co ma sens. Mógłbym oczywiście przekonwertować duże liczby całkowite na łańcuchy i użyć łańcucha jako klucza, ale szukam tutaj bardziej ogólnego rozwiązania. Czy mogę zawinąć moją strukturę w coś (interfejs?), Który implementuje funkcję równości i używa jej zamiast tego?

przykład kodu, który oczywiście nie działa:

package main                           

import (                            
     "big"                           
     "fmt"                           
)                              

func main() {                           
     one1 := big.NewInt(1)                       
     one2 := big.NewInt(1)                       

     hmap := make(map[*big.Int] int)                     
     hmap[one1] = 2                         
     _, exists := hmap[one2]                       
     fmt.Printf("Exists=%v\n", exists)                    
}                              
+2

to nie tylko równość. 'map' jest tablicą asocjacyjną, więc każdy typ klucza również potrzebuje funkcji mieszania – newacct

+0

True. I zapomniałem, że odkąd big.Int jest zmienny (co mi się nie podoba) umieszczenie ich w tablicach hash może nie być tak mądre. Może powinienem trzymać się funkcjonalnego programowania :) – Olof

Odpowiedz

7

Przepisy o równości zamiar wkrótce zmienić. Z Go 1 plan:

Go 1 określi równości na wartości struct i tablic składających się z pól, na których równość jest również określone (element mądry porównanie). Usunie równość z funkcji i wartości mapy, z wyjątkiem porównania z zerową. Przejdź 1 nadal będzie wykluczać równość dla plasterków . (W ogólnym przypadku jest to niewykonalne.)

Jednak nawet z tym zasadami, nie można używać *BigInt jako klucz, ponieważ zawiera kawałek. Zauważ też, że w Go nie można napisać niestandardowego operatora równości (nie można go zastąpić żadnym innym operatorem). Ale to jest w rzeczywistości siła Go w mojej opinii - bez niego rzeczy są po prostu prostsze.

Będziesz więc musiał używać ciągów znaków dla swoich kluczy. Łańcuchy jednak nie muszą być formatowane w systemie dziesiętnym (lub w jakimkolwiek innym formacie), o ile nie chcesz ich drukować. Tak więc najszybszym sposobem jest prawdopodobnie użycie metody Bytes() (która również odrzuci znak, pamiętaj o dołączeniu go osobno do łańcucha znaków).