golang how to specify empty array

7,927 views
Skip to first unread message

Tong Sun

unread,
May 28, 2016, 10:53:53 AM5/28/16
to golang-nuts
Sorry I just can't make it work myself:

parameters := struct {
From    mail.Address
To      []mail.Address
Subject string
Body    string
}{
{},
[]mail.Address, // []mail.Address{}
subject,
body,
}

How to initialize `parameters.To` to an empty array? 

Thanks


Konstantin Shaposhnikov

unread,
May 28, 2016, 10:57:34 AM5/28/16
to golang-nuts
parameters := struct {
From    mail.Address
To      []mail.Address
Subject string
Body    string
}{
mail.Address{},
[]mail.Address{},
"",
"",

Tong Sun

unread,
May 28, 2016, 11:03:42 AM5/28/16
to golang-nuts, Konstantin Shaposhnikov
Durrh! my code was on the same line before I post it out so I was confused where exactly the error coming from. Thanks!


Tong Sun

unread,
May 28, 2016, 11:08:37 AM5/28/16
to golang-nuts, Konstantin Shaposhnikov
How about pointer arrays:

parameters := struct {
From    *mail.Address
To      []*mail.Address
Subject string
Body    string
}{
&mail.Address{},
&[]mail.Address{},
subject,
body,
}

cannot use []mail.Address literal (type *[]mail.Address) as type []*mail.Address in field value

[]&mail.Address{},

even can't pass gofmt. 

Thanks

Konstantin Shaposhnikov

unread,
May 28, 2016, 11:14:43 AM5/28/16
to Tong Sun, golang-nuts
On 28 May 2016 at 23:08, Tong Sun <sunto...@gmail.com> wrote:
> How about pointer arrays:
>
> parameters := struct {
> From *mail.Address
> To []*mail.Address
> Subject string
> Body string
> }{
> &mail.Address{},
> &[]mail.Address{},
> subject,
> body,
> }

parameters := struct {
From *mail.Address
To []*mail.Address
Subject string
Body string
}{
&mail.Address{},
[]*mail.Address{},
"",
"",
}

In Go type can be naturally read from left to right. For example array
([]) of pointers (*) to mail.Address: []*mail.Address and add {} to
make it empty.

Roberto Zanotto

unread,
May 28, 2016, 11:55:13 AM5/28/16
to golang-nuts
Most of the times you don't want to initialize empty slices, it's ok to leave them nil.
(you say arrays but your code says slices)
Empty slices and nil slices behave very similarly.
In fact, len and cap of a nil slice are 0 and do not panic.
Also, it's perfectly fine to append elements to a nil slice.

Tong Sun

unread,
May 28, 2016, 1:08:35 PM5/28/16
to golang-nuts, Konstantin Shaposhnikov
Thank you Konstantin & Roberto for your explanation!

On Sat, May 28, 2016 at 11:13 AM, Konstantin Shaposhnikov  wrote:

Yeah, I know Go's convention is far better and intuitive. I wish I can unlearn my decades of C experiences. :-)

For this particular question, I'm still unable to wrap my head around it yet.

To me, coming from C, 

- '*' symbolizes a pointer
- '&' symbolizes an address-getter, so as to assign to pointers

That's why for `*mail.Address` pointer type, the initialization is `&mail.Address{}`, i.e., an address. Correct so far?

Moving further, I intuitively think that for `[]*mail.Address`, the initialization should be `[]&mail.Address{}`, to put addresses in the slice. If `[]*mail.Address{}` is the correct way to initialize empty  `parameters.To` , then shouldn't `*mail.Address{}` be the correct way to initialize  `parameters.From` as well? I still thing it is contradicting...


Roberto Zanotto

unread,
May 28, 2016, 1:28:50 PM5/28/16
to golang-nuts, k.shapo...@gmail.com
* is two things:
1) An operator that lets you dereference a pointer, like: bar = *foo
2) A token that, inside a type literal, indicates a pointer type, like: type intpt *int

& is just one thing, an operator that lets you take the address of something, like: pt := &foo
& does not make sense inside type literals.

Now, to initialize a slice, you use a slice literal, such as:
myslice := []int{1, 2, 3, 5}
or, if the slice is empty:
myslice := []int{}

What comes before "{}" is the type of the slice ([]int in this case).
The type of the slice is a type literal, so & does not make sense there.

Dave Cheney

unread,
May 28, 2016, 9:44:17 PM5/28/16
to golang-nuts
There are no arrays in your sample code, only slices. In your example of you do not want to initialise a field in strict literal, do not provide any value. If you find that you are having to make up values to properly pad out the space u til you have a real field to initialise you can use the names form, field: value, instead.
Reply all
Reply to author
Forward
0 new messages