【问题标题】:Get *uint8 pointer to a first character in a string获取 *uint8 指向字符串中第一个字符的指针
【发布时间】:2017-07-19 03:07:40
【问题描述】:

我正在尝试使用 unsafe.Pointer 将哈希函数从 C 移植到 Go。我需要获取指向键字符串第一个字符的指针。

我试过&(hello[0])&hello[0] 都失败了。

【问题讨论】:

  • 您很可能有 xy 问题。如果您需要遍历字符串中的字节,有比不使用指针更好的方法。
  • @nos 不幸的是没有,有一个繁重的指针算法将字符串中的字符处理为字节、单词和双字。
  • 您不能将字符串中的“字符”作为字节处理,至少在 Unicode 世界中是这样。
  • @exebook 那么这对您的问题至关重要,您应该明确提及您需要做什么。有办法做你需要的,但你的问题太开放了。最好给出具体的问题或编码sn-ps,这样你才能得到具体的答案。您可能仍然需要重新编写代码,而不是从 C 进行 1:1 移植。
  • @nos 谢谢,创建了一个具体问题stackoverflow.com/questions/42507846/…

标签: string pointers go


【解决方案1】:

string 在 Go 中的值是不可变的,因此不是 addressable;所以你不能获取它的符文或字节的地址。如果可以,您可以修改指向的值,从而修改 string 值的内容。在 Go 中还有 no pointer arithmetic

您可以做的只是indexstring,索引string 索引其字节(以UTF-8 编码形式,这就是Go 在内存中存储string 值的方式)。你可以用“索引算术”来“模仿”指针算术。

看这个例子:

s := "Hello World"
i := 0
fmt.Println(s[i], string(s[i]))
i += 4
fmt.Println(s[i], string(s[i]))

输出(在Go Playground上试试):

72 H
111 o

您也可以将string 转换为[]byte[]rune,如果您需要这样做(例如,如果您需要修改字节),您可以使用它。切片也是可寻址的。请注意,将string 值转换为上述切片类型将复制string 内容(以保持string 的不变性)。

虽然它是代表 Unicode 字符的 rune 类型,但如果您尝试重现哈希算法,您很可能希望使用字节,因此将其转换为字节切片(即 UTF-8 string)的编码字节序列:

s := "Hello World"
b := []byte(s)
// Here you can work with b which is addressable

注意,在 Go 中,byteuint8 类型是“相同的”,byteuint8 的别名,你也可以这样写:

s := "Hello World"
b := []uint8(s)

【讨论】:

    【解决方案2】:

    在golang字符串中,它是一个巨大的字节,需要将字符串转换为符文

    package main
    
    import (
        "fmt"
    )
    
    func test(r *rune) {
        *r = rune('L')
    }
    
    func main() {
        s := []rune("Hello")
        fmt.Println(string(s))
        fmt.Println(&s[0])
        test(&s[0])
        fmt.Println(string(s))
    }
    

    Example playground golang

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-22
      • 1970-01-01
      • 2017-05-26
      • 2013-04-26
      • 2021-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多