Establece la estructura de datos en Golang

60

Realmente me gusta google golang pero ¿podría alguien explicar cuál es la razón para que los implementadores hayan omitido una estructura de datos básica como los conjuntos de la biblioteca estándar?

    
pregunta cobie 28.11.2012 - 01:02

3 respuestas

60

Una posible razón para esta omisión es que es realmente fácil modelar conjuntos con un mapa.

Para ser honesto, creo que también es un descuido, sin embargo, mirando a Perl, la historia es exactamente la misma. En Perl obtienes listas y tablas hash, en Go obtienes matrices, cortes y mapas. En Perl, por lo general, utilizas una tabla hash para todos los problemas relacionados con un conjunto, lo mismo se aplica a Go.

Ejemplo

para imitar un conjunto de entradas en Go, definimos un mapa:

set := make(map[int]bool)

Agregar algo es tan fácil como:

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

Eliminar algo es solo

delete(set, i)

Y la torpeza potencial de esta construcción se extrae fácilmente:

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
}

Y eliminar y obtener se pueden definir de manera similar, tengo la implementación completa aquí . La principal desventaja aquí es el hecho de que ir no tiene genéricos. Sin embargo, es posible hacerlo con interface{} , en cuyo caso habrías obtenido los resultados de get.

    
respondido por el jozefg 28.11.2012 - 04:08
3

La respuesta anterior funciona SOLAMENTE SI la clave es un tipo integrado. Para complementar la respuesta anterior, aquí hay una manera de implementar un conjunto cuyos elementos son tipos definidos por el usuario:

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))}
}
    
respondido por el amahfouz 16.02.2015 - 04:46
2

Creo que esto tiene que ver con el enfoque golang en la simplicidad. set s se vuelve realmente útil con los métodos difference , intersection , union , issubset , etc. Quizás el equipo de golang consideró que es demasiado para una estructura de datos. Pero por lo demás, un "conjunto de tontos" que solo tiene add , contains y remove se puede replicar fácilmente con map como se explica en @jozefg.

    
respondido por el Akavall 17.11.2015 - 05:40

Lea otras preguntas en las etiquetas

Comentarios Recientes

¶módulo de datos. Establecer () donde los datos Persona = Persona {nombre :: Int, dirección :: Int} derivando (Eq, Mostrar, Mostrar) import struct.pack # Nombres completos en el paquete struct [Nombre] (...) derivando (Mostrar, [Eq, Eq]) func n-scala. Persona {_ _ = P (P (Persona {nombre :: Cadena, dirección :: Cadena})), err = P (UnicodeError (mapa .. ""), parseJSON (str "Error de codificación de caracteres Unicode 5")), })} doc <- 1.3 UnoType main :: IO () main = printfn "================================ ==========================... Lee mas