Question

Go strings.HasPrefix: Check Whether a String Starts With a Prefix

gostringstartswith

Question

Is there a Go function equivalent to Java's startsWith() that checks whether one string begins with another string?

For example, how can I check whether str2 starts with str1 (that is, whether str1 is a prefix of str2)?

Short Answer

Go provides strings.HasPrefix in the standard library. It checks whether a string starts with a specified prefix and returns a bool: true when the prefix matches, otherwise false. You will learn its argument order, behavior, and practical uses.

Concept

Use strings.HasPrefix from Go's built-in strings package to test a string prefix.

strings.HasPrefix(s, prefix)
  • s is the complete string to inspect.
  • prefix is the text that must appear at the beginning of s.
  • The result is a boolean: true or false.
strings.HasPrefix("golang", "go") // true
strings.HasPrefix("golang", "lang") // false

This matters whenever a program needs to classify, validate, or route text based on how it begins. For example, an HTTP service may recognize API paths beginning with /api/, or a file-processing tool may select files whose names begin with report-.

HasPrefix is part of the Go standard library, so no third-party package is required.

Mental Model

Think of a prefix as the opening label on a package.

If a package label reads ORDER-1042, you can check whether it starts with ORDER-. You do not need to inspect the entire label; you only compare the characters at the front.

In strings.HasPrefix(s, prefix), the first argument is the whole package label, and the second argument is the opening label you expect.

Take Quiz

Syntax and Examples

Import the strings package, then call strings.HasPrefix.

package main

import (
	"fmt"
	"strings"
)

func main() {
	filename := "report-2025.csv"

	if strings.HasPrefix(filename, "report-") {
		fmt.Println("This is a report file.")
	}
}

Output:

This is a report file.

The call checks whether filename begins with "report-".

Store the result

isSecureURL := strings.HasPrefix("https://example.com", "https://")
fmt.Println(isSecureURL) // true

Important argument order

The complete string comes first:

strings.HasPrefix("hello world", "hello") // true

This is similar to Java's receiver-based syntax:

"hello world".startsWith("hello")

In Go, the receiver becomes the first function argument.

Step by Step Execution

Consider this program:

package main

import (
	"fmt"
	"strings"
)

func main() {
	path := "/api/users"
	isAPIPath := strings.HasPrefix(path, "/api/")
	fmt.Println(isAPIPath)
}

Step by step:

  1. path stores "/api/users".
  2. strings.HasPrefix compares the beginning of path with "/api/".
  3. The first five characters match: /api/.
  4. The function returns true.
  5. isAPIPath receives true.
  6. fmt.Println prints true.

If path were "/health", the comparison would fail and the result would be false.

Real World Use Cases

strings.HasPrefix is useful wherever the beginning of text has meaning.

  • HTTP routing: Identify requests such as /api/users or /admin/settings.
  • Configuration: Read environment variable names with a shared prefix, such as APP_.
  • File processing: Select generated files named backup-... or report-....
  • Protocol handling: Recognize URL schemes such as https://, mailto:, or git@.
  • Log processing: Filter lines beginning with ERROR: or WARN:.
  • Command-line tools: Identify flags beginning with --, such as --verbose.
Take Quiz

Real Codebase Usage

In real Go projects, prefix checks are commonly combined with validation and early returns.

Guard clause for validation

func validateAPIPath(path string) error {
	if !strings.HasPrefix(path, "/api/") {
		return fmt.Errorf("path must start with /api/")
	}

	return nil
}

The early return keeps invalid input from reaching later logic.

Classify values while processing data

func internalEmails(emails []string) []string {
	result := make([]string, 0)

	for _, email := range emails {
		if strings.HasPrefix(email, "admin@") {
			result = append(result, email)
		}
	}

	return result
}

Normalize before comparing when needed

Prefix checks are case-sensitive. If input may have inconsistent casing, normalize it deliberately:

scheme := "HTTPS://example.com"
isHTTPS := strings.HasPrefix(strings.ToLower(scheme), "https://")
fmt.Println(isHTTPS) // true

