如何在Golang字符串中索引字符?

问题描述 投票:0回答:11

如何获得“E”输出而不是 69?

package main

import "fmt"

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

Golang 是否有将字符转换为字节的函数,反之亦然?

string go character
11个回答
228
投票

解释的字符串文字是双引号 "" 之间的字符序列,使用单个字符的(可能是多字节)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 中的字符串、字节、符文和字符


28
投票

这个怎么样?

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

正如 Peter 指出的,不仅仅允许使用 ASCII:

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

17
投票

您也可以尝试使用字符串进行类型转换。

package main

import "fmt"

func main() {
    fmt.Println(string("Hello"[1]))
}

17
投票

也可以通过切片来完成

package main

import "fmt"

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

注意: 此解决方案仅适用于 ASCII 字符。


9
投票

Go 并没有真正的字符类型。 byte 通常用于 ASCII 字符,rune 用于 Unicode 字符,但它们都只是整数类型(uint8 和 int32)的别名。因此,如果您想强制将它们打印为字符而不是数字,则需要使用

Printf("%c", x)
%c
格式规范适用于任何整数类型。


6
投票

将 char 解释为字符串的一般解决方案是

string("HELLO"[1])

Rich 的解决方案当然也有效。


3
投票

尝试通过索引获取字符

package main

import (
      "fmt"
      "strings"
)

func main() {
   str := strings.Split("HELLO","")
    fmt.Print(str[1])
}

2
投票

字符串字符是符文,因此要打印它们,您必须将它们转回字符串。

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


0
投票

正确答案取决于上下文。

最简单的解决方案是将字符串转换为符文切片。符文是单个 UTF-8 字符。请记住,这种转换对于您的 CPU 以及内存来说都是昂贵的。

package main

import "fmt"

func main() {
    str := "Hello, 世界"
    runeSlice := []rune(str)
    fmt.Printf("%c\n", runeSlice[8])
}

如果您经常需要一次又一次地获取同一字符串的第 i 个字符,这可能是一个很好的解决方案。 在这种情况下,您只需进行一次转换,并多次使用相同的符文切片。

普通字符串是字节数组。当你将其转换为符文切片时,在最坏的情况下它将占用 4 倍的内存,因为单个符文有 4 个字节。这种转变也需要时间。 因此,使用此解决方案创建一个返回字符串第 i 个字符的通用实用函数绝对是糟糕的。 下面的代码可以工作,但不是一个好主意。

package main

import (
    "fmt"
)

func RuneAt(s string, i int) (rune, bool) {
    runeSlice := []rune(s)
    if i >= len(runeSlice) || i < 0 {
        return 0, false
    }
    return runeSlice[i], true
}

func main() {
    str := "Hello, 世界"
    char, ok := RuneAt(str, 8)
    fmt.Printf("char: '%c', ok: %#v\n", char, ok)
}

在这种情况下,更好的解决方案是使用 for 循环和

utf8.DecodeRuneInString
迭代现有字符串以查找第 i 个 unicode 字符。这不会浪费内存和 CPU 时间来创建整个字符串的 4 倍大副本。您仅迭代到您指定的索引。

package main

import (
    "fmt"
    "unicode/utf8"
)

// Get the ith rune in s
func RuneAt(s string, i int) (rune, bool) {
    if i < 0 {
        return 0, false
    }

    leftStr := string(s)
    var result rune
    var j int
    for {
        var size int
        result, size = utf8.DecodeRuneInString(leftStr)
        if size == 0 {
            return 0, false
        }
        if j == i {
            return result, true
        }
        leftStr = leftStr[size:]
        j++
    }
}

func main() {
    str := "Hello, 世界"
    char, ok := RuneAt(str, 8)
    fmt.Printf("char: '%c', ok: %#v\n", char, ok)
}

-2
投票

隔离字符串中的字符的另一种解决方案

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]))

// = 注释行


-6
投票

解决方案是:

 package main

 import "fmt"

func main() {
  str := "HELLO"
  string(str[0])//H
  string(str[1])//E
  string(str[2])//L
  string(str[3])//L
  string(str[4])//O
}
© www.soinside.com 2019 - 2024. All rights reserved.