Referencias
Move tiene dos tipos de referencias: inmutables &
y mutables &mut
. Las referencias inmutables son de solo lectura y no pueden modificar el valor subyacente (ni ninguno de sus campos). Las referencias mutables permiten modificaciones mediante una escritura a través de esa referencia. El sistema de tipos de Move impone una disciplina de propiedad que evita errores de referencia.
Para obtener más detalles sobre las reglas de referencia, consulte Estructuras y recursos.
Operadores de referencia
Move proporciona operadores para crear y ampliar referencias, así como para convertir una referencia mutable en una inmutable. Aquí y en otros lugares utilizamos la notación e: T
para "la expresión e
tiene tipo T
".
Sintaxis | Tipo | Descripción |
|
| Crear una referencia inmutable a |
|
| Cree una referencia mutable a |
|
| Cree una referencia inmutable al campo |
|
| Cree una referencia mutable al campo |
|
| Convierta la referencia mutable |
Los operadores &e.f
y &mut e.f
se pueden utilizar tanto para crear una nueva referencia en una estructura como para ampliar una referencia existente:
Copiar
Una expresión de referencia con múltiples campos funciona siempre que ambas estructuras estén en el mismo módulo:
Copiar
Finalmente, tenga en cuenta que no se permiten referencias a referencias:
Copiar
Lectura y escritura a través de referencias
Se pueden leer referencias mutables e inmutables para producir una copia del valor al que se hace referencia.
Sólo se pueden escribir referencias mutables. Una escritura *x = v
descarta el valor previamente almacenado x
y lo actualiza con v
.
Ambas operaciones utilizan la *
sintaxis similar a C. Sin embargo, tenga en cuenta que una lectura es una expresión, mientras que una escritura es una mutación que debe ocurrir en el lado izquierdo de un igual.
Sintaxis | Tipo | Descripción |
|
| Lea el valor señalado por |
|
| Actualice el valor |
Para que se pueda leer una referencia, el tipo subyacente debe tener la copy
capacidad de leer la referencia para crear una nueva copia del valor. Esta regla impide la copia de valores de recursos:
Copiar
Doblemente: para poder escribir en una referencia, el tipo subyacente debe tener la drop
capacidad, ya que escribir en la referencia descartará (o "eliminará") el valor anterior. Esta regla evita la destrucción de valores de recursos:
Copiar
freeze
inferencia
freeze
inferenciaSe puede utilizar una referencia mutable en un contexto donde se espera una referencia inmutable:
Copiar
Esto funciona porque, bajo el capó, el compilador inserta freeze
instrucciones donde son necesarias. Aquí hay algunos ejemplos más de freeze
inferencia en acción:
Copiar
Subtipificación
Con esta freeze
inferencia, el verificador de tipo de movimiento puede verse &mut T
como un subtipo de &T
. Como se muestra arriba, esto significa que en cualquier lugar para cualquier expresión donde &T
se use un valor, &mut T
también se puede usar un valor. Esta terminología se utiliza en mensajes de error para indicar de forma concisa que &mut T
se necesitaba un elemento donde &T
se proporcionó un. Por ejemplo
Copiar
producirá los siguientes mensajes de error
Copiar
Los únicos otros tipos actualmente que tienen subtipos son las tuplas.
Propiedad
Tanto las referencias mutables como las inmutables siempre se pueden copiar y ampliar incluso si existen copias o extensiones de la misma referencia :
Copiar
Esto podría resultar sorprendente para los programadores familiarizados con el sistema de propiedad de Rust, que rechazarían el código anterior. El sistema de tipos de Move es más permisivo en el tratamiento de las copias, pero igualmente estricto a la hora de garantizar la propiedad única de las referencias mutables antes de la escritura.
Las referencias no se pueden almacenar
Las referencias y las tuplas son los únicos tipos que no se pueden almacenar como valores de campo de estructuras, lo que también significa que no pueden existir en el almacenamiento global. Todas las referencias creadas durante la ejecución del programa se destruirán cuando finalice un programa Move; son enteramente efímeros. Esta invariante también es válida para valores de tipos sin la store
capacidad, pero tenga en cuenta que las referencias y las tuplas van un paso más allá al no permitirse nunca en las estructuras en primer lugar.
Esta es otra diferencia entre Move y Rust, que permite almacenar referencias dentro de estructuras.
Actualmente, Move no puede admitir esto porque las referencias no se pueden serializar , pero cada valor de Move debe ser serializable . Este requisito proviene del almacenamiento global persistente de Move, que necesita serializar valores para conservarlos en las ejecuciones del programa. Las estructuras se pueden escribir en el almacenamiento global y, por lo tanto, deben ser serializables.
Uno podría imaginar un sistema de tipos más sofisticado y expresivo que permitiría almacenar referencias en estructuras y prohibiría que esas estructuras existan en el almacenamiento global. Quizás podríamos permitir referencias dentro de estructuras que no tienen la store
capacidad, pero eso no resolvería completamente el problema: Move tiene un sistema bastante complejo para rastrear la seguridad de las referencias estáticas, y este aspecto del sistema de tipos también tendría que extenderse a admite el almacenamiento de referencias dentro de estructuras. En resumen, el sistema de tipos de Move (particularmente los aspectos relacionados con la seguridad de las referencias) tendría que expandirse para admitir referencias almacenadas. Pero es algo a lo que estamos atentos a medida que evoluciona el lenguaje.
Last updated