The docs give the following alternative to using transmute:
Turning an &mut T into an &mut U :
let ptr = &mut 0;
let val_transmuted = unsafe {
std::mem::transmute::<&mut i32, &mut u32>(ptr)
};
// Now, put together `as` and reborrowing - note the chaining of `as`
// `as` is not transitive
let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };
Yes, these are pretty much equivalent. However, transmute can also change the types of non-pointer types and it can also change lifetimes. You can't do that with as. Since transmute has such power (and therefore potential for misuse), its use is generally not recommend.
In fact as compiles to the same code even at O0, whereas the transmute version needs at least O1 to collapse. It’s rare to care about performance of unoptimized code but debug builds would be that little smidge quicker with as