Only normalize when case should not matter for your application. Some identifiers and paths are intentionally case-sensitive.

Common Mistakes

Reversing the arguments

The full string must be first and the expected prefix second.

// Incorrect: asks whether "go" starts with "golang".
strings.HasPrefix("go", "golang") // false

// Correct
strings.HasPrefix("golang", "go") // true

Forgetting to import strings

// This will not compile unless the strings package is imported.
strings.HasPrefix("golang", "go")

Add:

import "strings"

Expecting case-insensitive matching

strings.HasPrefix("GoLang", "go") // false

HasPrefix compares case exactly. Use strings.ToLower first only if a case-insensitive rule is appropriate.

Using Contains when position matters

strings.Contains("my-api-path", "api") // true
strings.HasPrefix("my-api-path", "api") // false

Contains checks anywhere in the string. HasPrefix checks only the beginning.

Forgetting that an empty prefix matches

strings.HasPrefix("hello", "") // true

Every string starts with an empty string. Validate the prefix separately if empty prefixes are not allowed.

Comparisons

TaskGo functionExampleResult
Check the beginning of a stringstrings.HasPrefixstrings.HasPrefix("golang", "go")true
Check the end of a stringstrings.HasSuffixstrings.HasSuffix("main.go", ".go")true
Check anywhere in a stringstrings.Containsstrings.Contains("golang", "lan")true
Find the first position of textstrings.Indexstrings.Index("golang", "lan")2

HasPrefix versus manual slicing

You could compare a slice manually:

word := "golang"
if len(word) >= 2 && word[:2] == "go" {
	fmt.Println("match")
}

But strings.HasPrefix(word, "go") is clearer and avoids writing length checks. Manual slicing without a length check can panic when the string is shorter than the prefix.

HasPrefix versus regular expressions

Use HasPrefix for a fixed, literal prefix. It is simpler than a regular expression such as ^api-. Use a regular expression only when the prefix itself has a pattern, such as specific digit or letter rules.

Take Quiz

Cheat Sheet

import "strings"

matched := strings.HasPrefix(s, prefix)
RuleDetail
Argument orderFull string first, prefix second: HasPrefix(s, prefix)
Return typebool
Case sensitivityCase-sensitive
Empty prefixAlways returns true
Prefix longer than stringReturns false
Standard libraryImport strings

Examples:

strings.HasPrefix("main.go", "main")    // true
strings.HasPrefix("main.go", ".go")     // false
strings.HasPrefix("main.go", "")        // true
strings.HasPrefix("go", "golang")       // false
strings.HasPrefix("Go", "go")           // false

Related helpers:

strings.HasSuffix("main.go", ".go")
strings.Contains("main.go", "ain")

FAQ

Is there a startsWith function in Go?

Go uses strings.HasPrefix(s, prefix) instead of a method named startsWith.

What is the equivalent of Java String.startsWith() in Go?

Use strings.HasPrefix. Java's text.startsWith(prefix) is equivalent to Go's strings.HasPrefix(text, prefix).

Does strings.HasPrefix ignore uppercase and lowercase letters?

No. It is case-sensitive. For case-insensitive comparisons, normalize both values with strings.ToLower when that matches your requirements.

Does strings.HasPrefix work with UTF-8 strings?

Yes. It compares string bytes and safely determines whether the exact prefix byte sequence is present. A normal UTF-8 prefix works as expected.

What happens if the prefix is empty?

It returns true, because every string starts with an empty string.

Can I use HasPrefix with a []byte?

Not directly. For byte slices, use bytes.HasPrefix from the bytes package.

Is HasPrefix safe when the prefix is longer than the string?

Yes. It returns false; it does not panic.

Take Quiz

Mini Project

Description

Build a small URL classifier that accepts a list of URLs and labels each one as secure (https://), insecure (http://), or unsupported. This demonstrates how prefix checks can route input into different program behavior.

Goal

Classify each URL by its scheme using strings.HasPrefix.

Requirements

Requirement 1

Take Quiz

Keep learning

Related questions

View more