Using the index operator [] on a string yields byte:
A string's bytes can be accessed by integer indices 0 through len(s)-1.
so the naive approach of indexing the string directly will work only if it just happens to contain only single-byte characters.
A more solid solution is to convert the string to rune slice:
func replaceAt(s string, i int, c rune) string {
r := []rune(s)
r[i] = c
return string(r)
}
Which will work nicely with arbitrary UTF-8 input:
package main
import "fmt"
var chars = "abcdef"
var multibyte = "由汉字组成的一句话"
func main() {
v := replaceAt(chars, 3, 'z')
fmt.Println(v) // abczef
w := replaceAt(multibyte, 3, 'z')
fmt.Println(w) // 由汉子z成的一句话
}
func replaceAt(s string, i int, c rune) string {
r := []rune(s)
r[i] = c
return string(r)
}
Playground: https://go.dev/play/p/wKtYIkIXw4Z