将结构内容复制到Go中的uint64中
我想把一个结构的值复制到uint64中,没有不安全的方法正确吗将结构内容复制到Go中的uint64中,go,Go,我想把一个结构的值复制到uint64中,没有不安全的方法正确吗 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
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)
}
你试过打字吗
u = uint64(t1.no)
啊,好的。你试过二进制。写/二进制。读吗
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)
}
但是,请注意,二进制软件包使用反射软件包,反射软件包使用不安全软件包。您尝试过类型转换吗
u = uint64(t1.no)
啊,好的。你试过二进制。写/二进制。读吗
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)
}
但是,请注意,二进制软件包使用reflect软件包,reflect软件包使用不安全软件包。例如,在little endian体系结构上,不使用package
不安全软件包
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: copy t1's content into u1 (both id and 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)
}
例如,在little-endian体系结构上,不使用包不安全
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: copy t1's content into u1 (both id and 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)
}
您是否尝试过类型断言u=t1.(T)
?我并不认为这会奏效,但仍然值得一试。另一种方法是自己解析t1的内容并填充T中的字段。我甚至不清楚这意味着什么,因为我不相信Go对系统字长和尾端有任何要求;您可以发现您的最高有效字节是'A'
,'D'
,'E'
或7
。您是否尝试过键入断言u=t1.(T)
?我并不认为这会奏效,但仍然值得一试。另一种方法是自己解析t1的内容并填充T中的字段。我甚至不清楚这意味着什么,因为我不相信Go对系统字长和尾端有任何要求;你可以发现你的最高有效字节是'A'
,'D'
,'E'
或7
。OP试图“强制转换”整个结构,而不仅仅是一个字段。OP试图“强制转换”整个结构,而不仅仅是一个字段。我喜欢这种方法,但它似乎只适用于byte和uint8结构。(我只是指这个例子)我说得对吗?这个方法还有其他限制吗?我喜欢这个方法,但它似乎只适合字节和uint8结构。(我只是指这个例子)。我说得对吗?这个方法还有其他限制吗?