Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the optimal way to convert a `usize` to a `&str`?

Tags:

rust

I need to convert a usize to a &str to pass to a fn foo(&str). I found the following two ways, but don't know if there is a difference between using as_str() or Deref. Maybe the work done by self in as_str links with Deref somehow? I do not know if it may be better to use one or the other or if they actually are the same.

  1. Using temp.to_string().as_str():

    #[inline]
    #[stable(feature = "string_as_str", since = "1.7.0")]
    pub fn as_str(&self) -> &str {
        self
    }
    
  2. Using &*temp.to_string() or &temp.to_string(). This works via Deref:

    #[stable(feature = "rust1", since = "1.0.0")]
    impl ops::Deref for String {
        type Target = str;
    
        #[inline]
        fn deref(&self) -> &str {
            unsafe { str::from_utf8_unchecked(&self.vec) }
        }
    }
    

The question may depend on what you want to do in foo: does the passed &str need to outlive foo or not ?

foo(&str) is a minimal example for s: &str in this code:

extern crate termbox_sys as termbox;

pub fn print(&self, x: usize, y: usize, sty: Style, fg: Color, bg: Color, s: &str) {
    let fg = Style::from_color(fg) | (sty & style::TB_ATTRIB);
    let bg = Style::from_color(bg);
    for (i, ch) in s.chars().enumerate() {
        unsafe {
            self.change_cell(x + i, y, ch as u32, fg.bits(), bg.bits());
        }
    }
}

pub unsafe fn change_cell(&self, x: usize, y: usize, ch: u32, fg: u16, bg: u16) {
    termbox::tb_change_cell(x as c_int, y as c_int, ch, fg, bg)
}

termbox_sys

like image 951
Angel Angel Avatar asked Apr 27 '16 20:04

Angel Angel


1 Answers

As you noticed, as_str doesn't appear to do anything. In fact it returns self, a &String, where a &str is expected. This causes the compiler to insert a call to Deref. So your two ways are exactly the same.

like image 189
durka42 Avatar answered Nov 17 '22 12:11

durka42