2013-09-22 4 views
3

Чтение rust tutorial управляемых и принадлежащих указателей можно передать функции, требующей заимствованных указателей as-is, и преобразуются в заимствованные указатели во время компиляции.Синтаксис Rust "Заимствованные указатели"

Почему переменная стека не может быть передана таким же образом? Какой синтаксис или функция требует, чтобы явный оператор & передал это, в отличие от компилятора, автоматически преобразующего его?

struct Point {x: float, y: float} 

let on_the_stack : Point = Point {x: 3.0, y: 4.0}; 
let managed_box : @Point = @Point {x: 5.0, y: 1.0}; 
let owned_box : ~Point = ~Point {x: 7.0, y: 9.0}; 

fn compute_distance(p1: &Point, p2: &Point) -> float { 
    let x_d = p1.x - p2.x; 
    let y_d = p1.y - p2.y; 
    sqrt(x_d * x_d + y_d * y_d) 
} 

compute_distance(&on_the_stack, managed_box); 
compute_distance(managed_box, owned_box); 

Добавление к путанице цитата из kibwen на ycombinator (я не могу найти оригинальную цитату, но вот цитата цитаты)

Мы еще & и & MUT , но это не указатели, они ссылки (это наша собственная вина для вызова их «заимствованные указатели» в нашей документации)

Если compute_distance принимает ссылки и ком piler автоматически преобразует указатели в ссылки, почему он не может делать то же самое для значений?

Редактировать: Поскольку pnkfelix, похоже, знает, о чем идет речь, я скопирую здесь какой-нибудь диалог для упрощения чтения.

pnkfelix

Проектировщики Руст решил не следовать по пути С ++ в этом отношении. Одним из побочных эффектов этого решения является то, что, когда кто-то читает код, он обращается к вызову, подобному f (x, y) в Rust, не нужно тратить время на размышления «подождите, как f принимает свои аргументы, если он мутирует y, Я вижу, что это отразилось на том, что после возвращения f? Что относительно х? и т.д.

J V

Я могут быть спутаны от природы ссылок затем. @var и ~var в ржавчине - указатели (хотя они ведут себя скорее как ссылки) - являются ли ссылки на C++ просто указателями под капотом?

В любом случае, я мог бы применить ту же логику к C в отношении читаемости кода.

Переменные - это либо значения, либо указатели (где вы просто передаете переменную так же, как и в ржавчине: f(var)) или ссылаются на вызов функции (например, вы делаете в ржавчине: f(&var)) - Я бы подумал, что компилятор ржавчины распознавать подпись функции и обрабатывать ее автоматически. Я не вижу улучшение по сравнению с C или С ++

pnkfelix

Один период наблюдения: эта линия, что я писал: «ждать, как же е принимает свои аргументы, если он мутирует у, я буду см., что отражено в том, что после возвращения f? Что относительно x? " является несколько увлекательным, поскольку даже вызов типа f (& x, y) не сможет изменить x; это должно быть f (& mut x, y). (и объявление самого x должно быть разрешено mut x = ... и т. д.- pnkfelix 1 час назад

второй период наблюдения: причина, почему явные & х может быть более важным в Русте, чем в C/C++ (вместо того, чтобы Р (х, у) неявно сделать заимствуют & х), потому, что заимствовать средства проверки, заставляет следовать определенным правилам и откажется от компиляции кода, который не соответствует. Когда вы получаете ошибку от заемщика, IMO, это лучший пользовательский опыт, если компилятор указывает на выражение формы & x или & мута x в источнике, вместо того, чтобы указывать на вызов функции и говорить «есть здесь подразумевается заимствование ». (Это субъективное мнение, конечно.) - pnkfelix 1 час назад

Я видел, что в вашем ответе у вас была заметка о последующих действиях, но я не понимаю, что вы делаете о применении «той же логики к C». Если вы имеете в виду C, а не C++, вам обычно приходится явно принимать адреса памяти при вызове функций, которые ожидают указатели. Если функция принимает int**, то кому-то нужно сделать &E, где E является l-значением типа int*. Это кажется мне похожим на Rust. (Главное исключение к этому, что я помню навскидку из C является функция-указатели, вам не нужно делать &f, чтобы указатель на функцию f.) - pnkfelix 1 час назад

