stringgocharacter-encodingrune

How to convert a string to rune?


Here is my code snippet:

var converter = map[rune]rune {//some data}

sample := "⌘こんにちは"

var tmp string

for _, runeValue := range sample {
        fmt.Printf("%+q", runeValue)
        tmp = fmt.Sprintf("%+q", runeValue)
    }

The output of fmt.Printf("%+q", runeValue) is:

'\u2318'
'\u3053'
'\u3093'
'\u306b'
'\u3061'
'\u306f'

These value are literally rune but as the return type of Sprintf is string, I cannot use it in my map which is [rune]rune. I was wondering how can I convert string to rune, or in other words how can I handle this problem?


Solution

  • A string is not a single rune, it may contain multiple runes. You may use a simple type conversion to convert a string to a []runes containing all its runes like []rune(sample).

    The for range iterates over the runes of a string, so in your example runeValue is of type rune, you may use it in your converter map, e.g.:

    var converter = map[rune]rune{}
    sample := "⌘こんにちは"
    for _, runeValue := range sample {
        converter[runeValue] = runeValue
    }
    fmt.Println(converter)
    

    But since rune is an alias for int32, printing the above converter map will print integer numbers, output will be:

    map[8984:8984 12371:12371 12385:12385 12395:12395 12399:12399 12435:12435]
    

    If you want to print characters, use the %c verb of fmt.Printf():

    fmt.Printf("%c\n", converter)
    

    Which will output:

    map[⌘:⌘ こ:こ ち:ち に:に は:は ん:ん]
    

    Try the examples on the Go Playground.

    If you want to replace (switch) certain runes in a string, use the strings.Map() function, for example:

    sample := "⌘こんにちは"
    
    result := strings.Map(func(r rune) rune {
        if r == '⌘' {
            return 'a'
        }
        if r == 'こ' {
            return 'b'
        }
        return r
    }, sample)
    
    fmt.Println(result)
    

    Which outputs (try it on the Go Playground):

    abんにちは
    

    If you want the replacements defined by a converter map:

    var converter = map[rune]rune{
        '⌘': 'a',
        'こ': 'b',
    }
    sample := "⌘こんにちは"
    
    result := strings.Map(func(r rune) rune {
        if c, ok := converter[r]; ok {
            return c
        }
        return r
    }, sample)
    
    fmt.Println(result)
    

    This outputs the same. Try this one on the Go Playground.