string не реализует интерфейс Stringer golang
Допустим я хочу написать функцию конкатенации строк и любых других объектов, приводимых к строкам. Хотел я написать это вот так:
package main
import "fmt"
func concatenate(s1 fmt.Stringer, s2 fmt.Stringer) string {
return s1.String() + s2.String()
}
func main() {
concatenate("q", "w")
}
Но обнаружил, что string не реализует интерфейс Stringer
В связи с этим возникает 2 вопроса
- Можно ли реализовать мою задумку красиво? Я придумал такой вариант:
package main
import "fmt"
type StringStringer struct {
value string
}
func (str StringStringer) String() string {
return str.value
}
func concatenate(s1 fmt.Stringer, s2 fmt.Stringer) string {
return s1.String() + s2.String()
}
func main() {
s1 := StringStringer{"q"}
s2 := StringStringer{"w"}
concatenate(s1, s2)
}
Но все-таки получается как-будто лишний код, мне это не очень нравиться.
- Почему разработчики
goне добавили методString()к строкам? Мне кажется это было бы очень логично, хотя я, конечно, могу ошибаться.
Ответы (1 шт):
Ни один из встроенных типов в Go не имеет методов. Для того, чтобы string удовлетворял интерфейсу fmt.Stringer, нужно к типу string добавить метод String. Тогда сразу возникнет вопрос - какие ещё методы можно добавить? А почему методы добавляются только к string? От этого посыпится вся система встроенных типов.
Ваш тип StringStringer можно упростить:
type StringStringer string
func (s StringStringer) String() string { return string(s) }
В этом случае достаточно делать приведение типа
s1, s2 := "q", "w"
s := Concat(
StringStringer(s1),
StringStringer(s2),
)
Ну и саму функцию конкатенации можно сделать с переменным числом аргументов
func Concat(objects ...fmt.Stringer) string {
var builder strings.Builder
for _, obj := range objects {
builder.WriteString(obj.String())
}
return builder.String()
}
Полный пример https://go.dev/play/p/_EYgKsuQLat