Как принять &str, String и &String в одной функции?

Я хочу написать одну функцию, которая принимает &str, String и заимствованный &String. Я написал следующие 2 функции:

fn accept_str_and_ref_string(value: &str) {
    println!("value: {}", value);
}

fn accept_str_and_string<S: Into<String>>(value: S) {
    let string_value: String = value.into();
    println!("string_value: {}", string_value);
}

fn main() {
    let str_foo = "foo";
    let string_foo = String::from("foo");

    accept_str_and_ref_string(str_foo);
    accept_str_and_ref_string(&string_foo);

    accept_str_and_string(str_foo);
    accept_str_and_string(string_foo);
}

Можно ли реализовать одну функцию, чтобы я мог это сделать:

accept_all_strings(str_foo);
accept_all_strings(&string_foo);
accept_all_strings(string_foo);

Похоже, начиная с Rust 1.35.0 вариант Into<String> также работает для &String.

Matthias 07.07.2019 19:57

Да, вы правы, я протестировал его с текущей версией Rust 1.36.

Ringo Leese 08.07.2019 19:36
В чем разница между методом "==" и equals()
В чем разница между методом "==" и equals()
Это один из наиболее часто задаваемых вопросов новичкам на собеседовании. Давайте обсудим его на примере.
Замена символа по определенному индексу в JavaScript
Замена символа по определенному индексу в JavaScript
В JavaScript существует несколько способов заменить символ в строке по определенному индексу.
26
2
5 643
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать трейт AsRef<str>:

// will accept any object that implements AsRef<str>
fn print<S: AsRef<str>>(stringlike: S) {
    // call as_ref() to get a &str
    let str_ref = stringlike.as_ref();

    println!("got: {:?}", str_ref)
}

fn main() {
    let a: &str = "str";
    let b: String = String::from("String");
    let c: &String = &b;

    print(a);
    print(c);
    print(b);
}

Функция print будет поддерживать любой тип, реализующий AsRef<str>, включая &str, String и &String.

@trentcl A String не будет скопирован, право собственности на него будет передано методу, если вы не используете ссылку.

Frxstrem 09.03.2019 17:05

Моя ошибка, мой мозг смешал тело примера ОП с вашей подписью.

trent 09.03.2019 17:32

Что, если функции в конечном итоге потребуется собственная строка, а не ссылка?

malthe 30.12.2019 11:06

@malthe Лично я обычно просто использую stringlike.as_ref().to_string(), так как мне нравится иметь одну и ту же подпись независимо от того, нужна ли мне собственная или заимствованная строка. Я думаю, что это может быть немного неэффективно с аргументами, которые уже принадлежат строкам, поэтому, если вы хотите избежать этого, вы можете использовать другие черты, такие как S: Into<String>.

Frxstrem 30.12.2019 14:23

Другие вопросы по теме