将 `usize` 转换为 `&str` 的最佳方式是什么?

13

我需要将一个 usize 转换为 &str,以便传递给一个 fn foo(&str)。我找到了以下两种方法,但不知道使用 as_str() 或者 Deref 之间是否有区别。也许 as_str 中的 self 所做的工作与 Deref 有所关联?我不知道使用其中的哪一个是更好的,或者它们实际上是否相同。

  1. 使用 temp.to_string().as_str()

    #[inline]
    #[stable(feature = "string_as_str", since = "1.7.0")]
    pub fn as_str(&self) -> &str {
        self
    }
    
    使用 &*temp.to_string()&temp.to_string()。这是通过 Deref 实现的:
  2. #[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) }
        }
    }
    

这个问题取决于您在 foo 中想要做什么:传递的 &str 是否需要比 foo 存活更久?

foo(&str) 是代码中 s: &str 的最简示例:

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


@malbarbo,to_string() 返回一个 String。对于 &str,我使用 &*。我认为在这种情况下我需要 &*,但是如果有更好的方式的话,那就不需要了吧? - Angel Angel
你是对的,我在这方面有些匆忙。如果 foo 是一个方法,那么 temp.to_string().foo() 将自动解引用为 &str,但是 foo 是一个函数,所以需要使用 &*。将 usize 转换为 String 是正确的方式。 - malbarbo
我们要优化什么? - bluss
2个回答

2

正如你所注意到的,as_str 似乎没有任何作用。实际上,它返回了一个 &String,而预期的是一个 &str。这会导致编译器插入对 Deref 的调用。因此,你的两种方式完全相同。


1
要将usize转换为&str,您可以首先将其转换为String。
value.to_string().as_str()

这是最简单的方法,你提到的两种方式都使用了解引用(deref)强制转换,一种是内部自动使用,另一种是显式定义。

解引用强制转换将实现 Deref trait 的类型的引用转换为另一种类型的引用。例如,解引用强制转换可以将 &String 转换为 &str,因为 String 实现了 Deref trait,使其返回 &str。解引用强制转换是 Rust 在函数和方法的参数上自动执行的便利操作,仅适用于实现了 Deref trait 的类型。当我们将特定类型的引用作为参数传递给与函数或方法定义中的参数类型不匹配的函数或方法时,它会自动发生。一系列对 deref 方法的调用将所提供的类型转换为参数所需的类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接