How should I avoid - literal copies lock value from

12,196 views
Skip to first unread message

Kasun Vithanage

unread,
Aug 7, 2018, 8:42:26 AM8/7/18
to golang-nuts
I'm implementing some thread safe data structures

type Set struct {
   m   map[string]int
   mux sync.Mutex
}

func New() *Set {
return &Set{m: make(map[string]int)}
}


In my Diff function i need to pass an array of sets to do a diff on another set

func (set *Set) DiffS(sets []Set) *Set {
set.mux.Lock()
defer set.mux.Unlock()
dup := duplicateMap(set.m)

for i := 0; i < len(sets); i++ {
for _, key := range sets[i].Elems() {
delete(dup, key)
}
}

return &Set{m: dup}
}

Code works fine, i ve written a unit test like this

func TestSet_Diff(t *testing.T) {
set1 := New()
set2 := New()
set3 := New()

set1.Add([]string{"a", "b", "c", "d"})
set2.Add([]string{"c"})
set3.Add([]string{"a", "b"})

el := set1.Diff([]Set{*set2, *set3})
testsuite.ContainsElements(t, []string{"d"}, el)
}

This Unit Test passes fine

But when i run the vet command with
go vet ./...

I get the following error
internal\types\set\set_test.go:41: literal copies lock value from *set2: set.Set contains sync.Mutex
internal\types\set\set_test.go:41: literal copies lock value from *set3: set.Set contains sync.Mutex

What is the ideal solution for this? 


Kasun Vithanage

unread,
Aug 7, 2018, 8:52:28 AM8/7/18
to golang-nuts
Error is gone when used 

mux *sync.Mutex

Dave Cheney

unread,
Aug 7, 2018, 9:02:25 AM8/7/18
to golang-nuts
Pass a pointer, *Set into your Diff method.

Kasun Vithanage

unread,
Aug 10, 2018, 3:02:57 AM8/10/18
to golang-nuts
I want an slice of sets

jake...@gmail.com

unread,
Aug 11, 2018, 8:41:17 AM8/11/18
to golang-nuts
I don't see anything fundamentally wrong with using a *sync.Mutex as long as users always use New(). It allows Set to be passed by value, which is nice.

But if you keep the mutex as a non pointer, then you probably want to pass a slice of set pointers:
func (set *Set) Diff(sets []*Set) *Set
This avoids copying the mutex when you create your slice, so the test line becomes:
set1.Diff([]*Set{set2, set3})

Of course your original Diff code is technically ok. The problem is in creating a []Set from individual Set objects without violating the mutex copy rules is difficult, and would require a bunch of code.
Reply all
Reply to author
Forward
0 new messages