Как индексировать символы в строке Голанга?

101

Как получить на выходе "Е" вместо 69?

package main

import "fmt"

func main() {
    fmt.Print("HELLO"[1])
}

Есть ли у Golang функция преобразования символа в байт и наоборот?

user977828
источник

Ответы:

150

Интерпретируемые строковые литералы - это последовательности символов, заключенные в двойные кавычки "" с использованием (возможно, многобайтовой) кодировки UTF-8 отдельных символов. В UTF-8 символы ASCII являются однобайтовыми, что соответствует первым 128 символам Unicode. Строки ведут себя как кусочки байтов. Руна - это целое число, определяющее кодовую точку Unicode. Следовательно,

package main

import "fmt"

func main() {
    fmt.Println(string("Hello"[1]))              // ASCII only
    fmt.Println(string([]rune("Hello, 世界")[1])) // UTF-8
    fmt.Println(string([]rune("Hello, 世界")[8])) // UTF-8
}

Выход:

e
e
界

Читать:

Раздел « Спецификация языка программирования Go » о преобразованиях .

Блог Go: строки, байты, руны и символы в Go

Питер SO
источник
19

Как насчет этого ?

fmt.Printf("%c","HELLO"[1])

Как отмечает Питер, чтобы разрешить не только ASCII:

fmt.Printf("%c", []rune("HELLO")[1])
Богатый чурчер
источник
10

Можно сделать и через нарезку

package main

import "fmt"

func main() {
    fmt.Print("HELLO"[1:2])
}

ПРИМЕЧАНИЕ. Это решение работает только для символов ASCII.

Самкит Джайн
источник
это работает только с однобайтовыми кодировками, попробуйте "हैलो"[:1]дать вам »
vladkras
@vladkras Вы правы. Работает только с ASCII. Для UTF-8 посмотрите утвержденный ответ. Я тоже буду редактировать решение с этой информацией.
Самкит Джайн,
7

В Go нет типа персонажа как такового. byte часто используется для символов ASCII, а rune используется для символов Unicode, но они оба являются просто псевдонимами для целочисленных типов (uint8 и int32). Поэтому, если вы хотите, чтобы они печатались как символы вместо чисел, вам нужно использовать Printf("%c", x). Спецификация %cформата работает для любого целочисленного типа.

Andybalholm
источник
5

Вы также можете попробовать привести его к типу строки.

package main

import "fmt"

func main() {
    fmt.Println(string("Hello"[1]))
}
бесконечный
источник
4

Общее решение интерпретации символа как строки string("HELLO"[1]).

Решение Рича, конечно, тоже работает.

Томас Капплер
источник
0

Попробуйте это, чтобы получить персонажей по их индексу

package main

import (
      "fmt"
      "strings"
)

func main() {
   str := strings.Split("HELLO","")
    fmt.Print(str[1])
}
Аншу
источник
0

Строковые символы - это руны, поэтому для их печати вам нужно снова превратить их в String.

fmt.Print(string("HELLO"[1]))

леммер
источник
-3

Другое решение изолировать символ в строке

package main
import "fmt"

   func main() {
        var word string = "ZbjTS"

       // P R I N T 
       fmt.Println(word)
       yo := string([]rune(word)[0])
       fmt.Println(yo)

       //I N D E X 
       x :=0
       for x < len(word){
           yo := string([]rune(word)[x])
           fmt.Println(yo)
           x+=1
       }

}

для строковых массивов также:

fmt.Println(string([]rune(sArray[0])[0]))

// = закомментированная строка

HMC
источник
11
На самом деле, действительно плохой код, который вызывает панику при вводе Unicode ( len("cafés")> len([]rune("cafés"))и может преобразовывать строку на каждой итерации для O (n²). Просто сделайте это for _, r := range word { fmt.Printf("%c", r) }. Если вы действительно хотите выполнить цикл с индексом for x := 0; x < limit; x++. Пожалуйста, изучите основы языка, прежде чем отвечать вопросы
Dave C