Как сджойнить слайс в строку на 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}, " "))
}
Поиграться можно здесь.
Всем спасибо!
🚀 Если узнал из статьи что-то полезное, ставь лайк и подписывайся на наш канал в Телеграм или группу ВК. Обсудить статью можно в нашем уютном чатике 😏