{wcademy}

Как сджойнить слайс в строку на Go?

July 13, 2020

Всем привет!

В стандартной библиотеке уже есть похожая функция:

func main() {
	fmt.Println(strings.Join([]string{"hello", "world"}, " "))
}
hello world

Какой минус? Принимает только строки — надо заранее всё засунуть в один слайс со строками. А можно ли более лаконично и универсально? Ведь дженерики так и не подвезли (обещают в следующем году).

Воспользуемся reflect.ValueOf, чтобы получить value слайса, над которым мы уже сможем провести операции универсально:

package main

import (
	"bytes"
	"fmt"
	"reflect"
)

func Join(elems interface{}, sep string) string {
	val := reflect.ValueOf(elems) // получаем значение слайса

	// если он пустой сразу возвращаем пустую строку
	if val.Len() == 0 {
		return ""
	}

	// создаем буфер с нулевым элементом слайса
	buf := bytes.NewBufferString(fmt.Sprint(val.Index(0)))

	// итерируемся по слайсу, сохраняя значения в буфер
	for i := 1; i < val.Len(); i++ {
		buf.WriteString(sep)
		buf.WriteString(fmt.Sprint(val.Index(i)))
	}

	// и возвращаем финальную строку
	return buf.String()
}

func main() {
	fmt.Println(Join([]int{1, 2, 3}, ", "))
	fmt.Println(Join([]interface{}{"The", "answer", "is", 42}, " "))
}
1, 2, 3
The answer is 42

Ну, неплохо же, да?

И для любителей всего нового, пример того как это будет выглядеть на го с драфтовой версией дженериков:

package main

import (
	"bytes"
	"fmt"
)

func Join(type T)(elems []T, sep string) string {
	buf := bytes.NewBufferString(fmt.Sprint(elems[0]))
	for i := 1; i < len(elems); i++ {
		buf.WriteString(sep)
		buf.WriteString(fmt.Sprint(elems[i]))
	}
	return buf.String()
}

func main() {
	fmt.Println(Join([]int{1, 2, 3}, ", "))
	fmt.Println(Join([]interface{}{"The", "answer", "is", 42}, " "))
}

Поиграться можно здесь.

Всем спасибо!

🚀  Если узнал из статьи что-то полезное, ставь лайк и подписывайся на наш канал в Телеграм или группу ВК. Обсудить статью можно в нашем уютном чатике 😏

© 2019 - 2022, {wcademy}