Helin Wang
Helin Wang

Reputation: 4202

literal initialization of embeded struct with multiple fields

type fun struct {}

type starcraft struct {
    *fun // embedding struct
    mu sync.Mutex
}

I know I can literal initial struct startcraft as:

f := &fun{}
s := starcraft{f, *new(sync.Mutex)}

I don't like it, since:

a. I don't want to initialize sync.Mutex by myself

b. in this case there is a wasted copy using *new(sync.Mutex).

Is there any better way?

Upvotes: 1

Views: 321

Answers (2)

Mr_Pink
Mr_Pink

Reputation: 109377

You can name embedded structs:

s := starcraft{
    fun: f,
    mu:  *new(sync.Mutex),
}

You don't need to use new to create a zero value. If the type is already declared, you don't need to initialize it at all, or you can use the zero value.

s := starcraft{
    fun: f,
    mu:  sync.Mutex{},
}

And since the zero value for a Mutex is a valid, unlocked Mutex (http://golang.org/pkg/sync/#Mutex), you definitely don't need to initialize it, and can leave it out of the struct literal.

s := starcraft{
    fun: f,
}

On top of that, it's also very common to embed the Mutex and call Lock and Unlock directly on the outer struct.

Upvotes: 5

Nick Craig-Wood
Nick Craig-Wood

Reputation: 54079

Embedded structs can be named, which suggests this method

f := &fun{}
s := starcraft{fun:f}

Which might be what you want

Playground

Upvotes: 2

Related Questions