9

I've got a largish struct which until just now I was instantiating with the struct literal syntax, e.g.:

Thing{
  "the name",
  ...
}

I've just added an unexported field the Thing struct and now Go is complaining: implicit assignment of unexported field 'config' in Thing literal.

Is there any way I can continue using the literal syntax even though there's now an unexported field on the struct?

icza
  • 389,944
  • 63
  • 907
  • 827
jbrown
  • 7,518
  • 16
  • 69
  • 117

2 Answers2

18

You can only use composite literals to create values of struct types defined in another package if you use keyed values in the literal, because then you are not required to provide initial values for all fields, and so you can leave out unexported fields (which only the declaring package can set / change).

If the type is declared in the same package, you can set unexported fields too:

t := Thing{
    Name:           "the name",
    someUnexported: 23,
}

But you can only provide initial values for exported fields if the type is declared in another package, which is not a surprise I guess:

t := otherpackage.Thing{
    Name: "the name",
    // someUnexported will implicitly be its zero value
}

If you need values of the struct where the unexported fields have values other than the zero value of their types, the package itself must export some kind of constructor or initializer (or setter method), because from the outside (of the package), you can't change / set unexported fields.

See related question: How to clone a structure with unexported field?

icza
  • 389,944
  • 63
  • 907
  • 827
11

One more point to add. All properties of a structure should start with capital letter if they are supposed to be visible outside the package. For example:

t := Thing
{

    Name: "the name", // <-- This will work because Name start with capital letter 

    someUnexported: 23, // <-- this wont work because someUnexported starts with small letter
}
badbishop
  • 1,281
  • 2
  • 18
  • 38
  • 7
    This is not true. Field can start with a lowercase letter when it is meant to be accessed **only** from the package it is declared in. – begie Sep 12 '19 at 09:09