deckarep/golang-set

A simple, battle-tested and generic set type for the Go language. Trusted by GoogleCloudPlatform, Docker, 1Password, Ethereum and Hashicorp.

Go

4,760

211 commits

updated Oct 2, 2026

See the code

README

example workflow Go Report Card GoDoc

golang-set

The missing generic set collection for the Go language. Until Go has sets built-in...use this.

Psst

  • Hi there, 👋! Do you use or have interest in the Zig programming language created by Andrew Kelley? If so, the golang-set project has a new sibling project: ziglang-set! Come check it out!

Update 9/15/2026

Golang-set now squeezes out more performance which adds up to something significant thanks to the work of some of our open-source contributors. (See the benchmarks in the mentioned PRS!) Additionally some convenience methods have been added and a new IsDisjoint method. We cut a major release because the Mongo Driver/BSON support is fully removed from this version. The community in general was not happy to bring in such a large dependency just for supporting BSON Marshaling/Unmarshaling. Additionally, this did impact the project with a security CVE affecting the Mongo driver. Going forward, Golang-set will remain a 100% stdlib only package. The users have spoken and they appreciate the simplicity and minimal attack vector having this package be small in scope.

  • Packaged version: 3.0.0 contains the following:
    • New Filter method added for set element filtering: PR #175
    • Perf: now using Go's maps.Clone() instead of custom implemenation: PR #176
    • New AppendFrom method: PR #178
    • Perf: removes function call overhead internal when marshaling: PR #180
    • Perf: Optimize method calls: PR #195
    • New IsDisjoint method: PR #179
    • Remove Mongo DB driver and BSON support: PR #198

Update 4/20/2026

  • Packaged version: 2.9.0 contains the following:
    • Address an edge case where a deadlock may occur with Each should a panic occur: PR #164
    • BSON Marshaling support for Marshaling and Unmarshaling: PR #142
    • New PopN method: PR #166
    • Reduced allocations by using capacity arg for some methods that may allocate: PR #171

Update 3/14/2025

  • Packaged version: 2.8.0 introduces support for true iterators for Go 1.23+. Please see issue #141 for further details on the implications of how iterations work between older Go versions vs newer Go versions. Additionally, this release has a minor unit-test spelling fix.

Update 12/3/2024

  • Packaged version: 2.7.0 fixes a long-standing bug with JSON Unmarshaling. A large refactor in the interest of performance introduced this bug and there was no way around it but to revert the code back to how it was previously. The performance difference was likely negligible to begin with. JSON Marshaling and Unmarshaling is now properly supported again without needing to do workarounds.

Update 3/5/2023

  • Packaged version: 2.2.0 release includes a refactor to minimize pointer indirection, better method documentation standards and a few constructor convenience methods to increase ergonomics when appending items Append or creating a new set from an exist Map.
  • supports new generic syntax
  • Go 1.18.0 or higher
  • Workflow tested on Go 1.20

With Generics

Coming from Python one of the things I miss is the superbly wonderful set collection. This is my attempt to mimic the primary features of the set collection from Python. You can of course argue that there is no need for a set in Go, otherwise the creators would have added one to the standard library. To those I say simply ignore this repository and carry-on and to the rest that find this useful please contribute in helping me make it better by contributing with suggestions or PRs.

Install

Use go get to install this package.

go get github.com/deckarep/golang-set/v3

Features

  • NEW Generics based implementation (v3 requires Go 1.25 or higher)
  • One common interface to both implementations
    • a non threadsafe implementation favoring performance
    • a threadsafe implementation favoring concurrent use
  • SQL support through the standard sql.Scanner and driver.Valuer interfaces, using JSON arrays
  • Feature complete set implementation modeled after Python's set implementation.
  • Exhaustive unit-test and benchmark suite

Trusted by

This package is trusted by many companies and thousands of open-source packages. Here are just a few sample users of this package.

  • Notable projects/companies using this package
    • Ethereum
    • Docker
    • 1Password
    • Hashicorp

Star History

Star History Chart

Usage

The code below demonstrates how a Set collection can better manage data and actually minimize boilerplate and needless loops in code. This package now fully supports generic syntax so you are now able to instantiate a collection for any comparable type object.

What is considered comparable in Go?

  • Booleans, integers, strings, floats or basically primitive types.
  • Pointers
  • Arrays
  • Structs if all of their fields are also comparable independently

Using this library is as simple as creating either a threadsafe or non-threadsafe set and providing a comparable type for instantiation of the collection.

// Syntax example, doesn't compile.
mySet := mapset.NewSet[T]() // where T is some concrete comparable type.

