Golang generic, make our programming work easier, we only need to write less code, to achieve multi-functional functions.

# Introduction

We will use golang generics to write several common sorting algorithms such as bubble sort, insertion sort, etc. Then test if the sorting algorithm works properly.

# Implementation

## Define the Constraints

package constraints

// Signed is a generic type constraint for all signed integers
type Signed interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}

// Unsigned is a generic type constraint for all unsigned integers
type Unsigned interface {
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
}

// Integer is a generic type constraint for all integers(signed and unsigned)
type Integer interface {
Signed | Unsigned
}

// Float is a generic type constraint for all floating point types
type Float interface {
~float32 | ~float64
}

// Number is a generic type constraint for all numeric type in Go except Complex types
type Number interface {
Integer | Float
}

// Ordered is a generic type constraint for all ordered data types in Go
type Ordered interface {
Integer | ~string | Float
}


## Sorting Algorithms

• Bubble Sort
func BubbleSort[T constraints.Ordered](arr []T) []T {
swapped := true

for swapped {
swapped = false
// length -i - 1 is for ignoring comparisons of elements which have
// already been compared in earlier iterations
for i := 0; i < len(arr)-1; i++ {
if arr[i+1] < arr[i] {
// here swapping of positions is being done
arr[i+1], arr[i] = arr[i], arr[i+1]
swapped = true
}
}
}

return arr
}

• Insertion Sort
func InsertionSort[T constraints.Ordered](arr []T) []T {
for currentIndex := 1; currentIndex < len(arr); currentIndex++ {
// storing current element whose left side is checked for
// its correct position
temp := arr[currentIndex]
iterator := currentIndex

// check whether the adjacent element in left side is greater or
// less than the current element
for ; iterator > 0 && arr[iterator-1] >= temp; iterator-- {

// moving the left side element to one position forward
arr[iterator] = arr[iterator-1]
}

// moving current element to its  correct position
arr[iterator] = temp
}

return arr
}


## Testing

### Generic BubbleSort

Integer

func main() {
ints := []int{1, 4, 6, 2, 8, -1, -4, -2, 9}
fmt.Println(sorts.BubbleSort(ints))
}

// Output:
//  [-4 -2 -1 1 2 4 6 8 9]


Floating

func main() {
floats := []float64{2.1, 3.2, -3, 9, 7, 8.3}
fmt.Println(sorts.BubbleSort(floats))
Output:
}

// Output:
//  [-3 2.1 3.2 7 8.3 9]


Strings

func main() {
strs := []string{"obama", "trump", "biden"}
fmt.Println(sorts.BubbleSort(strs))
}

// Output:
//  [biden obama trump]


### Generic InsertionSort

As we expected, it is consistent with the results of BubbleSort.

# Conclusion

By using generics, some repetitive code is reduced and our work is made easier. Thanks for reading, the full code is in my GitHub repository awesome-golang-algorithm.