48

I have the following struct which contains a net/http.Request:

type MyRequest struct { http.Request PathParams map[string]string } 

Now I want to initialize the anonymous inner struct http.Request in the following function:

func New(origRequest *http.Request, pathParams map[string]string) *MyRequest { req := new(MyRequest) req.PathParams = pathParams return req } 

How can I initialize the inner struct with the parameter origRequest?

1

4 Answers 4

45
req := new(MyRequest) req.PathParams = pathParams req.Request = origRequest 

or...

req := &MyRequest{ PathParams: pathParams Request: origRequest } 

See: http://golang.org/ref/spec#Struct_types for more about embedding and how the fields get named.

Sign up to request clarification or add additional context in comments.

4 Comments

I get the compiler error cannot use origRequest (type *http.Request) as type http.Request in assignment. I guess this is because Request is not a named field.
nope it's because the type of the field is not the same as the type of origRequest. Use *origRequest instead and the problem goes away.
You're right: derefencing with the asterisk or using a reference in the struct helps. Thanks.
As for how the fields get named: "The unqualified type name acts as the field name." So http.Request ends up being called just Request.
21

What about:

func New(origRequest *http.Request, pathParams map[string]string) *MyRequest { return &MyRequest{*origRequest, pathParams} } 

It shows that instead of

New(foo, bar) 

you might prefer just

&MyRequest{*foo, bar} 

directly.

2 Comments

How about when there is some field you don't want to initialize yourself, e.g., a file of type sync.Mutex?
The zero value of a mutex should be a ready-to-use mutex, so you're good simply including it as an embedded value: var hits struct { sync.Mutex n int } hits.Lock() hits.n++ hits.Unlock() (from 10 things you probably didn't know about Go)
7

As Jeremy shows above, the "name" of an anonymous field is the same as the type of the field. So if the value of x were a struct containing an anonymous int, then x.int would refer to that field.

Comments

2

Just for completeness sake, I'll add another example as well. Based on the comment from @Victor

This example shows another way recommended https://play.golang.org/p/Gbn8e6CTVi_c

type MyRequest struct { http.Request PathParams map[string]string } func New(origRequest *http.Request, pathParams map[string]string) *MyRequest { req := MyRequest{Request: origRequest, PathParams: pathParams} return req } 

Another comment from @Jeffery Martinez helped clarify it further:

As for how the fields get named: "The unqualified type name acts as the field name." So http.Request ends up being called just Request

i.e: The two following declarations are equivalent

// Version 1 type MyRequest struct { http.Request PathParams map[string]string } // Version 2 type MyRequest struct { Request http.Request PathParams map[string]string } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.