Your Join function is a simple extension of strings.Join:
func JoinJoinLast(elems []string, sep, lastSep string) string
However, for no obvious reason, you chose a different function parameter signature:
func JoinJoinLast(sep string, lastSep string, words ...string) string
You don't have not provided any testing benchmarks. For example,
BenchmarkJoin-4 5626939 5534918 219 207.49 ns/op 45104 B/op 35 allocs/op
func JoinStringsIntoArray(sep string, lastSep string, words ...string) string {
lastElementIndex := len(words) - 1
var joinedString string
for index, word := range words[0:lastElementIndex] {
if index == lastElementIndex-1 {
sep = lastSep
}
joinedString += word + sep
}
joinedString += words[lastElementIndex]
return joinedString
}
func BenchmarkJoin(b *testing.B) {
words := []string{"one", "two", "three", "four", "five"}
b.ReportAllocs()
b.ResetTimer()
for N := 0; N < b.N; N++ {
JoinStringsIntoArray(", ", " and ", words...)
}
}
BenchmarkJoin-4 1197461216612879 96 70.0195 ns/op 24 32 B/op 1 allocs/op
func JoinLast(elems []string, sep, lastSep string) string {
var join strings.Builder
joinCap := 0
for i := 0; i < len(elems); i++ {
joinCap += len(elems[i])
}
if len(elems) > 1 {
joinCap += len(lastSep)
if len(elems) > 2 {
joinCap += (len(elems) - 2) * len(sep)
}
}
join.Grow(joinCap)
last := len(elems) - 1 - 1
for i, elem := range elems {
if i >= last {
if i == last {
sep = lastSep
} else {
sep = ""
}
}
join.WriteString(elem)
join.WriteString(sep)
}
return join.String()
}
func BenchmarkJoin(b *testing.B) {
words := []string{"one", "two", "three", "four", "five"}
b.ReportAllocs()
b.ResetTimer()
for N := 0; N < b.N; N++ {
JoinLast(words, ", ", " and ")
}
}