Show byte representation of generic type I am new to Rust. I would like to know any better way of doing this and if it can be done preferably with safe code.  

use std::mem;
use std::mem::size_of;

fn show_byte &lt;T&gt; ( element: T) {

    let array: * mut u8 = unsafe{ mem::transmute(&amp;element) };
    for i in (0.. size_of::&lt;T&gt;()) {
         let current = (array as usize + i) as *mut u8;
         print!("{:X}", unsafe { *current });
    }
}

fn main() {
   show_byte(-1i64);
}
I am not aware of any safe method in the standard library to do this, so we need some unsafe code.

In your code, you have two unsafe blocks. However, the first one is unnecessary: you can use as to perform the cast, but you need two consecutive casts, because we can't cast from &amp;T to *mut u8 directly. Actually, you should use *const u8 here instead, since you don't actually mutate the referent. So, instead of mem::transmute, you can write:

let array = &amp;element as *const T as *const u8;


If you really need a *mut u8, then you'd need to define element as mut and write &amp;mut element instead of &amp;element.

However, I would do this differently. I'd write a function to turn a &amp;T into a slice of bytes (&amp;[u8]), which would encapsulate the only unsafe operation of the program. Then, we can use a simple for loop on that slice to print each byte.

use std::mem;
use std::slice;

fn bytes_of&lt;T&gt;(value: &amp;T) -&gt; &amp;[u8] {
    unsafe {
        slice::from_raw_parts(
            value as *const T as *const u8, mem::size_of::&lt;T&gt;())
    }
}

fn show_as_bytes&lt;T&gt;(element: T) {
    for b in bytes_of(&amp;element) {
        print!("{:X}", b);
    }
}

fn main() {
    show_as_bytes(-1i64);
}


Note that the bytes_of function plays a very important role that would be lost if it was inlined (by hand): the lifetime of the returned byte slice is tied to the lifetime of the input parameter. It's as if it was written thus:

fn bytes_of&lt;'a, T&gt;(value: &amp;'a T) -&gt; &amp;'a [u8] {
    // ...
}


If the function's body was inlined, the slice returned by slice::from_raw_parts would be unconstrained, and the compiler wouldn't be able to report an error if the slice accidentally outlived the data it references, causing subtle memory errors at runtime.



Bonus: Here's how I would format your original code (note the changes to whitespace and the removal of parentheses).

use std::mem::size_of;

fn show_byte&lt;T&gt;(element: T) {
    let array: *mut u8 = unsafe { mem::transmute(&amp;element) };
    for i in 0..mem::size_of::&lt;T&gt;() {
         let current = (array as usize + i) as *mut u8;
         print!("{:X}", unsafe { *current });
    }
}

fn main() {
    show_byte(-1i64);
}