Question
I am trying to combine multiple strings into one comma-separated string in Go using strings.Join, but my code gives a type error:
package main
import (
"fmt"
"strings"
)
func main() {
reg := [...]string{"a", "b", "c"}
fmt.Println(strings.Join(reg, ","))
}
The error is:
prog.go:10: cannot use reg (type [3]string) as type []string in argument to strings.Join
Why does this happen, and what is the correct way to join these values into a single string? Is there a better approach than manually looping and appending to a variable?
Short Answer
By the end of this page, you will understand why strings.Join accepts a slice of strings rather than an array, how arrays and slices differ in Go, and how to correctly convert or declare your data so it can be joined. You will also see practical examples, common mistakes, and how this appears in real Go codebases.
Concept
In Go, strings.Join is designed to work with a slice of strings:
func Join(elems []string, sep string) string
That means its first argument must be of type []string.
In your code, however, reg is declared as:
reg := [...]string{"a", "b", "c"}
This creates an array, not a slice. In Go, arrays and slices are related, but they are different types.
[3]stringmeans: an array with exactly 3 strings[]stringmeans: a slice of strings of any length
Even though they look similar, Go does not automatically treat an array as a slice when calling a function that expects []string.
To use strings.Join, you have two common options:
- Declare the value as a slice from the start
- Slice the array using
reg[:]
Mental Model
Think of an array as a fixed-size storage box with a label saying exactly how many compartments it has.
[3]string= a box with exactly 3 slots[5]string= a different box with 5 slots
A slice is more like a view or window into a sequence of items.
[]string= “some strings,” without fixing the count in the type
strings.Join says: “Give me a slice view of strings.”
If you hand it a fixed-size array box, Go says: “That is not the same type.”
When you write reg[:], you are saying: “Create a slice view over the whole array.” That gives strings.Join exactly what it expects.
Syntax and Examples
The correct syntax for strings.Join is:
strings.Join(sliceOfStrings, separator)
Example 1: Declare a slice directly
package main
import (
"fmt"
"strings"
)
func main() {
reg := []string{"a", "b", "c"}
result := strings.Join(reg, ",")
fmt.Println(result)
}
Output:
a,b,c
This is the simplest approach when you want to join values.
Example 2: Convert an array to a slice
package main
import (
"fmt"
"strings"
)
func main() {
reg := [...]string{"a", "b", "c"}
result := strings.Join(reg[:], ",")
fmt.Println(result)
}
Output:
Step by Step Execution
Consider this example:
package main
import (
"fmt"
"strings"
)
func main() {
reg := [...]string{"a", "b", "c"}
result := strings.Join(reg[:], ",")
fmt.Println(result)
}
Step by step:
-
reg := [...]string{"a", "b", "c"}- Go creates an array of type
[3]string - It contains three values:
"a","b", and"c"
- Go creates an array of type
-
reg[:]- This creates a slice over the entire array
- The new value has type
[]string
-
strings.Join(reg[:], ",")strings.Joinreceives the slice- It places between each element
Real World Use Cases
Joining string slices is common in many kinds of Go programs.
Building CSV-like output
row := []string{"Alice", "25", "London"}
line := strings.Join(row, ",")
Creating log messages
parts := []string{"INFO", "server started", "port=8080"}
msg := strings.Join(parts, " | ")
Generating file paths or keys
segments := []string{"users", "42", "profile"}
path := strings.Join(segments, "/")
Formatting tags or labels
tags := []string{"go", "backend", "api"}
output := strings.Join(tags, ", ")
Combining SQL placeholders or dynamic content
When building text from known safe string parts, strings.Join is cleaner and more readable than repeated concatenation.
Real Codebase Usage
In real Go projects, developers usually prefer slices over arrays for data they want to pass to functions.
Common pattern: declare slices directly
headers := []string{"Content-Type", "Authorization", "X-Trace-ID"}
fmt.Println(strings.Join(headers, ", "))
This is common because slices work naturally with:
- function parameters
- loops
append- standard library functions
Pattern: join after collecting values
var errors []string
errors = append(errors, "name is required")
errors = append(errors, "email is invalid")
msg := strings.Join(errors, "; ")
This is often used in validation and error reporting.
Pattern: guard clause for empty data
func formatTags(tags []string) string {
if len(tags) == 0 {
return "no tags"
}
strings.Join(tags, )
}
Common Mistakes
1. Using an array instead of a slice
Broken code:
reg := [...]string{"a", "b", "c"}
fmt.Println(strings.Join(reg, ","))
Why it fails:
regis an arraystrings.Joinexpects[]string
Fix:
fmt.Println(strings.Join(reg[:], ","))
Or declare it as a slice:
reg := []string{"a", "b", "c"}
2. Confusing [3]string and []string
These are not interchangeable.
[3]stringand[4]stringare also different from each other[]stringis a separate type
3. Manually concatenating in a loop
Comparisons
| Concept | Type | Fixed size? | Common for function parameters? | Works with strings.Join directly? |
|---|---|---|---|---|
| Array | [3]string | Yes | No | No |
| Slice | []string | No | Yes | Yes |
Array vs slice in Go
arr := [...]string{"a", "b", "c"} // array
slc := []string{"a", "b", "c"} // slice
Use an array when:
Cheat Sheet
// strings.Join signature
strings.Join(elems []string, sep string) string
Use a slice directly
items := []string{"a", "b", "c"}
result := strings.Join(items, ",")
Convert an array to a slice
arr := [...]string{"a", "b", "c"}
result := strings.Join(arr[:], ",")
Key rules
strings.Joinneeds[]string[3]stringis an array, not a slicearr[:]creates a slice over the whole array- Empty slice joined with any separator returns
"" - Separator is inserted between elements only
Common forms
strings.Join(words, " ") // sentence
strings.Join(parts, )
strings.Join(tags, )
strings.Join(lines, )
FAQ
Why does strings.Join not accept an array in Go?
Because its function signature explicitly requires []string, which is a slice type. Arrays and slices are different types in Go.
How do I convert an array to a slice in Go?
Use slicing syntax:
arr[:]
This creates a slice covering the whole array.
Should I use arrays or slices for strings in Go?
In most everyday Go code, use slices. Arrays are less common for function arguments because their size is part of the type.
Is strings.Join better than looping manually?
Yes, when you already have a slice of strings. It is shorter, clearer, and idiomatic.
What happens if I join an empty slice?
You get an empty string:
strings.Join([]string{}, ",") // ""
Can I join values that are not strings?
Not directly with strings.Join. You must first convert them to strings.
Does strings.Join add a separator at the end?
No. The separator is only placed between elements.
Mini Project
Description
Create a small Go program that formats a list of command-line style labels into a single readable string. This demonstrates how slices are collected and joined using strings.Join, which is a common pattern in logging, reporting, and configuration output.
Goal
Build a Go program that joins a list of labels into a comma-separated string and handles the empty case cleanly.
Requirements
- Declare a slice of strings containing at least three labels.
- Use
strings.Jointo combine them into one string. - Print the final result.
- Add a small function that returns a fallback message when the slice is empty.
Keep learning
Related questions
Automatic Build Versioning in Go: Embed Incrementing Build Numbers
Learn how to add automatic build versioning in Go using linker flags, build metadata, CI counters, and Git-based version values.
Blank Identifier Imports in Go: What `_` Means in an Import Statement
Learn what `_` means in a Go import, why blank identifier imports run package init code, and when to use them safely.
Calling Functions Across Files in the Same Go Package
Learn how Go uses packages across multiple files, why functions may appear undefined, and how to organize code correctly.