簡體   English   中英

為什么使用Vec :: contains時&str不會強制轉換為&String?

[英]Why does a &str not coerce to a &String when using Vec::contains?

一位朋友讓我解釋Rust中的以下怪癖。 我無法,因此這個問題:

fn main() {
    let l: Vec<String> = Vec::new();
    //let ret = l.contains(&String::from(func())); // works
    let ret = l.contains(func());  // does not work
    println!("ret: {}", ret);
}

fn func() -> & 'static str {
    "hello"
}

Rust Playground上的示例

編譯器會這樣抱怨:

error[E0308]: mismatched types
 --> src/main.rs:4:26
  |
4 |     let ret = l.contains(func());  // does not work
  |                          ^^^^^^ expected struct `std::string::String`, found str
  |
  = note: expected type `&std::string::String`
             found type `&'static str`

換句話說, &str不會強制使用&String

起初我認為這與'static ,然而這是一個紅色的鯡魚。

注釋行以額外分配為代價修復了示例。

我的問題:

  • 為什么&str強制使用&String
  • 有沒有辦法讓調用contains工作而沒有額外的分配?

你的第一個問題應該由@Marko回答。

你的第二個問題也應該很容易回答,只需使用一個閉包:

let ret = l.iter().any(|x| x == func());

編輯:

不再是“真正的”答案,但我在這里為那些可能對此解決方案感興趣的人提供了這個答案。

std::string::String是一個可增長的堆分配數據結構,而字符串slice( str )是內存中某個不可變的固定長度字符串。 字符串切片用作借用類型,通過&str 將其視為駐留在內存中某處的字符串日期的視圖。 這就是為什么它沒有意義的str要挾到String ,而周圍的其他方法完全是有道理的。 您在內存中的某處有一個堆分配的String ,並且您希望使用該字符串的視圖(字符串切片)。

回答你的第二個問題。 無法使代碼在當前表單中工作。 您需要更改為字符串切片的向量(這樣,將不會有額外的分配)或使用其他contains方法的其他contains

似乎Rust開發人員打算調整contains的簽名,以允許上面發布的示例工作

從某種意義上說,這是contains的已知錯誤。 聽起來修復程序不允許這些類型強制執行,但允許上面的示例工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM