Menu
Coddy logo textTech

Exported vs Unexported

Part of the Logic & Flow section of Coddy's GO journey — lesson 52 of 68.

In Go, visibility of identifiers (variables, functions, types, etc.) is controlled by a simple naming convention. This determines whether code from other packages can access your identifiers.

Exported identifiers start with a capital letter and are accessible from other packages. Think of them as "public" - they can be used by anyone who imports your package.

// These are exported (public)
var Name string
func Calculate() int
type Person struct

Unexported identifiers start with a lowercase letter and are only accessible within the same package. These are "private" to your package.

// These are unexported (private)
var age int
func helper() string
type config struct

This naming convention is Go's way of controlling access without needing keywords like public or private. When you try to use an unexported identifier from another package, Go will give you a compilation error because that identifier is not visible outside its package.

quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

challenge icon

Challenge

Easy

Fix the visibility issues in a Go package by correcting the naming convention for exported and unexported identifiers. You'll work with a simulated multi-package scenario where some identifiers are incorrectly named, causing compilation errors when accessed from other packages.

You will receive two inputs:

  • A string containing package definitions in the format "package_name:identifier1:type1:visibility1,identifier2:type2:visibility2|package_name:identifier1:type1:visibility1" (e.g., "utils:helper:function:private,Calculate:function:public|main:name:variable:private,Version:variable:public")
  • A string containing access attempts in the format "accessing_package.identifier1,accessing_package.identifier2,accessing_package.identifier3" (e.g., "main.helper,main.Calculate,utils.Version")

Your task is to:

  1. Parse the first input by splitting on pipes to get individual package definitions
  2. For each package definition, split on colons to get package name and its identifiers
  3. For each identifier definition, split on colons to get identifier name, type, and intended visibility
  4. Create a function called fixIdentifierName that takes an identifier name and intended visibility, and returns the corrected name:
    • If visibility is "public", ensure the identifier starts with a capital letter
    • If visibility is "private", ensure the identifier starts with a lowercase letter
  5. Display the package analysis header: "=== PACKAGE VISIBILITY ANALYSIS ==="
  6. For each package, display the package information:
    • "Package: [package_name]"
    • For each identifier in the package:
      • If the identifier name needs fixing: "- [original_name] ([type]) -> [corrected_name] (visibility: [visibility])"
      • If the identifier name is correct: "- [identifier_name] ([type]) (visibility: [visibility]) ✓"
    • Parse the second input by splitting on commas to get individual access attempts
    • For each access attempt, split on dots to get the accessing package and the identifier being accessed
    • Display the access validation header: "=== ACCESS VALIDATION ==="
    • For each access attempt, determine if the access is valid:
      • Find the package that contains the identifier
      • Check if the corrected identifier name starts with a capital letter (exported)
      • If the identifier is exported: "[accessing_package] accessing [target_package].[corrected_identifier_name]: ✓ ALLOWED (exported)"
      • If the identifier is unexported: "[accessing_package] accessing [target_package].[corrected_identifier_name]: ✗ DENIED (unexported)"
      • If the identifier doesn't exist: "[accessing_package] accessing [target_package].[identifier_name]: ✗ NOT FOUND"
    • Count and display the summary statistics:
      • "=== SUMMARY ==="
      • "Total packages analyzed: [number_of_packages]"
      • "Total identifiers processed: [total_number_of_identifiers]"
      • "Identifiers requiring fixes: [number_of_identifiers_that_needed_fixing]"
      • "Access attempts: [number_of_access_attempts]"
      • "Allowed accesses: [number_of_allowed_accesses]"
      • "Denied accesses: [number_of_denied_accesses]"
    • Display the final recommendations:
      • If there were identifiers requiring fixes: "Recommendation: Fix identifier naming to follow Go conventions"
      • If all identifiers were correct: "All identifiers follow proper Go naming conventions"

Use the strings package to split the input strings, the fmt package for formatted output, and string manipulation functions to check and modify identifier names. This challenge demonstrates how Go's naming convention controls package visibility and helps you understand the difference between exported and unexported identifiers.

Cheat sheet

Go controls visibility through naming conventions without explicit keywords like public or private.

Exported identifiers start with a capital letter and are accessible from other packages:

// These are exported (public)
var Name string
func Calculate() int
type Person struct

Unexported identifiers start with a lowercase letter and are only accessible within the same package:

// These are unexported (private)
var age int
func helper() string
type config struct

Attempting to access unexported identifiers from other packages results in compilation errors.

Try it yourself

package main

import (
	"fmt"
	"strings"
)

func main() {
	// Read input
	var packageDefinitions string
	var accessAttempts string
	fmt.Scanln(&packageDefinitions)
	fmt.Scanln(&accessAttempts)

	// TODO: Write your code below
	
	// Create the fixIdentifierName function
	
	// Parse package definitions
	
	// Display package analysis
	
	// Parse access attempts
	
	// Display access validation
	
	// Calculate and display summary statistics
	
	// Display recommendations
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Logic & Flow