{"id":1082,"date":"2026-08-17T00:30:15","date_gmt":"2026-08-17T00:30:15","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/?p=1082"},"modified":"2026-08-17T00:30:16","modified_gmt":"2026-08-17T00:30:16","slug":"go-tutorial-exported-and-unexported-identifiers","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/go-tutorial-exported-and-unexported-identifiers\/","title":{"rendered":"Go Tutorial: Exported and Unexported Identifiers"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This concept becomes much easier once you remember <strong>one rule<\/strong>:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Starts with an uppercase letter \u2192 Exported<\/strong><br><strong>Starts with a lowercase letter \u2192 Unexported<\/strong><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">In Go, this is how you control whether something can be accessed from another package.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. First: What is an identifier?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">An <strong>identifier<\/strong> is simply a name you give to something in Go.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Examples:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var age int\n\nfunc PrintMessage() {}\n\ntype User struct {}\n\nconst MaxUsers = 100<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here, these are identifiers:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>age\nPrintMessage\nUser\nMaxUsers<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Go uses the <strong>first letter<\/strong> of an identifier to decide whether other packages can access it.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">2. Exported vs Unexported<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Feature<\/th><th>Exported<\/th><th>Unexported<\/th><\/tr><\/thead><tbody><tr><td>First letter<\/td><td>Uppercase<\/td><td>Lowercase<\/td><\/tr><tr><td>Example function<\/td><td><code>PrintMessage()<\/code><\/td><td><code>printMessage()<\/code><\/td><\/tr><tr><td>Example variable<\/td><td><code>Username<\/code><\/td><td><code>username<\/code><\/td><\/tr><tr><td>Example type<\/td><td><code>User<\/code><\/td><td><code>user<\/code><\/td><\/tr><tr><td>Example struct field<\/td><td><code>Name<\/code><\/td><td><code>name<\/code><\/td><\/tr><tr><td>Accessible inside same package<\/td><td>\u2705 Yes<\/td><td>\u2705 Yes<\/td><\/tr><tr><td>Accessible from another package<\/td><td>\u2705 Yes<\/td><td>\u274c No<\/td><\/tr><tr><td>Similar idea in other languages<\/td><td>Public<\/td><td>Private-ish<\/td><\/tr><tr><td>Main purpose<\/td><td>Public package API<\/td><td>Internal implementation<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The easiest mental model is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Uppercase = package exposes it\nLowercase = package keeps it internal<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3. WHAT is an exported identifier?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">An exported identifier is something that <strong>another Go package is allowed to access<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>func SayHello() {\n    fmt.Println(\"Hello\")\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Because <code>SayHello<\/code> begins with uppercase <code>S<\/code>, another package can use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>greeting.SayHello()<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4. WHAT is an unexported identifier?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">An unexported identifier can normally only be used <strong>inside the package where it was declared<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>func buildMessage() {\n    fmt.Println(\"Building message\")\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Because <code>buildMessage<\/code> begins with lowercase <code>b<\/code>, another package cannot do:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>greeting.buildMessage()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That would produce a compile error.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5. WHY does Go have this?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Packages need a way to separate:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Things users should use\n\nfrom\n\nThings used internally by the package<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine a package like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>greeting\n\u2502\n\u251c\u2500\u2500 SayHello()        \u2190 users should call this\n\u251c\u2500\u2500 NewGreeting()     \u2190 users should call this\n\u2502\n\u251c\u2500\u2500 buildMessage()    \u2190 internal helper\n\u2514\u2500\u2500 validateName()    \u2190 internal helper<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">There is usually no reason for users of the package to know about internal functions such as <code>buildMessage()<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Go therefore lets the package expose only its intended API.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6. HOW does Go decide?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The rule is extremely simple.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TD\n    A&#91;Identifier] --&gt; B{First letter uppercase?}\n    B --&gt;|Yes| C&#91;Exported]\n    B --&gt;|No| D&#91;Unexported]\n\n    C --&gt; E&#91;Other packages can access it]\n    D --&gt; F&#91;Other packages cannot access it]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>User\nPrint\nMaxConnections\nName<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">are exported.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>user\nprint\nmaxConnections\nname<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">are unexported.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7. Complete Self-Contained Example<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Because exported\/unexported identifiers are mainly about <strong>communication between packages<\/strong>, the best example needs two packages.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We will create this tiny project:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>exportdemo\/\n\u2502\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 main.go\n\u2502\n\u2514\u2500\u2500 greeting\/\n    \u2514\u2500\u2500 greeting.go<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: <code>go.mod<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module example.com\/exportdemo\n\ngo 1.22<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This simply gives our Go project a module name.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: <code>greeting\/greeting.go<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a directory named:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>greeting<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Inside it create:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>greeting.go<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package greeting\n\n\/\/ Message is exported because it starts with uppercase M.\n\/\/ Other packages can access it.\nvar Message = \"Hello from the greeting package\"\n\n\/\/ secretMessage is unexported because it starts with lowercase s.\n\/\/ Only code inside package greeting can access it.\nvar secretMessage = \"This is a secret message\"\n\n\/\/ SayHello is exported because it starts with uppercase S.\n\/\/ Other packages can call it.\nfunc SayHello() string {\n\treturn secretMessage\n}\n\n\/\/ buildMessage is unexported because it starts with lowercase b.\n\/\/ Only code inside package greeting can call it.\nfunc buildMessage() string {\n\treturn \"Message created internally\"\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Notice something important here.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>SayHello()<\/code> can access:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>secretMessage<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">even though <code>secretMessage<\/code> is unexported.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Why?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because both are inside:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package greeting<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Unexported does <strong>not<\/strong> mean:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>only this function can access it<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It means:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>only this package can access it<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8. <code>main.go<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Create:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>main.go<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport (\n\t\"fmt\"\n\n\t\"example.com\/exportdemo\/greeting\"\n)\n\nfunc main() {\n\n\t\/\/ Message starts with uppercase M.\n\t\/\/ Therefore it is exported from package greeting.\n\tfmt.Println(greeting.Message)\n\n\t\/\/ SayHello starts with uppercase S.\n\t\/\/ Therefore we can call it from package main.\n\tfmt.Println(greeting.SayHello())\n\n\t\/\/ The following DOES NOT work because secretMessage\n\t\/\/ starts with lowercase s.\n\t\/\/\n\t\/\/ fmt.Println(greeting.secretMessage)\n\n\t\/\/ This also DOES NOT work because buildMessage\n\t\/\/ starts with lowercase b.\n\t\/\/\n\t\/\/ fmt.Println(greeting.buildMessage())\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">9. Run the program<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">From the <code>exportdemo<\/code> directory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go run .<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Hello from the greeting package\nThis is a secret message<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">10. What exactly happened?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Our program has two packages:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>main\ngreeting<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Inside <code>greeting<\/code> we declared:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Message\nsecretMessage\nSayHello\nbuildMessage<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Their visibility is:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Identifier<\/th><th>Starts With<\/th><th>Exported?<\/th><th>Accessible from <code>main<\/code>?<\/th><\/tr><\/thead><tbody><tr><td><code>Message<\/code><\/td><td><code>M<\/code> uppercase<\/td><td>\u2705<\/td><td>\u2705<\/td><\/tr><tr><td><code>secretMessage<\/code><\/td><td><code>s<\/code> lowercase<\/td><td>\u274c<\/td><td>\u274c<\/td><\/tr><tr><td><code>SayHello<\/code><\/td><td><code>S<\/code> uppercase<\/td><td>\u2705<\/td><td>\u2705<\/td><\/tr><tr><td><code>buildMessage<\/code><\/td><td><code>b<\/code> lowercase<\/td><td>\u274c<\/td><td>\u274c<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">So this works:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>greeting.Message<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and this works:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>greeting.SayHello()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But this doesn&#8217;t:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>greeting.secretMessage<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and this doesn&#8217;t:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>greeting.buildMessage()<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">11. An important point: unexported does NOT mean inaccessible everywhere<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose we have:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package greeting\n\nvar secretMessage = \"Secret\"\n\nfunc SayHello() string {\n\treturn secretMessage\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is perfectly valid.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>SayHello()<\/code> and <code>secretMessage<\/code> belong to the <strong>same package<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SayHello()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">can use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>secretMessage<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The restriction only becomes important when another package tries to access it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Think of the package as a house:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Package greeting\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                              \u2502\n\u2502  Message       \u2190 exported    \u2502\n\u2502  SayHello()    \u2190 exported    \u2502\n\u2502                              \u2502\n\u2502  secretMessage \u2190 internal    \u2502\n\u2502  buildMessage  \u2190 internal    \u2502\n\u2502                              \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n        \u2191\n        \u2502\n Package main can only\n access exported names<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">12. Struct fields follow the same rule<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This rule is not limited to functions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Consider:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type User struct {\n\tName string\n\tage  int\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Name<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is exported.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>age<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is unexported.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore another package can do:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>user.Name<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">but cannot do:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>user.age<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Again:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Name \u2192 uppercase \u2192 exported\nage  \u2192 lowercase \u2192 unexported<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">13. Functions follow the same rule<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>func StartServer() {}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Exported:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>StartServer\n\u2191\nuppercase<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Another package can call it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>func startServer() {}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is unexported.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">14. Types follow the same rule<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Exported:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type User struct{}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Unexported:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type user struct{}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">15. Constants and variables follow the same rule<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Exported:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const MaxUsers = 100\n\nvar ServerName = \"production\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Unexported:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const maxUsers = 100\n\nvar serverName = \"production\"<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">16. Methods follow the same rule<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Exported:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>func (u User) PrintName() {\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Unexported:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>func (u User) printName() {\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">17. One rule applies everywhere<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">You do <strong>not<\/strong> need separate rules for variables, functions, structs, methods, and constants.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Remember this:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Code<\/th><th>Exported?<\/th><\/tr><\/thead><tbody><tr><td><code>User<\/code><\/td><td>\u2705<\/td><\/tr><tr><td><code>user<\/code><\/td><td>\u274c<\/td><\/tr><tr><td><code>Print()<\/code><\/td><td>\u2705<\/td><\/tr><tr><td><code>print()<\/code><\/td><td>\u274c<\/td><\/tr><tr><td><code>Name<\/code><\/td><td>\u2705<\/td><\/tr><tr><td><code>name<\/code><\/td><td>\u274c<\/td><\/tr><tr><td><code>MaxSize<\/code><\/td><td>\u2705<\/td><\/tr><tr><td><code>maxSize<\/code><\/td><td>\u274c<\/td><\/tr><tr><td><code>Connect()<\/code><\/td><td>\u2705<\/td><\/tr><tr><td><code>connect()<\/code><\/td><td>\u274c<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">18. WHEN should you export something?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Export something when users of your package are supposed to use it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package database\n\nfunc Connect() {\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If another package needs to connect to the database:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>database.Connect()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">then <code>Connect<\/code> needs to be exported.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">19. WHEN should you keep something unexported?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use lowercase names for implementation details.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package database\n\nfunc Connect() {\n\tvalidateConfig()\n\topenConnection()\n}\n\nfunc validateConfig() {\n}\n\nfunc openConnection() {\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Other packages only need:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>database.Connect()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">They don&#8217;t need:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>validateConfig()\nopenConnection()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So those helpers remain unexported.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This gives you a clean package API.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">20. WHERE will you see this in real Go programs?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Very frequently.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Consider the standard <code>fmt<\/code> package.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You write:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fmt.Println(\"Hello\")<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Notice:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Println\nP\n\u2191\nuppercase<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Println<\/code> is exported by the <code>fmt<\/code> package.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Similarly:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http.ListenAndServe(...)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>ListenAndServe<\/code> begins with uppercase <code>L<\/code>, so the <code>net\/http<\/code> package exposes it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This naming convention is fundamental to how Go packages work.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">21. One subtle point: <code>main<\/code> is lowercase<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">You may wonder:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>func main() {\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Why isn&#8217;t it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>func Main() {\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>main()<\/code> is special.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Go specifically looks for:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nfunc main()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">as the program&#8217;s entry point.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It isn&#8217;t designed to be exported and called by other packages.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>main<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">being lowercase is intentional.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">22. Exported is similar to <code>public<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">If you know languages such as Java, C#, C++, or TypeScript, you can roughly think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Go                         Java-like idea\n\nSayHello()      \u2248          public\nsayHello()      \u2248          package internal<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But Go does <strong>not<\/strong> require keywords such as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public\nprivate\nprotected<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Instead, Go uses naming.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Java-style idea:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public void SayHello() {\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Go:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>func SayHello() {\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The uppercase <code>S<\/code> does the job.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">23. Final Comparison<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Question<\/th><th>Exported<\/th><th>Unexported<\/th><\/tr><\/thead><tbody><tr><td>What?<\/td><td>Visible outside package<\/td><td>Hidden from other packages<\/td><\/tr><tr><td>How?<\/td><td>First letter uppercase<\/td><td>First letter lowercase<\/td><\/tr><tr><td>Why?<\/td><td>Create public package API<\/td><td>Hide implementation details<\/td><\/tr><tr><td>When?<\/td><td>Other packages need it<\/td><td>Only your package needs it<\/td><\/tr><tr><td>Where?<\/td><td>Functions, types, fields, methods, variables, constants<\/td><td>Same<\/td><\/tr><tr><td>Example<\/td><td><code>Connect()<\/code><\/td><td><code>connect()<\/code><\/td><\/tr><tr><td>Other package can use?<\/td><td>\u2705 Yes<\/td><td>\u274c No<\/td><\/tr><tr><td>Same package can use?<\/td><td>\u2705 Yes<\/td><td>\u2705 Yes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">24. The 10-second rule to remember<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Whenever you see:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>greeting.SayHello()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">ask:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Does <code>SayHello<\/code> start with an uppercase letter?<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Yes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SayHello\n\u2191\nS<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore it is exported.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Whenever you see:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sayHello<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">lowercase:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sayHello\n\u2191\ns<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore it is unexported.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So remember:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Uppercase \u2192 Exported   \u2192 Other packages can use it\n\nlowercase \u2192 unexported \u2192 Only its package can use it<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That single rule will handle almost every beginner-level exported\/unexported identifier question you encounter in Go.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This concept becomes much easier once you remember one rule: Starts with an uppercase letter \u2192 ExportedStarts with a lowercase letter \u2192 Unexported In Go, this is&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1082","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1082","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=1082"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1082\/revisions"}],"predecessor-version":[{"id":1083,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1082\/revisions\/1083"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=1082"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=1082"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=1082"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}