// Therefore this code creates an int set
mySet := mapset.NewSet[int]()

// Or perhaps you want a string set
mySet := mapset.NewSet[string]()

type myStruct struct {
  name string
  age uint8
}

// Alternatively a set of structs
mySet := mapset.NewSet[myStruct]()

// Lastly a set that can hold anything using the any or empty interface keyword: interface{}. This is effectively removes type safety.
mySet := mapset.NewSet[any]()

Comprehensive Example

package main

import (
  "fmt"
  mapset "github.com/deckarep/golang-set/v3"
)

func main() {
  // Create a string-based set of required classes.
  required := mapset.NewSet[string]()
  required.Add("cooking")
  required.Add("english")
  required.Add("math")
  required.Add("biology")

  // Create a string-based set of science classes.
  sciences := mapset.NewSet[string]()
  sciences.Add("biology")
  sciences.Add("chemistry")
  
  // Create a string-based set of electives.
  electives := mapset.NewSet[string]()
  electives.Add("welding")
  electives.Add("music")
  electives.Add("automotive")

  // Create a string-based set of bonus programming classes.
  bonus := mapset.NewSet[string]()
  bonus.Add("beginner go")
  bonus.Add("python for dummies")
}

Create a set of all unique classes. Sets will automatically deduplicate the same data.

  all := required
    .Union(sciences)
    .Union(electives)
    .Union(bonus)
  
  fmt.Println(all)

Output:

Set{cooking, english, math, chemistry, welding, biology, music, automotive, beginner go, python for dummies}

Is cooking considered a science class?

result := sciences.Contains("cooking")
fmt.Println(result)

Output:

false

Show me all classes that are not science classes, since I don't enjoy science.

notScience := all.Difference(sciences)
fmt.Println(notScience)
Set{ music, automotive, beginner go, python for dummies, cooking, english, math, welding }

Which science classes are also required classes?

reqScience := sciences.Intersect(required)

Output:

Set{biology}

How many bonus classes do you offer?

fmt.Println(bonus.Cardinality())

Output:

2

Thanks for visiting!

-deckarep

concurrency
datastructures
generics
go
golang
set
threadsafe

deckarep/golang-set

A simple, battle-tested and generic set type for the Go language. Trusted by GoogleCloudPlatform, Docker, 1Password, Ethereum and Hashicorp.

Go

4,760

211 commits

updated Oct 2, 2026

See the code

README

example workflow Go Report Card GoDoc

golang-set

The missing generic set collection for the Go language. Until Go has sets built-in...use this.

Psst

  • Hi there, 👋! Do you use or have interest in the Zig programming language created by Andrew Kelley? If so, the golang-set project has a new sibling project: ziglang-set! Come check it out!

Update 9/15/2026

Golang-set now squeezes out more performance which adds up to something significant thanks to the work of some of our open-source contributors. (See the benchmarks in the mentioned PRS!) Additionally some convenience methods have been added and a new IsDisjoint method. We cut a major release because the Mongo Driver/BSON support is fully removed from this version. The community in general was not happy to bring in such a large dependency just for supporting BSON Marshaling/Unmarshaling. Additionally, this did impact the project with a security CVE affecting the Mongo driver. Going forward, Golang-set will remain a 100% stdlib only package. The users have spoken and they appreciate the simplicity and minimal attack vector having this package be small in scope.

  • Packaged version: 3.0.0 contains the following:
    • New Filter method added for set element filtering: PR #175
    • Perf: now using Go's maps.Clone() instead of custom implemenation: PR #176
    • New AppendFrom method: PR #178
    • Perf: removes function call overhead internal when marshaling: PR #180
    • Perf: Optimize method calls: PR #195
    • New IsDisjoint method: PR #179
    • Remove Mongo DB driver and BSON support: PR #198

Update 4/20/2026

  • Packaged version: 2.9.0 contains the following:
    • Address an edge case where a deadlock may occur with Each should a panic occur: PR #164
    • BSON Marshaling support for Marshaling and Unmarshaling: PR #142
    • New PopN method: PR #166
    • Reduced allocations by using capacity arg for some methods that may allocate: PR #171

Update 3/14/2025

  • Packaged version: 2.8.0 introduces support for true iterators for Go 1.23+. Please see issue #141 for further details on the implications of how iterations work between older Go versions vs newer Go versions. Additionally, this release has a minor unit-test spelling fix.

Update 12/3/2024

  • Packaged version: 2.7.0 fixes a long-standing bug with JSON Unmarshaling. A large refactor in the interest of performance introduced this bug and there was no way around it but to revert the code back to how it was previously. The performance difference was likely negligible to begin with. JSON Marshaling and Unmarshaling is now properly supported again without needing to do workarounds.