СП

Это похоже на ржавчину для меня. - точно моя точка зрения - с точки зрения удобочитаемости нет ничего лучше по сравнению с обычным C. , потому что средство проверки займа заставляет следить за определенными правилами ... скорее, указывая на вызов функции и говоря: «есть неявный заимствование Вот." Бинго - это одна из основных причин, которые я искал. Если вы найдете какие-либо другие причины для ручной подачи, не стесняйтесь добавить свой ответ!

ответ

3

Я думаю, что цель состоит в том, чтобы дать понять читателю, когда делается копия структуры по сравнению с передачей ссылки на существующую структуру. (подробнее об этом ниже.)

Управляемый ящик и собственная ящик в приведенном примере уже являются ссылками; они просто временно преобразуются из одного вида ссылок (@Point и ~Point соответственно) в &Point ссылок. Но они оба являются ссылками, тем не менее, и копия ссылочного хранилища не производится.


Это вполне может быть так, что компилятор Rust может делать вывод, на основе типа подписи вызываемой функции, если ссылка должна быть создана в сравнении, когда структура должна быть скопирована.

в самом деле, это именно то, что компилятор C++ делает, когда он видит звонок как f(x, y): он должен смотреть на подпись f, таких как f(A &a, B b), и из этого определения: «Хорошо, я сделаю ссылку на аргумент x (предположим, что он имеет тип A) и сделать копию аргумента y (при условии, что он имеет тип B), поскольку он передается по значению. "

Дизайнеры Rust решили не следовать по пути C++ в этом отношении.Одним из побочных эффектов этого решения является то, что, когда кто-то читает код, он обращается к вызову вроде f(x, y) в Rust, не нужно тратить время на то, чтобы «ждать», как f принимает свои аргументы, если он мутирует y, увижу ли это, что отражено в что после возврата f? Как насчет x? " и т.д.

  • (Конечно, все еще нужно рассуждать о памяти достижимы от x и y через любые изменяемые или принадлежащие ссылки они сами держат ... но я отвлекся.)
+0

я могу затем путайте с характером ссылок. '@ var' и' ~ var' в ржавчине - указатели (хотя они ведут себя скорее как ссылки) - являются ли ссылки на C++ просто указателями под капотом? В любом случае, я мог бы применить одну и ту же логику к C в отношении удобочитаемости кода. Переменные - это значения или указатели (где вы просто передаете переменную так же, как и в ржавчине: 'f (var)') или ссылаетесь на вызов функции (например, вы делаете в ржавчине: 'f (& var)') - I подумал бы, что компилятор ржавчины распознает подпись функции и обрабатывает ее автоматически. Я не вижу улучшения по сравнению с C или C++ –

+0

Одно из следующих действий: эта строка, которую я написал: «подождите, как f принимает свои аргументы, если она мутирует y, я увижу, что это отражено в том, что после возвращения f? ?» несколько ожесточен, так как даже вызов типа 'f (& x, y)' не сможет изменить 'x'; это должно быть «f (& mut x, y)». (и объявление самого 'x' должно быть« let mut x = ... »и т. д. – pnkfelix

+0

2-е последующее: причина, по которой явное' & x' может быть более важным в Rust, чем в C/C++ (а не позволяя 'f (x, y)' неявно выполнять заимствование '& x'), заключается в том, что средство проверки заимствований заставляет следить за определенными правилами и откажется от компиляции кода, который не соответствует. Когда вы получаете сообщение об ошибке, checker, IMO, это лучший пользовательский опыт, если компилятор указывает на выражение формы '& x' или' & mut x' в источнике, вместо того, чтобы указывать на вызов функции и говорить «здесь подразумевается заимствование». (Это, конечно, субъективное мнение.) – pnkfelix

Смежные вопросы