Define a estrutura de dados em Golang

63

Eu realmente gosto do google golang, mas alguém poderia explicar qual é a razão para os implementadores terem omitido uma estrutura de dados básica, como conjuntos da biblioteca padrão?

    
por cobie 28.11.2012 / 01:02
fonte

3 respostas

63

Um motivo potencial para essa omissão é que é realmente fácil modelar conjuntos com um mapa.

Para ser honesto, acho que também é um pouco de descuido, mas olhando para Perl, a história é exatamente a mesma. Em Perl você obtém listas e hashtables, em Go você obtém matrizes, fatias e mapas. Em Perl você geralmente usaria um hashtable para todos e quaisquer problemas relacionados a um conjunto, o mesmo é aplicável ao Go.

Exemplo

para imitar um conjunto de ints em Go, definimos um mapa:

set := make(map[int]bool)

Para adicionar algo é tão fácil quanto:

i := valueToAdd()
set[i] = true

Excluir algo é apenas

delete(set, i)

E o constrangimento potencial dessa construção é facilmente abstraído:

type IntSet struct {
    set map[int]bool
}

func (set *IntSet) Add(i int) bool {
    _, found := set.set[i]
    set.set[i] = true
    return !found   //False if it existed already
}

E delete e get podem ser definidos da mesma forma, eu tenho a implementação completa aqui . A principal desvantagem aqui é o fato de que não tem genéricos. No entanto, é possível fazer isso com interface{} , caso em que você teria lançado os resultados de get.

    
por 28.11.2012 / 04:08
fonte
3

A resposta anterior funciona APENAS SE a chave for do tipo embutido. Para complementar a resposta anterior, aqui está uma maneira de implementar um conjunto cujos elementos são tipos definidos pelo usuário:

package math

// types

type IntPoint struct {
    X, Y int
}

// set implementation for small number of items
type IntPointSet struct {
    slice []IntPoint 
}

// functions

func (p1 IntPoint) Equals(p2 IntPoint) bool {
    return (p1.X == p2.X) && (p1.Y == p2.Y)
}

func (set *IntPointSet) Add(p IntPoint) {
    if ! set.Contains(p) {
        set.slice = append(set.slice, p)
    }
}

func (set IntPointSet) Contains(p IntPoint) bool {
  for _, v := range set.slice {
    if v.Equals(p) {
      return true
    }
  }
  return false
}

func (set IntPointSet) NumElements() int {
    return len(set.slice)
}

func NewIntPointSet() IntPointSet {
  return IntPointSet{(make([]IntPoint, 0, 10))}
}
    
por 16.02.2015 / 04:46
fonte
2

Acho que isso tem a ver com golang foco na simplicidade. set s se tornou realmente útil com os métodos difference , intersection , union , issubset e assim por diante. Talvez golang team ache que é demais para uma estrutura de dados. Caso contrário, um "conjunto estúpido" que tenha apenas add , contains e remove pode ser facilmente replicado com map , conforme explicado por @jozefg.

    
por 17.11.2015 / 05:40
fonte