Update 3/5/2023

  • Packaged version: 2.2.0 release includes a refactor to minimize pointer indirection, better method documentation standards and a few constructor convenience methods to increase ergonomics when appending items Append or creating a new set from an exist Map.
  • supports new generic syntax
  • Go 1.18.0 or higher
  • Workflow tested on Go 1.20

With Generics

Coming from Python one of the things I miss is the superbly wonderful set collection. This is my attempt to mimic the primary features of the set collection from Python. You can of course argue that there is no need for a set in Go, otherwise the creators would have added one to the standard library. To those I say simply ignore this repository and carry-on and to the rest that find this useful please contribute in helping me make it better by contributing with suggestions or PRs.

Install

Use go get to install this package.

go get github.com/deckarep/golang-set/v3

Features

  • NEW Generics based implementation (v3 requires Go 1.25 or higher)
  • One common interface to both implementations
    • a non threadsafe implementation favoring performance
    • a threadsafe implementation favoring concurrent use
  • SQL support through the standard sql.Scanner and driver.Valuer interfaces, using JSON arrays
  • Feature complete set implementation modeled after Python's set implementation.
  • Exhaustive unit-test and benchmark suite

Trusted by

This package is trusted by many companies and thousands of open-source packages. Here are just a few sample users of this package.

  • Notable projects/companies using this package
    • Ethereum
    • Docker
    • 1Password
    • Hashicorp

Star History

Star History Chart

Usage

The code below demonstrates how a Set collection can better manage data and actually minimize boilerplate and needless loops in code. This package now fully supports generic syntax so you are now able to instantiate a collection for any comparable type object.

What is considered comparable in Go?

  • Booleans, integers, strings, floats or basically primitive types.
  • Pointers
  • Arrays
  • Structs if all of their fields are also comparable independently

Using this library is as simple as creating either a threadsafe or non-threadsafe set and providing a comparable type for instantiation of the collection.

// Syntax example, doesn't compile.
mySet := mapset.NewSet[T]() // where T is some concrete comparable type.

// Therefore this code creates an int set
mySet := mapset.NewSet[int]()

// Or perhaps you want a string set
mySet := mapset.NewSet[string]()

type myStruct struct {
  name string
  age uint8
}

// Alternatively a set of structs
mySet := mapset.NewSet[myStruct]()

// Lastly a set that can hold anything using the any or empty interface keyword: interface{}. This is effectively removes type safety.
mySet := mapset.NewSet[any]()

Comprehensive Example

package main

import (
  "fmt"
  mapset "github.com/deckarep/golang-set/v3"
)

func main() {
  // Create a string-based set of required classes.
  required := mapset.NewSet[string]()
  required.Add("cooking")
  required.Add("english")
  required.Add("math")
  required.Add("biology")

  // Create a string-based set of science classes.
  sciences := mapset.NewSet[string]()
  sciences.Add("biology")
  sciences.Add("chemistry")
  
  // Create a string-based set of electives.
  electives := mapset.NewSet[string]()
  electives.Add("welding")
  electives.Add("music")
  electives.Add("automotive")

  // Create a string-based set of bonus programming classes.
  bonus := mapset.NewSet[string]()
  bonus.Add("beginner go")
  bonus.Add("python for dummies")
}

Create a set of all unique classes. Sets will automatically deduplicate the same data.

  all := required
    .Union(sciences)
    .Union(electives)
    .Union(bonus)
  
  fmt.Println(all)

Output:

Set{cooking, english, math, chemistry, welding, biology, music, automotive, beginner go, python for dummies}

Is cooking considered a science class?

result := sciences.Contains("cooking")
fmt.Println(result)

Output:

false

Show me all classes that are not science classes, since I don't enjoy science.

notScience := all.Difference(sciences)
fmt.Println(notScience)
Set{ music, automotive, beginner go, python for dummies, cooking, english, math, welding }

Which science classes are also required classes?

reqScience := sciences.Intersect(required)

Output:

Set{biology}

How many bonus classes do you offer?

fmt.Println(bonus.Cardinality())

Output:

2

Thanks for visiting!

-deckarep

concurrency
datastructures
generics
go
golang
set
threadsafe

Significant stargazers

(top 24 of 46)

Daniel Nephin

537 followers · starred Jan 2016

silverwind

662 followers · starred Jul 2023

Trim21

238 followers · starred Jul 2022

James Sumners

407 followers · starred Aug 2022