Golang Generics: Array Sums Redefined

Home » Programming Language » Golang » Golang Generics: Array Sums Redefined

Golang, or Go, has become an increasingly popular programming language over the years for its simplicity, efficiency, and robust standard library. As a developer, you may have encountered situations where you needed to write repetitive code for different types when working with arrays. Golang 1.18 introduced a game-changing feature: generics. Generics empower developers to write more flexible and reusable code. In this article, we’ll delve deeper into Golang generics, explore how they can redefine array sums, and streamline your code with real-world use case snippets.

Understanding Golang Generics

Generics is a programming concept that allows developers to write functions and data structures that work with different data types without duplicating code. Instead of writing separate functions for each data type, you can write a single function that handles different types, leading to cleaner and more maintainable code.

Golang generics consist of two main components:

  1. Type parameters: Type parameters are placeholders for actual types. They are enclosed in square brackets ([]), and you can define them with functions, types, or methods.
  2. Type constraints: Type constraints define the set of types that can be used as type arguments for a type parameter. They can be defined using interfaces or a special keyword, any.

Using Generics for Array Sums

Before Golang introduced generics, Golang Developers used to write separate functions to compute the sum of elements in an array of different types (e.g., int, float64). Let’s see an example:

func SumInts(arr []int) int {
    sum := 0
    for _, v := range arr {
        sum += v
    }
    return sum
}

func SumFloat64s(arr []float64) float64 {
    sum := 0.0
    for _, v := range arr {
        sum += v
    }
    return sum
}

But now with generics, you can write a single function that works with multiple data types. Here’s an example, How you can rewrite the sum functions using Golang generics:

package main

import (
    "fmt"
)

type Adder interface {
    Add(Adder) Adder
}

type MyInt int
type MyFloat64 float64

func (a MyInt) Add(b Adder) Adder {
    return a + b.(MyInt)
}

func (a MyFloat64) Add(b Adder) Adder {
    return a + b.(MyFloat64)
}

func Sum[T Adder](arr []T) T {
    var sum T = arr[0]
    for _, v := range arr[1:] {
        sum = sum.Add(v).(T)
    }
    return sum
}

func main() {
    intArr := []MyInt{1, 2, 3, 4, 5}
    floatArr := []MyFloat64{1.1, 2.2, 3.3, 4.4, 5.5}

    fmt.Println(Sum(intArr))   // Output: 15
    fmt.Println(Sum(floatArr)) // Output: 16.5
}

In this example, We defined the Adder interface, Which requires an Add method to be implemented for the types it supports. We then created two custom types, MyInt and MyFloat64, That implement the Adder interface. The Add method is defined for both types, and the Sum function uses the Add method for the addition operation. This code should compile and run correctly with Go 1.18 and later.

More Examples

Suppose you’re working on a financial application that processes and analyzes transactions of various currencies. You may need to calculate the sum of transaction amounts for each currency. With Golang generics, You can write a single function to compute the sum for various currencies without duplicating code, here is the code example:

package main

import (
    "fmt"
)

type Adder interface {
    Add(Adder) Adder
}

type MyFloat64 float64

func (a MyFloat64) Add(b Adder) Adder {
    return a + b.(MyFloat64)
}

type CurrencyAmount struct {
    Currency string
    Amount   MyFloat64
}

func SumCurrencyAmounts(transactions []CurrencyAmount) CurrencyAmount {
    var sum MyFloat64 = transactions[0].Amount
    for _, transaction := range transactions[1:] {
        sum = sum.Add(transaction.Amount).(MyFloat64)
    }
    return CurrencyAmount{Currency: transactions[0].Currency, Amount: sum}
}

func main() {
    transactions := []CurrencyAmount{
        {"USD", MyFloat64(100.0)},
        {"USD", MyFloat64(200.0)},
        {"USD", MyFloat64(300.0)},
    }

    sum := SumCurrencyAmounts(transactions)
    fmt.Printf("Total: %s %.2f\n", sum.Currency, sum.Amount) // Output: Total: USD 600.00
}

In the following code snippet, we used a CurrencyAmount struct to represent transaction amounts in various currencies. We defined a custom type MyFloat64, Which is an alias for float64. This custom type implements the Adder interface by providing an Add method. The SumCurrencyAmounts function calculates the sum of transaction amounts in a given currency, taking advantage of the Add method for the addition operation.

By using the SumCurrencyAmounts function, we can easily compute the sum of transaction amounts without having to write separate functions for each currency type. This approach showcases the power of Golang generics in creating cleaner, more maintainable code for various applications, such as financial data analysis.

Extending the Use of Generics: Multi-Dimensional Arrays

Another code example of Golang generics is, Working with multi-dimensional arrays. For example, Suppose you need to compute the sum of all elements in a matrix (a two-dimensional array) of different data types. With Golang generics, You can write a single function to calculate the sum for different data types, Here is an example of it:

package main

import (
    "fmt"
)

type Adder interface {
    Add(Adder) Adder
}

type MyInt int
type MyFloat64 float64

func (a MyInt) Add(b Adder) Adder {
    return a + b.(MyInt)
}

func (a MyFloat64) Add(b Adder) Adder {
    return a + b.(MyFloat64)
}

func SumMatrix[T Adder](matrix [][]T) T {
    var sum T
    for _, row := range matrix {
        for _, v := range row {
            sum = sum.Add(v).(T)
        }
    }
    return sum
}

func main() {
    intMatrix := [][]MyInt{
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9},
    }

    floatMatrix := [][]MyFloat64{
        {1.1, 2.2, 3.3},
        {4.4, 5.5, 6.6},
        {7.7, 8.8, 9.9},
    }

    fmt.Println(SumMatrix(intMatrix))   // Output: 45
    fmt.Println(SumMatrix(floatMatrix)) // Output: 49.5
}

By using the SumMatrix function, you can easily compute the sum of all elements in a multi-dimensional array, regardless of the data type.

Final Word

Golang generics provide a powerful way to streamline your code and make it more reusable. By implementing generics in array sum operations, you can reduce code duplication and improve code maintainability. This feature opens up new possibilities for cleaner, more efficient code in various applications, such as financial data analysis and multi-dimensional array manipulation.

With the introduction of generics in Golang 1.18, developers have a versatile tool at their disposal to create more efficient, maintainable, and elegant code. As you explore Golang generics further, you’ll discover even more ways to apply them to your projects, revolutionizing your coding experience. So, take advantage of Golang generics in your next project, and experience the revolutionized array sums and streamlined code that it brings. Happy coding!

Join Our Newsletter!

Join our newsletter to get our latest ebook "Ultimate JavaScript Cheat-Sheet", and Tips, Articles..

We don’t spam! Read our privacy policy for more info.

Join Our Newsletter!

Join our newsletter to get our latest ebook "Ultimate JavaScript Cheat-Sheet", and Tips, Articles..

We don’t spam! Read our privacy policy for more info.

Leave a Comment

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.