Как в Go проверить, начинается ли строка с определенной подстроки (аналог StartsWith)?
Используйте strings.HasPrefix — это и есть StartsWith в Go
Вы почти у цели! В Go функция strings.HasPrefix — это полный аналог JavaScript метода startsWith(). Она возвращает bool (true/false) и работает именно так, как вы ожидаете. Не путайте её с strings.HasSuffix (проверка окончания) или strings.Contains (проверка вхождения в любом месте).
Вот исправленный пример вашего кода:
package main
import (
"fmt"
"strings"
)
func main() {
url := "https://example.com/api/v1/users"
// Правильный способ — используем HasPrefix
if strings.HasPrefix(url, "https://") {
fmt.Println("Это HTTPS URL")
}
// Ещё примеры:
path := "/home/user/docs/file.txt"
if strings.HasPrefix(path, "/home") {
fmt.Println("Путь начинается с /home")
}
// Можно проверять и пустые строки
empty := ""
fmt.Println(strings.HasPrefix(empty, "")) // true — пустая строка считается префиксом для любой строки
fmt.Println(strings.HasPrefix(empty, "a")) // false
}
Почему именно HasPrefix?
В Go стандартная библиотека следует принципу «явное лучше неявного». Название HasPrefix (имеет префикс) очень точно описывает действие: «проверяет, имеет ли строка данный префикс». Это более описательно, чем StartsWith. Вот полный список похожих функций из пакета strings:
- strings.HasPrefix(s, prefix) — проверяет, начинается ли s с prefix (возвращает bool)
- strings.HasSuffix(s, suffix) — проверяет, заканчивается ли s на suffix (bool)
- strings.Contains(s, substr) — проверяет, содержит ли s substr в любом месте (bool)
- strings.TrimPrefix(s, prefix) — удаляет prefix из начала s, если он есть (возвращает новую строку)
- strings.CutPrefix(s, prefix) — (Go 1.20+) удаляет prefix и возвращает остаток + true/false
Важные нюансы
1. Регистрозависимость: HasPrefix чувствителен к регистру. HasPrefix("Hello", "he") вернёт false. Если нужна проверка без учёта регистра, используйте strings.EqualFold вместе с HasPrefix или преобразуйте строки:
// Проверка без учёта регистра
if strings.HasPrefix(strings.ToLower(url), "https://") {
// ...
}
// Или через EqualFold (только для полного равенства, не для префикса)
// Для префикса без учёта регистра придётся написать свою функцию
func hasPrefixFold(s, prefix string) bool {
return len(s) >= len(prefix) && strings.EqualFold(s[:len(prefix)], prefix)
}
2. Производительность: HasPrefix работает за O(n) по длине префикса (а не всей строки). Для коротких префиксов это очень быстро.
3. Пустая строка: HasPrefix("anything", "") всегда возвращает true, так как пустая строка считается префиксом для любой строки.
4. Идиоматичность: В Go принято использовать именно HasPrefix, а не оборачивать его в свою функцию типа StartsWith. Это стандартный паттерн, который поймёт любой Go-разработчик.
Альтернатива с Go 1.20+
Если вам нужно не только проверить, но и получить остаток строки после префикса, используйте strings.CutPrefix:
url := "https://example.com"
if rest, ok := strings.CutPrefix(url, "https://"); ok {
fmt.Println("Префикс найден, остаток:", rest) // "example.com"
}
Так что смело используйте strings.HasPrefix — это и есть правильный, идиоматичный способ проверки начала строки в Go.
Создание собственной обёртки для читаемости
Хотя strings.HasPrefix — это стандартный и рекомендуемый способ, в больших проектах иногда удобно создать свою функцию-обёртку с более привычным названием, особенно если в команде есть разработчики из других языков:
package main
import (
"fmt"
"strings"
)
// StartsWith — обёртка над HasPrefix для читаемости
func StartsWith(s, prefix string) bool {
return strings.HasPrefix(s, prefix)
}
func main() {
url := "https://example.com"
// Теперь можно писать как в JS
if StartsWith(url, "https://") {
fmt.Println("HTTPS")
}
// Или даже так, если вы любите fluent-интерфейсы:
// (но в Go это не очень идиоматично)
type MyString string
s := MyString(url)
fmt.Println(s.StartsWith("https://")) // потребует метод на типе
}
Когда это оправдано:
- В проектах с жёсткими корпоративными стандартами кода
- При миграции кода с другого языка (Python, JS, Java)
- Когда нужно добавить логирование или дополнительные проверки
Когда не стоит: В большинстве случаев лучше придерживаться стандартной библиотеки. Go-сообщество привыкло к HasPrefix, и лишние обёртки могут запутать других разработчиков. Кроме того, каждая обёртка — это дополнительный слой абстракции и потенциальное место для багов.
Если вы всё же решите создать свою функцию, обязательно задокументируйте её и укажите, что это просто обёртка над strings.HasPrefix.
Ответов пока нет.
Войдите чтобы оставить ответ