# Exported/Unexported Identifiers In Go

- Published: March 15, 2014
- Author: William Kennedy
- URL: https://www.ardanlabs.com/blog/2014/03/exportedunexported-identifiers-in-go.html

<b><span style="font-size: large;">Introduction</span></b><br />
One of the first things I learned about in Go was using an uppercase or lowercase letter as the first letter when naming a type, variable or function. It was explained that when the first letter was capitalized, the identifier was public to any piece of code that wanted to use it. When the first letter was lowercase, the identifier was private and could only be accessed within the package it was declared.<br />

I have come to realize that the use of the language public and private is really not accurate. It is more accurate to say an identifier is exported or unexported from a package. When an identifier is exported from a package, it means the identifier can be directly accessed from any other package in the code base. When an identifier is unexported from a package, it can't be directly accessed from any other package. What we will soon learn is that just because an identifier is unexported, it doesn't mean it can't be accessed outside of its package, it just means it can't be accessed directly.<br />
<br />
<b><span style="font-size: large;">Direct Identifier Access</span></b><br />
Let's start with a simple example of an exported type:<br />
<br />
Here we define a named type called <span style="font-family: Courier New, Courier, monospace;">AlertCounter</span>&nbsp;inside the package <span style="font-family: Courier New, Courier, monospace;">counters</span>. This type is an alias for the built-in type <span style="font-family: Courier New, Courier, monospace;">int</span>, but in Go <span style="font-family: Courier New, Courier, monospace;">AlertCounter</span>&nbsp;will be considered a unique and distinct type. We are using the capital letter <span style="font-family: Courier New, Courier, monospace;">'A'</span> as the first letter for the name of the type, which means this type is exported and accessible by other packages.<br />
<br />
Now let's access our&nbsp;<span style="font-family: Courier New, Courier, monospace;">AlertCounter</span>&nbsp;type in the main program:<br />
<br />
Since the <span style="font-family: Courier New, Courier, monospace;">AlertCounter</span>&nbsp;type has been exported, this code builds fine. When we run the program we get the value of 10.<br />
<br />
Now let's change the exported <span style="font-family: Courier New, Courier, monospace;">AlertCounter</span>&nbsp;type to be an unexported type by changing the name to <span style="font-family: Courier New, Courier, monospace;">alertCounter</span>&nbsp;and see what happens:<br />
<br />
After making the changes to the <span style="font-family: Courier New, Courier, monospace;">counters</span>&nbsp;and <span style="font-family: Courier New, Courier, monospace;">main</span>&nbsp;packages, we attempt to build the code again and get the following compiler error:<br />
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
./main.go:11: cannot refer to unexported name counters.alertCounter<br />
./main.go:11: undefined: counters.alertCounter
</div>
<br />
As expected we can't directly access the&nbsp;<span style="font-family: Courier New, Courier, monospace;">alertCounter</span>&nbsp;type because it is unexported. Even though we&nbsp;can't access the&nbsp;<span style="font-family: Courier New, Courier, monospace;">alertCounter</span>&nbsp;type directly anymore, there is a way for us to create and use variables of this unexported type in the main package:<br />
<br />
In the <span style="font-family: Courier New, Courier, monospace;">counters</span>&nbsp;package we add an exported function called <span style="font-family: Courier New, Courier, monospace;">NewAlertCounter</span>. This function creates and returns values of the&nbsp;<span style="font-family: Courier New, Courier, monospace;">alertCounter</span>&nbsp;type. In the main program we use this&nbsp;function and the programming logic stays the same.<br />
<br />
What this example shows is that an identifier that is declared as unexported can still be accessed and used by other packages. It just can't be accessed directly.<br />
<br />
<b><span style="font-size: large;">Using Structs</span></b><br />
Defining exported and unexported members for our structs work in the exact same way. If a field or method name starts with a capital letter, the member is exported and is accessible outside of the package. If a field or method starts with a lowercase letter, the member is unexported and does not have accessibility outside of the package.<br />
<br />
Here is an example of a struct with both exported and unexported fields. The main program has a compiler error because it attempts to access the unexported field directly:<br />
<br />
Here is the error from the compiler:<br />
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
./main.go:14: unknown animal.Dog field 'age' in struct literal
</div>
<br />
As expected the compiler does not let the main program access the <span style="font-family: Courier New, Courier, monospace;">age</span>&nbsp;field directly.<br />
<br />
Let's look at an interesting example of embedding. We start with two struct types where one type embeds the other:<br />
<br />
We added a new exported type called <span style="font-family: Courier New, Courier, monospace;">Animal</span>&nbsp;with two exported fields called <span style="font-family: Courier New, Courier, monospace;">Name</span>&nbsp;and <span style="font-family: Courier New, Courier, monospace;">Age</span>. Then we embed the <span style="font-family: Courier New, Courier, monospace;">Animal</span>&nbsp;type into the exported <span style="font-family: Courier New, Courier, monospace;">Dog</span>&nbsp;type. This means that the <span style="font-family: Courier New, Courier, monospace;">Dog</span>&nbsp;type now has three exported fields, <span style="font-family: Courier New, Courier, monospace;">Name</span>, <span style="font-family: Courier New, Courier, monospace;">Age</span>&nbsp;and <span style="font-family: Courier New, Courier, monospace;">BarkStrength</span>.<br />
<br />
Let's look at the implementation of the main program:<br />
<br />
In main we use a composite literal to create and initialize a value of the exported <span style="font-family: Courier New, Courier, monospace;">Dog</span>&nbsp;type. Then we display the structure and values of the <span style="font-family: Courier New, Courier, monospace;">dog</span>&nbsp;value.<br />
<br />
To make things more interesting, let's change the <span style="font-family: Courier New, Courier, monospace;">Animal</span>&nbsp;type from exported to unexported by changing the first letter of the type's name to a lowercase letter <span style="font-family: Courier New, Courier, monospace;">'a'</span>:<br />
<br />
The&nbsp;<span style="font-family: Courier New, Courier, monospace;">animal</span>&nbsp;type remains embedded in the exported&nbsp;<span style="font-family: Courier New, Courier, monospace;">Dog</span>&nbsp;type, but now as an unexported type.&nbsp;We keep the <span style="font-family: Courier New, Courier, monospace;">Name</span>&nbsp;and <span style="font-family: Courier New, Courier, monospace;">Age</span>&nbsp;fields within the <span style="font-family: Courier New, Courier, monospace;">animal</span>&nbsp;type as exported fields.<br />
<br />
In the main program we just change the name of the type from <span style="font-family: Courier New, Courier, monospace;">Animal</span>&nbsp;to <span style="font-family: Courier New, Courier, monospace;">animal</span>:<br />
<br />
Once again we have a main program that can't compile because we are trying to access the unexported type <span style="font-family: Courier New, Courier, monospace;">animal</span>&nbsp;from inside the composite literal:<br />
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
./main.go:11: cannot refer to unexported name animals.animal<br />
./main.go:14: unknown animals.Dog field 'animal' in struct literal
</div>
<br />
We can fix the compiler error by initializing the exported fields from the unexported embedded type outside of the composite literal:<br />
<br />
Now the main program builds again. The exported fields that were embedded into the <span style="font-family: Courier New, Courier, monospace;">Dog</span>&nbsp;type from the <span style="font-family: Courier New, Courier, monospace;">animal</span>&nbsp;type are accessible, even though they came from an unexported type. The exported fields keep their exported status when the type is embedded.<br />
<br />
<b><span style="font-size: large;">Standard Library</span></b><br />
The exported <span style="font-family: Courier New, Courier, monospace;">Time</span>&nbsp;type from the <span style="font-family: Courier New, Courier, monospace;">time</span>&nbsp;package is a good example of a type from the standard library that provides no access to its internals:<br />
<br />
The language designers are using the unexported fields to keep the internals of the <span style="font-family: Courier New, Courier, monospace;">Time</span> type private. They are &quot;hiding&quot; the information so we can't do anything contrary to how the time data works. With that being said, we still can use the unexported fields through the interface they provide. Without the ability to use and access unexported fields indirectly, we would not be able to copy values of this type or embed this type into our own struct types.<br />
<br />
<b><span style="font-size: large;">Conclusion</span></b><br />
A solid understanding of how to hide and provide access to data from our packages is important. There is a lot more to exporting and unexporting identifiers than meets the eye. In setting out to write this post, I though a couple of examples would do the trick. Then I realized how involved the topic can get once we start looking at embedding unexported types into our own types.<br />
<br />
The ability to use exported or unexported identifiers is an implementation detail, one that Go give us flexibility to use in our programs. The standard library has great examples of using unexported identifiers to hide and protect data. We looked at one example with the <span style="font-family: Courier New, Courier, monospace;">time.Time</span>&nbsp;type. Take the time to look at the standard library to learn more.
