Convert between slices of different types

前端 未结 7 1030
南旧
南旧 2020-11-30 01:35

I get a byte slice ([]byte) from a UDP socket and want to treat it as an integer slice ([]int32) without changing the underlying array, and vice ve

7条回答
  •  南笙
    南笙 (楼主)
    2020-11-30 02:14

    As others have said, casting the pointer is considered bad form in Go. Here are examples of the proper Go way and the equivalent of the C array casting.

    WARNING: all code untested.

    The Right Way

    In this example, we are using the encoding/binary package to convert each set of 4 bytes into an int32. This is better because we are specifying the endianness. We are also not using the unsafe package to break the type system.

    import "encoding/binary"
    
    const SIZEOF_INT32 = 4 // bytes
    
    data := make([]int32, len(raw)/SIZEOF_INT32)
    for i := range data {
        // assuming little endian
        data[i] = int32(binary.LittleEndian.Uint32(raw[i*SIZEOF_INT32:(i+1)*SIZEOF_INT32]))
    }
    

    The Wrong Way (C array casting)

    In this example, we are telling Go to ignore the type system. This is not a good idea because it may fail in another implementation of Go. It is assuming things not in the language specification. However, this one does not do a full copy. This code uses unsafe to access the "SliceHeader" which is common in all slices. The header contains a pointer to the data (C array), the length, and the capacity. Instead of just converting the header to the new slice type, we first need to change the length and capacity since there are less elements if we treat the bytes as a new type.

    import (
        "reflect"
        "unsafe"
    )
    
    const SIZEOF_INT32 = 4 // bytes
    
    // Get the slice header
    header := *(*reflect.SliceHeader)(unsafe.Pointer(&raw))
    
    // The length and capacity of the slice are different.
    header.Len /= SIZEOF_INT32
    header.Cap /= SIZEOF_INT32
    
    // Convert slice header to an []int32
    data := *(*[]int32)(unsafe.Pointer(&header))
    

提交回复
热议问题