In Golang you do not have set data structure. So you can use map instead. When you do not need values there are two options widely used - using empty struct{} or bool as value. struct{} should be more performant, while bool is more convinient. I decided to check the first promise myslef. Golang have benchamrks support in its standard library. SO I wrote this one:

package mapstruct

import (
	"math/rand"
	"testing"
)

func input() []int {
	slice := make([]int, 10_000)
	for i := 0; i < 10_000; i++ {
		slice[i] = rand.Intn(1_000)
	}
	return slice
}

func uniqueBool(input []int) []int {
	vals := map[int]bool{}
	for _, v := range input {
		vals[v] = true
	}
	result := make([]int, 0, len(vals))
	for v := range vals {
		result = append(result, v)
	}
	return result
}

func uniqueStruct(input []int) []int {
	vals := map[int]struct{}{}
	for _, v := range input {
		vals[v] = struct{}{}
	}
	result := make([]int, 0, len(vals))
	for v := range vals {
		result = append(result, v)
	}
	return result
}

func BenchmarkBool(b *testing.B) {
	for i := 0; i < b.N; i++ {
		uniqueBool(input())
	}
}

func BenchmarkStruct(b *testing.B) {
	for i := 0; i < b.N; i++ {
		uniqueStruct(input())
	}
}

And the result are quite variadic (Should developers write their own tooling to run benchamrks multiple times and compute averages, variances, etc?) Here are two results from different runs:

BenchmarkBool
BenchmarkBool-8     	    2378	    494532 ns/op
BenchmarkStruct
BenchmarkStruct-8   	    2210	    512692 ns/op
PASS

BenchmarkBool
BenchmarkBool-8     	    2272	    501090 ns/op
BenchmarkStruct
BenchmarkStruct-8   	    2313	    493226 ns/op
PASS

It seems the promise of more performant map[]struct{} is not true and I don’t see any other reasons to use it over map[]bool.