/elpr

Primary LanguageHTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="generator" content="rustdoc">
    <title>El Lenguaje de Programación Rust</title>

    <link rel="stylesheet" type="text/css" href="rustbook.css">

    
</head>
<body class="rustdoc">
    <!--[if lte IE 8]>
    <div class="warning">
        This old browser is unsupported and will most likely display funky
        things.
    </div>
    <![endif]-->

    
                <div id="nav">
                    <button id="toggle-nav">
                        <span class="sr-only">Toggle navigation</span>
                        <span class="bar"></span>
                        <span class="bar"></span>
                        <span class="bar"></span>
                    </button>
                </div>
<div id='toc' class='mobile-hidden'>
<ul class='chapter'>
<li><a class='active' href='README.html'><b>1.</b> Introduction</a>
</li>
<li><a  href='getting-started.html'><b>2.</b> Primeros Pasos</a>
<ul class='section'>
<li><a  href='installing-rust.html'><b>2.1.</b> Instalando Rust</a>
</li>
<li><a  href='hello-world.html'><b>2.2.</b> ¡Hola, mundo!</a>
</li>
<li><a  href='hello-cargo.html'><b>2.3.</b> ¡Hola, Cargo!</a>
</li>
</ul>
</li>
<li><a  href='learn-rust.html'><b>3.</b> Aprende Rust</a>
<ul class='section'>
<li><a  href='guessing-game.html'><b>3.1.</b> El Juego de las Adivinanzas</a>
</li>
<li><a  href='dining-philosophers.html'><b>3.2.</b> La Cena de los Filósofos</a>
</li>
<li><a  href='rust-inside-other-languages.html'><b>3.3.</b> Rust dentro de otros Lenguajes</a>
</li>
</ul>
</li>
<li><a  href='effective-rust.html'><b>4.</b> Rust Efectivo</a>
<ul class='section'>
<li><a  href='the-stack-and-the-heap.html'><b>4.1.</b> La Pila y el Montículo</a>
</li>
<li><a  href='testing.html'><b>4.2.</b> Pruebas</a>
</li>
<li><a  href='conditional-compilation.html'><b>4.3.</b> Compilación Condicional</a>
</li>
<li><a  href='documentation.html'><b>4.4.</b> Documentación</a>
</li>
<li><a  href='iterators.html'><b>4.5.</b> Iteradores</a>
</li>
<li><a  href='concurrency.html'><b>4.6.</b> Concurrencia</a>
</li>
<li><a  href='error-handling.html'><b>4.7.</b> Manejo de Errores</a>
</li>
<li><a  href='ffi.html'><b>4.8.</b> FFI</a>
</li>
<li><a  href='borrow-and-asref.html'><b>4.9.</b> Borrow y AsRef</a>
</li>
<li><a  href='release-channels.html'><b>4.10.</b> Canales de Distribución</a>
</li>
</ul>
</li>
<li><a  href='syntax-and-semantics.html'><b>5.</b> Sintaxis y Semantica</a>
<ul class='section'>
<li><a  href='variable-bindings.html'><b>5.1.</b> Enlaces a Variables</a>
</li>
<li><a  href='functions.html'><b>5.2.</b> Funciones</a>
</li>
<li><a  href='primitive-types.html'><b>5.3.</b> Tipos Primitivos</a>
</li>
<li><a  href='comments.html'><b>5.4.</b> Comentarios</a>
</li>
<li><a  href='if.html'><b>5.5.</b> if</a>
</li>
<li><a  href='loops.html'><b>5.6.</b> Ciclos</a>
</li>
<li><a  href='ownership.html'><b>5.7.</b> Pertenencia</a>
</li>
<li><a  href='references-and-borrowing.html'><b>5.8.</b> Referencias y Préstamo</a>
</li>
<li><a  href='lifetimes.html'><b>5.9.</b> Tiempos de Vida</a>
</li>
<li><a  href='mutability.html'><b>5.10.</b> Mutabilidad</a>
</li>
<li><a  href='structs.html'><b>5.11.</b> Estructuras</a>
</li>
<li><a  href='enums.html'><b>5.12.</b> Enumeraciones</a>
</li>
<li><a  href='match.html'><b>5.13.</b> Match</a>
</li>
<li><a  href='patterns.html'><b>5.14.</b> Patrones</a>
</li>
<li><a  href='method-syntax.html'><b>5.15.</b> Sintaxis de Métodos</a>
</li>
<li><a  href='vectors.html'><b>5.16.</b> Vectores</a>
</li>
<li><a  href='strings.html'><b>5.17.</b> Cadenas de Caracteres</a>
</li>
<li><a  href='generics.html'><b>5.18.</b> Genéricos</a>
</li>
<li><a  href='traits.html'><b>5.19.</b> Traits</a>
</li>
<li><a  href='drop.html'><b>5.20.</b> Drop</a>
</li>
<li><a  href='if-let.html'><b>5.21.</b> if let</a>
</li>
<li><a  href='trait-objects.html'><b>5.22.</b> Objetos Trait</a>
</li>
<li><a  href='closures.html'><b>5.23.</b> Closures</a>
</li>
<li><a  href='ufcs.html'><b>5.24.</b> Sintaxis Universal  de Llamada a Funciones</a>
</li>
<li><a  href='crates-and-modules.html'><b>5.25.</b> Crates y Módulos</a>
</li>
<li><a  href='const-and-static.html'><b>5.26.</b> `const` y `static`</a>
</li>
<li><a  href='attributes.html'><b>5.27.</b> Atributos</a>
</li>
<li><a  href='type-aliases.html'><b>5.28.</b> Alias `type`</a>
</li>
<li><a  href='casting-between-types.html'><b>5.29.</b> Conversión entre Tipos</a>
</li>
<li><a  href='associated-types.html'><b>5.30.</b> Tipos Asociados</a>
</li>
<li><a  href='unsized-types.html'><b>5.31.</b> Tipos sin Tamaño</a>
</li>
<li><a  href='operators-and-overloading.html'><b>5.32.</b> Operadores y Sobrecarga</a>
</li>
<li><a  href='deref-coercions.html'><b>5.33.</b> Coerciones Deref</a>
</li>
<li><a  href='macros.html'><b>5.34.</b> Macros</a>
</li>
<li><a  href='raw-pointers.html'><b>5.35.</b> Apuntadores Planos</a>
</li>
<li><a  href='unsafe.html'><b>5.36.</b> `unsafe`</a>
</li>
</ul>
</li>
<li><a  href='nightly-rust.html'><b>6.</b> Rust Nocturno</a>
<ul class='section'>
<li><a  href='compiler-plugins.html'><b>6.1.</b> Plugins del Compilador</a>
</li>
<li><a  href='inline-assembly.html'><b>6.2.</b> Ensamblador en Linea</a>
</li>
<li><a  href='no-stdlib.html'><b>6.3.</b> No stdlib</a>
</li>
<li><a  href='intrinsics.html'><b>6.4.</b> Intrínsecos</a>
</li>
<li><a  href='lang-items.html'><b>6.5.</b> Items de Lenguaje</a>
</li>
<li><a  href='advanced-linking.html'><b>6.6.</b> Enlace Avanzado</a>
</li>
<li><a  href='benchmark-tests.html'><b>6.7.</b> Pruebas de Rendimiento</a>
</li>
<li><a  href='box-syntax-and-patterns.html'><b>6.8.</b> Sintaxis Box y Patrones</a>
</li>
<li><a  href='slice-patterns.html'><b>6.9.</b> Patrones Slice</a>
</li>
<li><a  href='associated-constants.html'><b>6.10.</b> Constantes Asociadas</a>
</li>
<li><a  href='custom-allocators.html'><b>6.11.</b> Asignadores de Memoria Personalizados</a>
</li>
</ul>
</li>
<li><a  href='glossary.html'><b>7.</b> Glosario</a>
</li>
<li><a  href='bibliography.html'><b>8.</b> Bibliografia</a>
</li>
</ul>
</div>
<div id='page-wrapper'>
<div id='page'>


    <h1 class="title">El Lenguaje de Programación Rust</h1>
    <p>¡Bienvenido! Este libro te enseñará acerca del <a href="http://rust-lang.org">Lenguaje de Programación Rust</a>.
