По сути, типы ссылок в некотором смысле лгут мне, поскольку они на самом деле не делают то, что утверждают, что делают. Как мне правильно читать типы ссылок в этом случае или как еще я могу восстановить веру в эту концепцию?
Правильный способ чтения ссылок в Rust - это разрешения.
Право собственности на объект, если оно не заимствовано, дает вам разрешение делать с объектом все, что вы хотите; создать его, уничтожить его, переместить его из одного места в другое. Вы владелец, вы можете делать то, что хотите, вы контролируете жизнь этого объекта.
Изменяемая ссылка заимствует объект у владельца. Пока изменяемая ссылка жива, она предоставляет монопольный доступ к объекту. Никто не может читать, писать или делать что-либо еще с объектом. Изменяемая ссылка также может быть вызовом и эксклюзивной ссылкой или эксклюзивным заимствованием. Вы должны вернуть контроль над объектом первоначальному владельцу, но тем временем вы можете делать с ним все, что захотите.
Неизменная ссылка или общий заем означает, что вы получаете доступ к ней одновременно с другими. Из-за этого вы можете только прочитать его, и никто не может изменить его, иначе будут неопределенные результаты, основанные на точном порядке, в котором произошли действия.
Как изменяемые (или исключительные) ссылки, так и неизменяемые (или общие) ссылки могут быть сделаны для принадлежащих объектов, но это не означает, что вы владеете объектом, когда ссылаетесь на него через ссылку. То, что вы можете делать с объектом, зависит от того, через какую ссылку вы к нему обращаетесь.
Так что не думайте о ссылке &&mut T
как о «неизменной ссылке на изменяющуюся ссылку на T», а затем подумайте: «Ну, я не могу изменить внешнюю ссылку, но я должен иметь возможность изменять мутацию внутренняя ссылка. "
Вместо этого думайте об этом как о "Кто-то владеет T
. Они предоставили эксклюзивный доступ, поэтому прямо сейчас есть кто-то, кто имеет право изменять T
. Но в то же время, этот человек дал общий доступ к &mut T
, что означает, что они обещали не изменять его в течение определенного периода времени, и все пользователи могут использовать общую ссылку на &mut T
, включая разыменование базового T
, но только для вещей, которые вы обычно можете делать с общей ссылкой, что означает чтение, но не запись. "
Последнее, что нужно иметь в виду, это то, что изменяемая или неизменяемая часть не является принципиальной разницей между ссылками. Это действительно эксклюзивная и общая часть. В Rust вы можете изменить что-то с помощью общей ссылки, если есть какой-то механизм внутренней защиты, который гарантирует, что только один человек может сделать это одновременно. Есть несколько способов сделать это, например, Cell
, RefCell
или Mutex
.
То, что предоставляют &T
и &mut T
, на самом деле не является неизменным или изменяемым доступом, хотя они названы так, потому что это уровень доступа по умолчанию, который они предоставляют на уровне языка при отсутствии каких-либо библиотечных функций. Но на самом деле они предоставляют общий или монопольный доступ, и тогда методы для типов данных могут предоставлять вызывающим функции различные функции в зависимости от того, принимают ли они собственное значение, монопольную ссылку или общую ссылку.
Так что думайте о ссылках как о разрешениях; и именно ссылка, через которую вы достигаете чего-либо, определяет, что вам разрешено делать с этим. А когда у вас есть право собственности или исключительная ссылка, выдача исключительной или совместно используемой ссылки временно лишает вас возможности доступа к объекту, пока эти заимствованные ссылки еще живы.