I think &T
is completely equal to &[T;1]
in memory when T
has a concrete size, so there should be a way to cast &T
to &[T;1]
such as via as
keyword, but I don't know how to do.
They are two completely unrelated types, so adding yet another as
special-case would be entirely the wrong thing to do, especially now that as
is being phased out.
The conversion is already possible via the array::from_ref()
function, and it should absolutely remain nothing more than a plain old function call.
Thanks. I didn't read the document carefully.
Can you elaborate on that? I sometimes use as
.
Since many uses of as
are error-prone and have safer alternatives (eg. floating-point to integer conversions, lossy integer conversions, pointer casts), it's being considered that it should be largely replaced by those alternatives. It's fine to use as
for now, this is not going to happen overnight.
Basically, we're slowly adding methods to types so that the name of the method says what kind of thing you're doing, rather than just seeing as
and needing to run full type inference in your head to figure it out.
For example, *const T as *const U
is (since 1.38) best done via https://doc.rust-lang.org/std/primitive.pointer.html#method.cast, to emphasize that you're keeping it a *const
, just changing the pointee type. And starting in Rust 1.65, *const T as *mut T
will be best done via https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.cast_mut, to emphasize that you're intentionally making it mut
, but aren't changing the pointee type.
On the other hand, there's not yet good alternatives for truncating things like u64 as u16
. (I'd never say people should use (x & 0xFFFF).try_into().unwrap()
, even though it works, because it's so verbose.) So for those you should continue using as
until lang+libs-api comes up with the right way to represent them outside of as
.
I thought on as &[_]
to coerce a reference to an array into a reference to a slice (Playground). I just noticed there is the as_slice
method on it.
Hmmm… so should I consider as &[_]
as worse coding style than using .as_slice()
? I find the first a bit more readable, but maybe that's just my preference.
I think the two ways are all sound because &[...] as &[_]
doesn't make ambiguity. But if you like, as_slice
may be a better alternative which makes your motive more clear.
On the other hand, maybe casting &[T; SIZE]
to &[T]
can be approximate as de-referencing. If the sized slice has corresponding methods, call it, or rustc will trying "de-reference" it to unsized slice to finish the function call.
Yes, but I sometimes stumbled upon some cases where auto-dereference didn't work and I needed to cast manually.
Personally, I like to use slice syntax &vec[..]
or &array[..]
for such a conversion. It's relatively short and represents the idea that you're borrowing it as an arbitrary range.
It is not dereference doesn't work but the thing dereference from also implements the same trait or has the methods with duplicated name, compare to the target it dereference to.
For example, call clone
on Rc<u32>
will result to a new Rc<u32>
but not a u32
. Because if it always doing dereference, then how to call clone
on the origin? Compared with <Rc as Clone>::clone(&some)
, not always auto do dereference is the better design.
Btw, the above is for example, better using Rc::clone(&some)
instead of some.clone()
.
It's possible that as &[_]
will keep working, actually. One potential future is that as
will keep working for anything that's an implicit coercion. (Aka let x: &[_] = &vec;
works.) And there are very few input types for which as &[_]
works at all, so it's not particularly confusing.
as
is much more concerning for things like p as u64
, where it's unclear whether it's supposed to be *p as u64
or p as usize as u64
or what.
Yet I think rustc or rust-analyzer should recognize attempt to do that conversion using as
operator (or even without any explicit conversion) and show special diagnostic pointing to from_ref
's documentation.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.