Rust es un lenguaje de programación de sistemas enfocado en tres objetivos: seguridad, velocidad y concurrencia. Rust logra estos objetivos sin tener un recolector de basura, haciendolo util para un numero de casos de uso para los cuales otros lenguajes no son tan buenos: embeber en otros lenguajes, programas con requerimientos específicos de tiempo y espacio, escritura de código de bajo nivel, como controladores de dispositivo y sistemas operativos. Rust mejora por sobre los lenguajes actuales en este nicho a través de un numero de chequeos en tiempo de compilación que no incurren ninguna penalidad en tiempo de ejecución, eliminando al mismo tiempo las condiciones de carrera. Rust también implementa &#39;abstracciones con cero costo&#39;, abstracciones que se sienten como las de un lenguaje de alto nivel. Aun así, Rust permite control preciso tal y como un lenguaje de bajo nivel lo haria.</p>

<p>“El Lenguaje de Programación Rust” esta dividido en siete secciones. Esta introducción es la primera. Después de esta:</p>

<ul>
<li><a href="getting-started.html">Primeros Pasos</a> - Configura tu maquina para el desarrollo en Rust.</li>
<li><a href="learn-rust.html">Aprende Rust</a> - Aprende programación en Rust a través de pequeños proyectos.</li>
<li><a href="effective-rust.html">Rust Efectivo</a> - Conceptos de alto nivel para escribir excelente código Rust.</li>
<li><a href="syntax-and-semantics.html">Sintaxis y Semántica</a> - Cada pieza de Rust, dividida en pequenos pedazos.</li>
<li><a href="nightly-rust.html">Rust Nocturno</a> - Características todavía no disponibles en builds estables.</li>
<li><a href="glossary.html">Glosario</a> - Referencia de los términos usados en el libro.</li>
<li><a href="academic-research.html">Investigación Académica</a> - Literatura que influencio Rust.</li>
</ul>

