将一个结构体的内容复制到Go中的uint64中

huangapple go评论67阅读模式
英文:

Copy a struct content into uint64 in Go

问题

我想将一个结构体的值复制到uint64中,有没有不使用unsafe的正确方法?

package main

import "fmt"

type T struct {
    id [7]byte
    no uint8
}

func main() {
    t1 := T{[7]byte{'A', 'B', 'C', 'D', 'E', 'F', 'G'}, 7}
    var u uint64
    
    //TODO: 将t1的内容复制到u中(包括id和no)
    //u = *((*uint64)(unsafe.Pointer(&t1)))

    fmt.Println(t1, u)
}
英文:

I want to copy a strcuture's values into uint64, what's the proper method without unsafe?

package main

import "fmt"

type T struct {
	id [7]byte
	no uint8
}

func main() {
	t1 := T{[7]byte{'A', 'B', 'C', 'D', 'E', 'F', 'G'}, 7}
	var u uint64
	
	//TODO: copy t1's content into u (both id and no)
    //u = *((*uint64)(unsafe.Pointer(&t1)))

	fmt.Println(t1, u)
}

答案1

得分: 2

你试过类型转换了吗?

u = uint64(t1.no)

啊,好的。你试过使用binary.Write / binary.Read了吗?

package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
)

type T struct {
    id [7]byte
    no uint8
}

func main() {
    t1 := T{[7]byte{'A', 'B', 'C', 'D', 'E', 'F', 'G'}, 7}
    var u uint64

	var b bytes.Buffer
	binary.Write(&b, binary.LittleEndian, &t1)
	binary.Read(&b, binary.LittleEndian, &u)

    fmt.Println(t1, u)
}

但是请注意,binary包使用reflect包,reflect包使用unsafe包。

英文:

Did you try type cast?

u = uint64(t1.no)

Ah, ok. Did you try binary.Write / binary.Read ?

package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
)

type T struct {
    id [7]byte
    no uint8
}

func main() {
    t1 := T{[7]byte{'A', 'B', 'C', 'D', 'E', 'F', 'G'}, 7}
    var u uint64

	var b bytes.Buffer
	binary.Write(&b, binary.LittleEndian, &t1)
	binary.Read(&b, binary.LittleEndian, &u)

    fmt.Println(t1, u)
}

However, note that binary package uses reflect package, reflect package uses unsafe package.

答案2

得分: 2

例如,在小端架构上,不使用unsafe包,

package main

import (
	"fmt"
	"unsafe"
)

type T struct {
	id [7]byte
	no uint8
}

func Uint64LEFromT(t T) uint64 {
	return uint64(t.id[0]) | uint64(t.id[1])<<8 | uint64(t.id[2])<<16 | uint64(t.id[3])<<24 |
		uint64(t.id[4])<<32 | uint64(t.id[5])<<40 | uint64(t.id[6])<<48 | uint64(t.no)<<56
}

func Uint64LEToT(t *T, v uint64) {
	t.id[0] = byte(v)
	t.id[1] = byte(v >> 8)
	t.id[2] = byte(v >> 16)
	t.id[3] = byte(v >> 24)
	t.id[4] = byte(v >> 32)
	t.id[5] = byte(v >> 40)
	t.id[6] = byte(v >> 48)
	t.no = byte(v >> 56)
}

func main() {
	t1, t2 := T{[7]byte{'A', 'B', 'C', 'D', 'E', 'F', 'G'}, 7}, T{}
	var u1, u2 uint64

	//TODO: 将t1的内容复制到u1(包括id和no)
	u1 = *((*uint64)(unsafe.Pointer(&t1)))
	fmt.Printf("t1 to u1 (unsafe): t1 %X u1 %X\n", t1, u1)

	//DONE:
	u2 = Uint64LEFromT(t1)
	fmt.Printf("t1 to u2 (safe):   t1 %X u2 %X\n", t1, u2)
	Uint64LEToT(&t2, u2)
	fmt.Printf("u2 to t2 (safe):   t2 %X u2 %X\n", t2, u2)
}

输出:

t1 to u1 (unsafe): t1 {41424344454647 7} u1 747464544434241
t1 to u2 (safe):   t1 {41424344454647 7} u2 747464544434241
u2 to t2 (safe):   t2 {41424344454647 7} u2 747464544434241
英文:

For example, on little-endian architectures, without using package unsafe,

package main

import (
	&quot;fmt&quot;
	&quot;unsafe&quot;
)

type T struct {
	id [7]byte
	no uint8
}

func Uint64LEFromT(t T) uint64 {
	return uint64(t.id[0]) | uint64(t.id[1])&lt;&lt;8 | uint64(t.id[2])&lt;&lt;16 | uint64(t.id[3])&lt;&lt;24 |
		uint64(t.id[4])&lt;&lt;32 | uint64(t.id[5])&lt;&lt;40 | uint64(t.id[6])&lt;&lt;48 | uint64(t.no)&lt;&lt;56
}

func Uint64LEToT(t *T, v uint64) {
	t.id[0] = byte(v)
	t.id[1] = byte(v &gt;&gt; 8)
	t.id[2] = byte(v &gt;&gt; 16)
	t.id[3] = byte(v &gt;&gt; 24)
	t.id[4] = byte(v &gt;&gt; 32)
	t.id[5] = byte(v &gt;&gt; 40)
	t.id[6] = byte(v &gt;&gt; 48)
	t.no = byte(v &gt;&gt; 56)
}

func main() {
	t1, t2 := T{[7]byte{&#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;, &#39;G&#39;}, 7}, T{}
	var u1, u2 uint64

	//TODO: copy t1&#39;s content into u1 (both id and no)
	u1 = *((*uint64)(unsafe.Pointer(&amp;t1)))
	fmt.Printf(&quot;t1 to u1 (unsafe): t1 %X u1 %X\n&quot;, t1, u1)

	//DONE:
	u2 = Uint64LEFromT(t1)
	fmt.Printf(&quot;t1 to u2 (safe):   t1 %X u2 %X\n&quot;, t1, u2)
	Uint64LEToT(&amp;t2, u2)
	fmt.Printf(&quot;u2 to t2 (safe):   t2 %X u2 %X\n&quot;, t2, u2)
}

Output:

t1 to u1 (unsafe): t1 {41424344454647 7} u1 747464544434241
t1 to u2 (safe):   t1 {41424344454647 7} u2 747464544434241
u2 to t2 (safe):   t2 {41424344454647 7} u2 747464544434241

huangapple
  • 本文由 发表于 2013年6月17日 10:39:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/17139717.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定