Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: sync/atomic: constructors for typed atomics #63289

Open
dfawley opened this issue Sep 29, 2023 · 3 comments
Open

proposal: sync/atomic: constructors for typed atomics #63289

dfawley opened this issue Sep 29, 2023 · 3 comments
Labels
Milestone

Comments

@dfawley
Copy link

dfawley commented Sep 29, 2023

Typed atomics are great, but the ergonomics are a bit clumsy when they are in structs and need to be initialized to nonzero values. Consider a struct containing a typed atomic:

type Resource struct {
	Name string
	Value int
	OtherValue atomic.Int32
}

Initialization is typically done inline, but typed atomics need to be done as a separate step:

func newResource(name string, value int, otherValue int32) *Resource {
	r := &Resource{Name:name, Value:value}
	r.OtherValue.Store(otherValue)
	return r
}

If typed atomic constructors were provided, it could be initialized inline as follows:

type Resource struct {
	Name string
	Value int
	OtherValue *atomic.Int32
}

func newResource(name string, value int, otherValue int32) *Resource {
	return &Resource{Name:name, Value:value, OtherValue:atomic.NewInt32(otherValue)}
}
@gopherbot gopherbot added this to the Proposal milestone Sep 29, 2023
@ericlagergren
Copy link
Contributor

I agree about the ergonomics, but it would be a shame for the API to return a pointer since it forces an allocation and adds indirection. Might be difficult because they're all noCopy, though.

@mateusz834
Copy link
Member

I think it should be possible to return non-pointers in the constructors.
AFAIK the noCopy is not triggered on return values.

@AlexanderYastrebov
Copy link
Contributor

AlexanderYastrebov commented Sep 30, 2023

I think it should be possible to return non-pointers in the constructors.
AFAIK the noCopy is not triggered on return values.

Indeed, constructor like this works:

// NewInt32 returns a new Int32 with value val.
func NewInt32(val int32) Int32 { return Int32{v: val} }

This also works:

package atomic_test

import (
	"sync/atomic"
	"testing"
)

func newInt32(val int32) (v atomic.Int32) {
	v.Store(val)
	return
}

func TestNew(t *testing.T) {
	s := struct {
		i32 atomic.Int32
	}{
		i32: newInt32(42),
	}

	if got := s.i32.Load(); got != 42 {
		t.Fatalf("wrong value: got %v, want 42", got)
	}
}

while this, as expected, fails with return copies lock value: sync/atomic.Int32 contains sync/atomic.noCopy:

func newInt32(val int32) atomic.Int32 {
	var v atomic.Int32
	v.Store(val)
	return v
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Incoming
Development

No branches or pull requests

5 participants