<p>Después de leer esta introducción, dependiendo de tu preferencia, querrás leer ‘Aprende Rust’ o ‘Sintaxis y Semántica’: ‘Aprende Rust’ si quieres comenzar con un proyecto o ‘Sintaxis y Semántica’, si prefieres comenzar por lo más pequeño aprendiendo un único concepto detalladamente antes de moverte al siguiente. Abundantes enlaces cruzados conectan dichas partes.</p>

<h3 id='contribuyendo' class='section-header'><a href='#contribuyendo'>Contribuyendo</a></h3>
<p>Los archivos fuente de los cuales este libro es generado pueden ser encontrados en Github:
<a href="https://github.com/goyox86/elpr-sources">github.com/goyox86/elpr-sources</a></p>

<h2 id='una-breve-introducción-a-rust' class='section-header'><a href='#una-breve-introducción-a-rust'>Una breve introducción a Rust</a></h2>
<p>¿Es Rust un lenguaje en el cual estarías interesado? Examinemos unos pequeños ejemplos de código que demuestran algunas de sus fortalezas.</p>

<p>El concepto principal que hace único a Rust es llamado ‘pertenencia’ (‘ownership’). Considera este pequeño ejemplo:</p>
<span class='rusttest'>fn main() {
    let mut x = vec![&quot;Hola&quot;, &quot;mundo&quot;];
}
</span><pre class='rust rust-example-rendered'>
<span class='kw'>fn</span> <span class='ident'>main</span>() {
    <span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>x</span> <span class='op'>=</span> <span class='macro'>vec</span><span class='macro'>!</span>[<span class='string'>&quot;Hola&quot;</span>, <span class='string'>&quot;mundo&quot;</span>];
}</pre>

<p>Este programa crea un una <a href="variable-bindings.html">variable</a> llamada <code>x</code>.El valor de esta variable es <code>Vec&lt;T&gt;</code>, un ‘vector’, que creamos a través de una <a href="macros.html">macro</a> definida en la biblioteca estandar. Esta macro se llama <code>vec</code>, las macros son invocadas con un <code>!</code>. Todo esto siguiendo un principio general en Rust: hacer las cosas explícitas. Las macros pueden hacer cosas significativamente más complejas que llamadas a funciones, es por ello que son visualmente distintas. El <code>!</code> ayuda también al análisis sintáctico, haciendo la escritura de herramientas más fácil, lo cual es también importante.</p>

<p>Hemos usado <code>mut</code> para hacer <code>x</code> mutable: En Rust las variables son inmutables por defecto. Más tarde en este ejemplo estaremos mutando este vector.</p>

