In this article, we will learn how to create a custom string utility package in Go. Packages provide a way for us to manage directories, compile fast, and avoid naming collisions. We'll start with basic string functions and move towards creating a more complex package.

Understanding Packages in Go

Before we dive into building our string utility, it's important to understand the concept of packages in Go. A package in Go is essentially a directory containing Go source files. All files within a package can import each other.

Basic Package Setup

First, let's create our package directory structure. Open a terminal and run the following commands:

$ mkdir -p $GOPATH/src/github.com/yourusername/stringutil
$ cd $GOPATH/src/github.com/yourusername/stringutil

Create a file named stringutil.go:

package stringutil

// Reverse returns a reversed string of input.
func Reverse(s string) string {
    r := []rune(s)
    for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
        r[i], r[j] = r[j], r[i]
    }
    return string(r)
}

Basic String Operations

The example function Reverse is a straightforward one that demonstrates reversing a string in Go. This will be a part of our utility package. Let’s step up and add more functionality.

Intermediate String Operations

Next, let's add a function to count vowels in a string:

package stringutil

// CountVowels counts the vowels in a given string.
func CountVowels(s string) int {
    count := 0
    vowels := "aeiouAEIOU"
    for _, char := range s {
        if strings.ContainsRune(vowels, char) {
            count++
        }
    }
    return count
}

Advanced String Conversions

Let’s add an advanced utility to check if a string is a palindrome:

package stringutil

// IsPalindrome checks if a given string is a palindrome.
func IsPalindrome(s string) bool {
    s = strings.ToLower(s)
    return s == Reverse(s)
}

Testing the Package

To ensure everything works, we should write some test cases using Go's testing package. Create a file named stringutil_test.go:

package stringutil

import "testing"

func TestReverse(t *testing.T) {
    input := "hello"
    want := "olleh"
    got := Reverse(input)
    if got != want {
        t.Errorf("Reverse(%q) = %q; want %q", input, got, want)
    }
}

func TestCountVowels(t *testing.T) {
    input := "education"
    want := 5
    got := CountVowels(input)
    if got != want {
        t.Errorf("CountVowels(%q) = %d; want %d", input, got, want)
    }
}

func TestIsPalindrome(t *testing.T) {
    input := "Madam"
    want := true
    got := IsPalindrome(input)
    if got != want {
        t.Errorf("IsPalindrome(%q) = %v; want %v", input, got, want)
    }

    input = "Hello"
    want = false
    got = IsPalindrome(input)
    if got != want {
        t.Errorf("IsPalindrome(%q) = %v; want %v", input, got, want)
    }
}

Run the tests:

$ go test

You should see an output indicating all tests passed successfully if everything was set up correctly. This confirms our package is functioning as intended.

Conclusion

In this tutorial, we learned to create a custom package in Go for string utilities. We built functions to reverse a string, count vowels, and check for palindromes, and tested our code. These skills are fundamental as they help build reusable components effectively in Go projects.