Sling Academy
Home/Golang/Building Function Registries for Dynamic Dispatch in Go

Building Function Registries for Dynamic Dispatch in Go

Last updated: November 26, 2024

In Go, developing function registries can be a powerful technique for achieving dynamic dispatch, allowing you to call specific functions based on runtime data rather than compile-time decisions. In this tutorial, we will create a simple function registry that maps strings to functions, and explore how to utilize this construct for dynamic behavior.

Setting Up a Basic Function Registry

A function registry is essentially a map where keys are used to identify functions, and values are the functions themselves.

package main

import (
    "fmt"
)

type OperationFunc func(a, b int) int

var registry = map[string]OperationFunc{}

func init() {
    registry["add"] = func(a, b int) int { return a + b }
    registry["subtract"] = func(a, b int) int { return a - b }
}

func main() {
    init()  // Initialize the registry with functions

    opName := "add"
    opFunc, exists := registry[opName]

    if !exists {
        fmt.Printf("Operation %s not found!", opName)
        return
    }

    result := opFunc(5, 3)
    fmt.Printf("The result of %s operation is: %d", opName, result)
}

Understanding the Code

Let's delve into the code with explanations for each segment:

  • OperationFunc: A type alias for functions that take two integers and return an integer. This makes it easier to handle function types.
  • registry: A map variable where keys are strings identifying operations, and the values are functions of type OperationFunc.
  • init(): This function is automatically called when the program starts and is used to register our functions in the map.
  • Main logic in main function that retrieves and executes the registered functions based on a key.

Extending the Registry for More Operations

You can easily extend the registry by adding more operations:

func main() {
    registry["multiply"] = func(a, b int) int { return a * b }
    registry["divide"] = func(a, b int) int {
        if b == 0 {
            fmt.Println("Cannot divide by zero")
            return 0
        }
        return a / b
    }

    //Example usage
    runOperation("multiply", 10, 2)
    runOperation("divide", 10, 0)  // Handle division by zero
}

func runOperation(opName string, a, b int) {
    opFunc, exists := registry[opName]

    if !exists {
        fmt.Printf("Operation %s not exists!\n", opName)
        return
    }

    result := opFunc(a, b)
    fmt.Printf("The result of %s operation is: %d\n", opName, result)
}

Conclusion

By effectively using function registries in Go, you can enhance the flexibility and maintainability of your code, particularly in applications needing dynamic behavior such as plugins, commands processing, or conditional logic execution. This method also hints at advanced language features similar to function pointers in C/C++ while embracing the simplicity and type-safety of Go.

Next Article: Exploring Recursive Variadic Functions for Complex Arguments in Go

Previous Article: Using Reflection to Dynamically Invoke Functions in Go

Series: Functions in Go

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant