Rust, types and borrowing

Reading through the rust book, the rust programming language, I was trying to figure out the type of the variable third in the program below and decided to reuse std::any::Typeid. My simple program is below

fn typeid<T: std::any::Any>(_: &T) {
    println!("{:?}", std::any::TypeId::of::<T>());
}

fn main() {
    let v  = vec![1, 2, 3, 4, 5, 6];
    let third:&i32 = &v[2];
    println!("{}", third);
    let third:Option<&i32> = v.get(2);
    typeid(&third);
    println!("{:#?}", third);
}
  1. Interestingly, it complains that v is dropped while still borrowed, which is suprising. I can't really get anything help me figure out whats going on. Is it that lifetimes of third and v are different? Not calling typeid() causes no issues, should I be annotating the lifetime of third to be the same as v? Is it that taking a reference on third that is causing the issue?
  2. I was trying to enumerate third, via third.some.0 to understand what the layout of option<&i32> really looks like, is there a way I can look at the organization/layout of the enum?

The Any trait requires 'static:

pub trait Any: 'static {
    fn type_id(&self) -> TypeId;
}

Lifetimes apply only to borrows, and 'static means that all temporary borrows are forbidden. So you can't use Any with references to variables.


Definition of Option is here: https://doc.rust-lang.org/std/option/enum.Option.html

You can't see actual layout without peeking into compiler debug info, but you can have a guess based on std::mem::size_of and knowing how types are optimized:

https://doc.rust-lang.org/reference/type-layout.html

https://rust-lang.github.io/unsafe-code-guidelines/layout/enums.html

1 Like

You could use https://doc.rust-lang.org/stable/std/any/fn.type_name_of_val.html

#![feature(type_name_of_val)]

fn main() {
    let v  = vec![1, 2, 3, 4, 5, 6];
    let third:&i32 = &v[2];
    println!("{}", third);
    let third:Option<&i32> = v.get(2);
    println!("{:?}", std::any::type_name_of_val(&third));
    println!("{:#?}", third);
}

You'll have to use nightly Rust, because it's not stable yet.

1 Like

Is there a way for me to dereference an option via something like third.some.0 or third.*some.0 or am I trying to fit C/C++ into rust? Is there a way to look at values without a match?

Virtually anything that you might want to do that is type-consistent, memory-safe and thread-safe is doable in Rust. Often the required means differs from memory-unsafe and thread-unsafe languages, as well as from GC'd languages.

You can't get valid &i32 from the Option<&i32> if the value is None variant. In safe Rust it's guaranteed that every references you can access is valid to dereference, otherwise the source code can not be compiled.

1 Like

Not directly; options are not references.

The map method may be useful?

Makes sense! Thanks!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.