Jeevachaithanyan Sivanandan

golang-exported-unexported

In Programming, Go · 3 min read

Here’s a real-life example in Go programming language that demonstrates the concept of exported and unexported names using a fictional package for handling user profiles.

Imagine you’re building an application that manages user data, and you create a user package with some fields and functions related to user profiles. Only some of the fields and functions should be accessible from outside the user package.

Scenario: A user Package to Manage User Profiles

Unexported Fields (Private):

For security, we may want to keep fields like password private.

These fields should not be accessible from other packages directly.

Exported Fields (Public):

Fields like Username and Email are fine to share with other packages.

These should be accessible from outside the package.

Exported Functions:

A function like SetPassword allows controlled access to modify the password field.

A function like DisplayUserProfile provides a way to print user details.

// user/user.go
package user

// Exported fields (public)
type Profile struct {
    Username string  // Exported: accessible outside of the package
    Email    string  // Exported: accessible outside of the package
}

// Unexported fields (private)
type Profile struct {
    username string // Unexported: accessible only within the package
    email    string // Unexported: accessible only within the package
    password string // Unexported: password should not be accessible outside
}

// Exported function (public)
func (p *Profile) SetPassword(newPassword string) {
    p.password = newPassword
}

// Exported function (public)
func (p *Profile) DisplayUserProfile() {
    fmt.Printf("User: %s\nEmail: %s\n", p.Username, p.Email)
}

// Unexported function (private)
func (p *Profile) getEncryptedPassword() string {
    return encrypt(p.password) // Hypothetical encryption function
} 

In this example:

Exported Fields: Username and Email in the Profile struct can be accessed directly from outside the package. Other packages could display these fields.

Unexported Fields: password is unexported (lowercase), so it’s only accessible within the user package.

Exported Function: SetPassword is accessible to other packages to allow password changes.

Unexported Function: getEncryptedPassword is private and used only within the user package for security reasons.

Using the Package Outside

Suppose you want to use the user package in your main application

// main.go
package main

import (
    "fmt"
    "user"
)

func main() {
    profile := user.Profile{
        Username: "john_doe",
        Email: "john.doe@example.com",
    }

    profile.SetPassword("securePassword123")

    // Accessing exported fields
    fmt.Println("Username:", profile.Username)
    fmt.Println("Email:", profile.Email)

    // Trying to access password directly would cause an error:
    // fmt.Println(profile.password) // Error: password is not exported

    // Display user profile
    profile.DisplayUserProfile()
} 

In the main function:

You can access and modify Username and Email because they are exported, call SetPassword to change the password securely, attempting to access password directly will result in an error, since it’s unexported. The DisplayUserProfile function is also accessible because it’s exported.