Convenciones de nomenclatura en Go

·

4 min read

Variables

// Variables locales
userID := 42                  // ✅ camelCase
totalAmount := 100.50         // ✅ camelCase
isValid := true               // ✅ camelCase (booleano con prefijo "is")

// Variables de paquete (no exportadas)
var defaultTimeout = 30       // ✅ camelCase
var loggerInstance *Logger    // ✅ camelCase

Constantes

// Constantes públicas (exportadas)
const MaxRetries = 3          // ✅ UPPER_SNAKE_CASE
const DefaultTimeout = 60     // ✅ UPPER_SNAKE_CASE

// Constantes internas (no exportadas)
const maxBufferSize = 1024    // ✅ camelCase
const apiKey = "secret"       // ✅ camelCase

Tipos

// Tipos básicos
type UserID int               // ✅ PascalCase
type PaymentStatus string     // ✅ PascalCase

// Enums (usando iota)
type Status int
const (
    StatusPending Status = iota  // ✅ PascalCase
    StatusActive
    StatusInactive
)

Estructuras

// Estructura pública
type UserProfile struct {      // ✅ PascalCase
    UserID      string         // ✅ Exportado (PascalCase)
    CreatedAt   time.Time      // ✅ Exportado (PascalCase)
    isActive    bool           // ✅ No exportado (camelCase)
}

// Estructura interna
type dbConfig struct {         // ✅ camelCase (no exportada)
    host     string            // ✅ camelCase
    port     int               // ✅ camelCase
    username string            // ✅ camelCase
}

Métodos

// Método público
func (u *User) Save() error {  // ✅ PascalCase
    // Lógica para guardar el usuario
}

// Método privado
func (u *User) validate() bool {  // ✅ camelCase
    return u.UserID != ""
}

// Método con receptor corto
func (c *Client) Send() {      // ✅ Receptor corto y claro
    // Lógica para enviar datos
}

Funciones

// Función pública
func CalculateTotal(items []Item) float64 {  // ✅ PascalCase
    total := 0.0
    for _, item := range items {
        total += item.Price
    }
    return total
}

// Función privada
func validateInput(input string) bool {  // ✅ camelCase
    return len(input) > 0
}

Interfaces

// Interfaz pública
type Reader interface {        // ✅ PascalCase + sufijo "er"
    Read(p []byte) (n int, err error)
}

// Interfaz con múltiples métodos
type Storage interface {       // ✅ PascalCase
    Save(data []byte) error
    Load(id string) ([]byte, error)
}

Paquetes

// Nombre de paquete
package user                   // ✅ lowercase (singular)
package httputil               // ✅ lowercase (evitar "utils")

Parámetros

// Parámetros en funciones
func CreateUser(ctx context.Context, name string, age int) (*User, error) {  // ✅ camelCase
    // Lógica para crear usuario
}

// Parámetros en métodos
func (s *Service) ProcessOrder(orderID string, quantity int) error {  // ✅ camelCase
    // Lógica para procesar orden
}

Variables Globales

// Variable global no exportada
var defaultConfig = Config{    // ✅ camelCase
    Timeout: 30,
    Retries: 3,
}

// Variable global exportada
var GlobalLogger = NewLogger() // ✅ PascalCase

Acrónimos

// Acrónimos en nombres
type HTTPClient struct {       // ✅ Mayúsculas completas
    BaseURL string
}

func ParseJSON(data []byte) (map[string]interface{}, error) {  // ✅ Mayúsculas completas
    // Lógica para parsear JSON
}

Errores

// Variables de error
var ErrNotFound = errors.New("not found")  // ✅ Err + PascalCase
var ErrTimeout = errors.New("timeout")     // ✅ Err + PascalCase

// Mensajes de error
func GetUser(id int) (*User, error) {
    if id <= 0 {
        return nil, fmt.Errorf("invalid user ID: %d", id)  // ✅ Mensajes en minúscula
    }
    // Lógica para obtener usuario
}

Tests

// Función de test
func TestCalculateTotal(t *testing.T) {  // ✅ Test + PascalCase
    items := []Item{{Price: 10}, {Price: 20}}
    total := CalculateTotal(items)
    if total != 30 {
        t.Errorf("expected 30, got %v", total)
    }
}

// Test en paralelo
func TestUserSave(t *testing.T) {
    t.Parallel()  // ✅ Uso de t.Parallel()
    // Lógica del test
}

Constructores

// Constructor público
func NewUser(name string, age int) *User {  // ✅ New + PascalCase
    return &User{
        Name: name,
        Age:  age,
    }
}

// Constructor con opciones
func NewClient(options ClientOptions) *Client {  // ✅ New + PascalCase
    return &Client{
        Timeout: options.Timeout,
        Retries: options.Retries,
    }
}

Booleanos

// Variables booleanas
isActive := true               // ✅ Prefijo "is"
hasPermission := false         // ✅ Prefijo "has"
canEdit := true                // ✅ Prefijo "can"

// Métodos booleanos
func (u *User) IsAdmin() bool {  // ✅ Prefijo "Is"
    return u.Role == "admin"
}

Ejemplo Completo de un Paquete

package user  // ✅ Nombre de paquete en lowercase

import (
    "errors"
    "time"
)

// Constantes
const MaxLoginAttempts = 5  // ✅ UPPER_SNAKE_CASE

// Estructura
type User struct {  // ✅ PascalCase
    ID        string    // ✅ Exportado
    Name      string    // ✅ Exportado
    createdAt time.Time // ✅ No exportado
}

// Constructor
func NewUser(id, name string) *User {  // ✅ New + PascalCase
    return &User{
        ID:   id,
        Name: name,
    }
}

// Método
func (u *User) IsActive() bool {  // ✅ Prefijo "Is"
    return !u.createdAt.IsZero()
}

// Función pública
func FetchUser(id string) (*User, error) {  // ✅ PascalCase
    if id == "" {
        return nil, errors.New("invalid user ID")  // ✅ Mensaje de error en minúscula
    }
    // Lógica para obtener usuario
    return &User{ID: id, Name: "John Doe"}, nil
}