Go 将字符串复制到字符串结构中

Go 将字符串复制到字符串结构中,go,memcpy,unsafe-pointers,Go,Memcpy,Unsafe Pointers,我试图使用unsafe.Pointer从C中模拟memcpy。 我必须以以下方式将字符串映射到字符串结构: package main import ( "fmt" "unsafe" ) type myMessage struct { Field1 [30]string Field2 [2]string Field3 [4]string Field4 [1]string Field5 [1]string } func main() {

我试图使用
unsafe.Pointer
从C中模拟memcpy。 我必须以以下方式将字符串映射到字符串结构:

package main

import (
    "fmt"
    "unsafe"
)

type myMessage struct {
    Field1 [30]string
    Field2 [2]string
    Field3 [4]string
    Field4 [1]string
    Field5 [1]string
}

func main() {

    var inputString string = "Abcdefghi"

    inputPtr := &inputString

    unsafePtr := unsafe.Pointer(inputPtr)

    messPtr := (*myMessage)(unsafePtr)

    var messageString myMessage = *messPtr

    fmt.Println(messageString)
}
结果如下:

./test
{[Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi  Abcdefghi ] [Abcdefghi ] [Abcdefghi  Abcdefghi ] [Abcdefghi] []}
i、 e.代码在最终结构的每个位置复制
inputString


为什么输入字符串重复?

您没有为结构值保留足够的内存。struct值为38个字符串,但只能“复制”一个字符串。因此,剩余的37个字符串反映了第一个字符串之后的随机内存,它恰好是第一个字符串的副本

为结构保留足够的空间,它将按预期工作:

package main

import (
        "fmt"
        "unsafe"
)

type myMessage struct {
        Field1 [30]string
        Field2 [2]string
        Field3 [4]string
        Field4 [1]string
        Field5 [1]string
}

func main() {
        var mem [38]string
        mem[0] = "Abcdefghi"

        fmt.Println("Sizeof(string) =", unsafe.Sizeof(""))
        fmt.Println("Sizeof(myMessage) =", unsafe.Sizeof(myMessage{}))
        fmt.Println("Sizeof(mem) =", unsafe.Sizeof(mem))

        unsafePtr := unsafe.Pointer(&mem)
        messPtr := (*myMessage)(unsafePtr)

        var messageString myMessage = *messPtr
        fmt.Println(messageString)
}

// Output:
// Sizeof(string) = 16
// Sizeof(myMessage) = 608
// Sizeof(mem) = 608
// {[Abcdefghi                             ] [ ] [   ] [] []}

在操场上试试:

您没有为结构值保留足够的内存。struct值为38个字符串,但只能“复制”一个字符串。因此,剩余的37个字符串反映了第一个字符串之后的随机内存,它恰好是第一个字符串的副本

为结构保留足够的空间,它将按预期工作:

package main

import (
        "fmt"
        "unsafe"
)

type myMessage struct {
        Field1 [30]string
        Field2 [2]string
        Field3 [4]string
        Field4 [1]string
        Field5 [1]string
}

func main() {
        var mem [38]string
        mem[0] = "Abcdefghi"

        fmt.Println("Sizeof(string) =", unsafe.Sizeof(""))
        fmt.Println("Sizeof(myMessage) =", unsafe.Sizeof(myMessage{}))
        fmt.Println("Sizeof(mem) =", unsafe.Sizeof(mem))

        unsafePtr := unsafe.Pointer(&mem)
        messPtr := (*myMessage)(unsafePtr)

        var messageString myMessage = *messPtr
        fmt.Println(messageString)
}

// Output:
// Sizeof(string) = 16
// Sizeof(myMessage) = 608
// Sizeof(mem) = 608
// {[Abcdefghi                             ] [ ] [   ] [] []}

在操场上试一试:

此代码将所有的mem字符串写入[30]字符串(Field1)的第一个字符,扩展len(mem)的Field1的长度。相反,期望的结果是将mem传播到最终结构中,但不确定您是如何得出这个结论的。字段1的大小未更改:。字段的长度无论如何是不可变的(30),因为它是其类型的一部分。我觉得我误解了你的目标。如果代码的输出不是您所期望的,您能将期望的结果添加到问题中吗?此代码将所有mem字符串写入[30]字符串(Field1)的第一个字符,扩展len(mem)的Field1的长度。相反,期望的结果是将mem传播到最终结构中,但不确定您是如何得出这个结论的。字段1的大小未更改:。字段的长度无论如何是不可变的(30),因为它是其类型的一部分。我觉得我误解了你的目标。如果代码的输出不是您所期望的,您可以将期望的结果添加到问题中吗?