<p>Es importate mencionar que no necesitamos una anotación de tipos aquí: si bien Rust es estaticamente tipado, no necesitamos anotar el tipo de forma explicita. Rust posee inferencia de tipos para balancear el poder de el tipado estático con la verbosidad de las anotaciones de tipos.</p>

<p>Rust prefiere asignación de memoria desde la pila que desde el montículo: <code>x</code> es puesto directamente en la pila. Sin embargo, el tipo <code>Vec&lt;T&gt;</code> asigna espacio para los elementos del vector en el montículo. Si no estas familiarizado con esta distinción puedes ignorarla por ahora o echar un vistazo <a href="the-stack-and-the-heap.html">‘La Pila y el Monticulo’</a>. Rust como un lenguaje de programación de sistemas, te da la habilidad de controlar como la memoria es asignada, pero como estamos comenzando no es tan relevante.</p>

<p>Anteriormente mencionamos que la ‘pertenencia’ es nuevo concepto clave en Rust. En terminología Rust, <code>x</code> es el ‘dueño’ del vector. Esto significa que cuando <code>x</code> salga de ámbito, la memoria asignada a el vector sera liberada. Esto es hecho por el compilador de Rust de manera deterministica, sin la necesidad de un mecanismo como un recolector de basura. En otras palabras, en Rust, no haces llamadas a funciones como <code>malloc</code> y <code>free</code> explícitamente: el compilador determina de manera estática cuando se necesita asignar o liberar memoria, e inserta esas llamadas por ti. Errar es de humanos, pero los compiladores nunca olvidan.</p>

<p>Agreguemos otra línea a nuestro ejemplo:</p>
<span class='rusttest'>fn main() {
    let mut x = vec![&quot;Hola&quot;, &quot;mundo&quot;];

    let y = &amp;x[0];
}
</span><pre class='rust rust-example-rendered'>
<span class='kw'>fn</span> <span class='ident'>main</span>() {
    <span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>x</span> <span class='op'>=</span> <span class='macro'>vec</span><span class='macro'>!</span>[<span class='string'>&quot;Hola&quot;</span>, <span class='string'>&quot;mundo&quot;</span>];

    <span class='kw'>let</span> <span class='ident'>y</span> <span class='op'>=</span> <span class='kw-2'>&amp;</span><span class='ident'>x</span>[<span class='number'>0</span>];
}</pre>

<p>Hemos introducido otra variable, <code>y</code>. En este caso, <code>y</code> es una ‘referencia’ a el primer elemento de el vector. Las referencias en Rust son similares a los apuntadores en otros lenguajes, pero con chequeos de seguridad adicionales en tiempo de compilación. Las referencias interactuan con el sistema de pertenencia a través de el <a href="references-and-borrowing.html">‘prestamo’</a> (‘borrowing’), ellas toman prestado a lo que apuntan, en vez de adueñarse de ello. La diferencia es que cuando la referencia salga de ámbito, la memoria subyacente no sera liberada. De ser ese el caso estaríamos liberando la misma memoria dos veces, lo cual es malo.</p>

<p>Agreguemos una tercera línea. Dicha línea luce inocente pero causa un error de compilación:</p>
<span class='rusttest'>fn main() {
    let mut x = vec![&quot;Hola&quot;, &quot;mundo&quot;];

    let y = &amp;x[0];

    x.push(&quot;foo&quot;);
}
</span><pre class='rust rust-example-rendered'>
<span class='kw'>fn</span> <span class='ident'>main</span>() {
    <span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>x</span> <span class='op'>=</span> <span class='macro'>vec</span><span class='macro'>!</span>[<span class='string'>&quot;Hola&quot;</span>, <span class='string'>&quot;mundo&quot;</span>];

    <span class='kw'>let</span> <span class='ident'>y</span> <span class='op'>=</span> <span class='kw-2'>&amp;</span><span class='ident'>x</span>[<span class='number'>0</span>];

    <span class='ident'>x</span>.<span class='ident'>push</span>(<span class='string'>&quot;foo&quot;</span>);
}</pre>

<p><code>push</code> es un metodo en los vectores que agrega un elemento al final del vector. Cuando tratamos de compilar el programa obtenemos un error:</p>

<pre><code class="language-text">error: cannot borrow `x` as mutable because it is also borrowed as immutable
    x.push(&quot;foo&quot;);
    ^
