Явные аннотации ссылок против значений в ржавчине - PullRequest
1 голос
/ 29 апреля 2019

Так что в Rust одна вещь, которую я озадачил, - это способность определения типа, когда дело доходит до значения по сравнению со ссылкой. Например,

fn main() {
    let s1 = String::from("h1");
    let s2 = &s1;
    println!("string is {}", s1);
} 

Средство проверки заимствований позволяет это компилировать, но я не уверен, почему? Является ли s2 здесь значением или оно выводится как ссылка на s1?

В C ++ при инициализации нового значения с помощью ссылки создается копия, если только эта переменная не была явно объявлена ​​как ссылка:

#include <string>

int main(int argc, char const* argv[]) {
    std::string s1("Hello");
    std::string& s2 = s1; // reference
    std::string s3 = s2; // copy
}

Так что в отношении ржавчины мой вопрос таков: вывод типов также применим к ситуациям со ссылками и значениями? Если да, то когда требуется явно объявлять переменные как ссылки?

1 Ответ

2 голосов
/ 30 апреля 2019

Какой у меня тип?

Тип s2 равен &std::string::String, чаще выражается просто &String.

s2 - заем s1в форме (только для чтения) ссылки (&), и будет препятствовать записи в 1011 * (если оно изменчиво), пока s2 находится в области видимости.

Как можноЯ сам определю это в будущем?

Пример кода на игровой площадке

Если вы хотите попросить компилятор раскрыть тип конкретной привязки,общая идиома - использовать let () = some_binding;.Компилятор выдаст вам ошибку, указав тип some_binding.

. Я заметил, что компилятор, похоже, «помогает», пропуская ведущий &, поэтому, когда вы освоитесь с Rust, я рекомендуюпопытка вызвать фиктивную функцию с неправильным типом, который показывает полный тип привязки.Здесь компилятор раскрывает полный тип параметра вызова, который вы можете видеть следующим образом: &String.

Явное объявление типов (с учетом комментариев OP):

Что касается явного объявления типа наlet сторона объявления, как в C ++ ( см. 'AAA' ), Rust поддерживает нечто подобное:

let a: u32 = 42;

// equvialent
let b = 42_u32;

Для созданных типов тип будет любым типомконструктор типа возвращает:

// seems somewhat redundant (since `String::new()` returns `String`) 
// but is perfectly legal
let c: String = String::new("Hello, world!");

// equivalent
let d = String::new("Hello, world!");

Так что, пока компилятор может однозначно определять тип с правой стороны, тип может быть выведен для let.

Примечание: типспецификация по-прежнему обязательна для const привязок:

// error: despite the explicit type declaration on the RHS, the type is still required
//const foo = 42_u32;

// since the type must be explicitly defined specifying again on the RHS is redundant
// (but legal):
const foo: u32 = 42_u32;

// Rustic (idiomatic) for `const`
const bar: u32 = 42;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...