Jak indeksować znaki w ciągu Golang?

103

Jak uzyskać wynik „E” zamiast 69?

package main

import "fmt"

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

Czy Golang ma funkcję konwersji znaku na bajt i odwrotnie?

user977828
źródło

Odpowiedzi:

157

Zinterpretowane literały łańcuchowe to sekwencje znaków w podwójnych cudzysłowach "" przy użyciu (być może wielobajtowego) kodowania UTF-8 poszczególnych znaków. W UTF-8 znaki ASCII są jednobajtowe, odpowiadające pierwszym 128 znakom Unicode. Łańcuchy zachowują się jak fragmenty bajtów. Runa to liczba całkowita identyfikująca punkt kodowy Unicode. W związku z tym,

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
}

Wynik:

e
e
界

Czytać:

Przejdź do sekcji Specyfikacja języka programowania na temat konwersji .

Blog Go: ciągi znaków, bajty, runy i postacie w Go

peterSO
źródło
19

A co powiesz na to ?

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

Jak wskazuje Peter, aby pozwolić na coś więcej niż tylko ASCII:

fmt.Printf("%c", []rune("HELLO")[1])
Rich Churcher
źródło
10

Można to zrobić również poprzez krojenie

package main

import "fmt"

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

UWAGA: To rozwiązanie działa tylko w przypadku znaków ASCII.

Samkit Jain
źródło
to działa tylko z kodowaniem jednobajtowym, spróbuj "हैलो"[:1]to daje
vladkras
@vladkras Masz rację. Działa tylko z ASCII. W przypadku UTF-8 spójrz na zatwierdzoną odpowiedź. Będę również edytować rozwiązanie z tymi informacjami.
Samkit Jain
7

Go tak naprawdę nie ma typu postaci jako takiego. bajt jest często używany do znaków ASCII, a runa do znaków Unicode, ale oba są tylko aliasami dla typów całkowitych (uint8 i int32). Więc jeśli chcesz wymusić, aby były drukowane jako znaki zamiast liczb, musisz użyć Printf("%c", x). Specyfikacja %cformatu działa dla każdego typu liczby całkowitej.

andybalholm
źródło
5

Możesz także spróbować typecastingu za pomocą łańcucha.

package main

import "fmt"

func main() {
    fmt.Println(string("Hello"[1]))
}
nieskończonyLearner
źródło
4

Ogólnym rozwiązaniem interpretacji znaku jako łańcucha jest string("HELLO"[1]) .

Oczywiście rozwiązanie Richa również działa.

Thomas Kappler
źródło
1

Znaki ciągów to runy, więc aby je wydrukować, musisz zamienić je z powrotem w ciąg.

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

lemmer
źródło
0

Spróbuj tego, aby uzyskać znaki według ich indeksu

package main

import (
      "fmt"
      "strings"
)

func main() {
   str := strings.Split("HELLO","")
    fmt.Print(str[1])
}
Anshu
źródło
-3

Inne rozwiązanie, aby wyodrębnić znak w ciągu

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
       }

}

także dla tablic ciągów:

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

// = linia z komentarzem

HMC
źródło
11
Naprawdę, naprawdę zły kod, który będzie paniki z wejściem Unicode ( len("cafés")> len([]rune("cafés"))i może przestawienia ciąg na każdej iteracji dla, O (n²). Wystarczy zrobić for _, r := range word { fmt.Printf("%c", r) }. Jeśli naprawdę chciał pętli z indeksem for x := 0; x < limit; x++. Proszę nauczyć się podstaw języka przed odebraniem pytania
Dave C