note: previous borrow of `x` occurs here; the immutable borrow prevents
subsequent moves or mutable borrows of `x` until the borrow ends
    let y = &amp;x[0];
             ^
note: previous borrow ends here
fn main() {

}
^
</code></pre>

<p>¡Uff! El compilador de Rust algunas veces puede proporcionar errores bien detallados y esta vez una de ellas. Como el error lo explica, mientras hacemos la variable mutable no podemos llamar a <code>push</code>. Esto es porque ya tenemos una referencia a un elemento del vector, <code>y</code>. Mutar algo mientras existe una referencia a ello es peligroso, porque podemos invalidar la referencia. En este caso en especifico, cuando creamos el vector, solo hemos asignado espacio para dos elementos. Agregar un tercero significaría asignar un nuevo segmento de memoria para todos los elementos, copiar todos los valores anteriores y actualizar el apuntador interno a esa memoria. Todo eso esta bien. El problema es que <code>y</code> no seria actualizado, generando un ‘puntero colgante’. Lo cual esta mal. Cualquier uso de <code>y</code> seria un error en este caso, y el compilador nos ha prevenido de ello.</p>

<p>Entonces, ¿cómo resolvemos este problema? Hay dos enfoques que podríamos tomar. El primero es hacer una copia en lugar de una referencia:</p>
<span class='rusttest'>fn main() {
    let mut x = vec![&quot;Hola&quot;, &quot;mundo&quot;];

    let y = x[0].clone();

    x.push(&quot;foo&quot;);
}
</span><pre class='rust rust-example-rendered'>
<span class='kw'>fn</span> <span class='ident'>main</span>() {
    <span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>x</span> <span class='op'>=</span> <span class='macro'>vec</span><span class='macro'>!</span>[<span class='string'>&quot;Hola&quot;</span>, <span class='string'>&quot;mundo&quot;</span>];

    <span class='kw'>let</span> <span class='ident'>y</span> <span class='op'>=</span> <span class='ident'>x</span>[<span class='number'>0</span>].<span class='ident'>clone</span>();

    <span class='ident'>x</span>.<span class='ident'>push</span>(<span class='string'>&quot;foo&quot;</span>);
}</pre>

<p>Rust tiene por defecto <a href="ownership.html#move-semantics">semántica de movimiento</a>, entonces si queremos hacer una copia de alguna data, llamamos el método <code>clone()</code>. En este ejemplo <code>y</code> ya no es una referencia a el vector almacenado en <code>x</code>, sino una copia de su primer elemento, <code>&quot;Hola&quot;</code>. Debido a que no tenemos una referencia nuestro <code>push()</code> funciona perfectamente.</p>

<p>Si realmente queremos una referencia, necesitamos otra opción: asegurarnos de que nuestra referencia salga de ámbito antes que tratamos de hacer la mutación. De esta manera:</p>
<span class='rusttest'>fn main() {
    let mut x = vec![&quot;Hola&quot;, &quot;mundo&quot;];

    {
        let y = &amp;x[0];
    }

    x.push(&quot;foo&quot;);
}
</span><pre class='rust rust-example-rendered'>
<span class='kw'>fn</span> <span class='ident'>main</span>() {
    <span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>x</span> <span class='op'>=</span> <span class='macro'>vec</span><span class='macro'>!</span>[<span class='string'>&quot;Hola&quot;</span>, <span class='string'>&quot;mundo&quot;</span>];

    {
        <span class='kw'>let</span> <span class='ident'>y</span> <span class='op'>=</span> <span class='kw-2'>&amp;</span><span class='ident'>x</span>[<span class='number'>0</span>];
    }

    <span class='ident'>x</span>.<span class='ident'>push</span>(<span class='string'>&quot;foo&quot;</span>);
}</pre>

<p>Con el par adicional de llaves hemos creado un ámbito interno. <code>y</code> saldrá de ámbito antes que llamemos a <code>push()</code>, entonces no hay problema.</p>

<p>Este concepto de pertenencia no es solo bueno para prevenir punteros colgantes, sino un conjunto entero de problemas, como invalidación de iteradores, concurrencia y más.</p>

    <script type="text/javascript">
        window.playgroundUrl = "https://play.rust-lang.org";
    </script>
    <script src='rustbook.js'></script>
<script src='playpen.js'></script>
</div></div>


</body>
</html>