You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
patterns/po/es.po

10263 lines
338 KiB
Plaintext

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

msgid ""
msgstr ""
"Project-Id-Version: Rust Design Patterns\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2023-04-08 21:55+0200\n"
"Last-Translator: <EMAIL@ADDRESS>\n"
"Language-Team: Spanish\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src\SUMMARY.md:3
#, fuzzy
msgid "Introduction"
msgstr "Introducción"
#: src\SUMMARY.md:4
#, fuzzy
msgid "Translations"
msgstr "Traducciones"
#: src\SUMMARY.md:5
#, fuzzy
msgid "Idioms"
msgstr "Modismos"
#: src\SUMMARY.md:6
#, fuzzy
msgid "Use borrowed types for arguments"
msgstr "Usar tipos prestados para argumentos"
#: src\SUMMARY.md:7
#, fuzzy
msgid "Concatenating Strings with format!"
msgstr "¡Concatenación de cadenas con formato!"
#: src\SUMMARY.md:8
#, fuzzy
msgid "Constructor"
msgstr "Constructor"
#: src\SUMMARY.md:9
#, fuzzy
msgid "The Default Trait"
msgstr "El rasgo predeterminado"
#: src\SUMMARY.md:10
#, fuzzy
msgid "Collections Are Smart Pointers"
msgstr "Las colecciones son punteros inteligentes"
#: src\SUMMARY.md:11
#, fuzzy
msgid "Finalisation in Destructors"
msgstr "Finalización en Destructores"
#: src\SUMMARY.md:12
#, fuzzy
msgid "mem::{take(_), replace(_)}"
msgstr "mem::{tomar(_), reemplazar(_)}"
#: src\SUMMARY.md:13
#, fuzzy
msgid "On-Stack Dynamic Dispatch"
msgstr "Despacho dinámico en pila"
#: src\SUMMARY.md:14 src\SUMMARY.md:40
#, fuzzy
msgid "Foreign function interface (FFI)"
msgstr "Interfaz de función externa (FFI)"
#: src\SUMMARY.md:15
#, fuzzy
msgid "Idiomatic Errors"
msgstr "Errores idiomáticos"
#: src\SUMMARY.md:16
#, fuzzy
msgid "Accepting Strings"
msgstr "Aceptar cadenas"
#: src\SUMMARY.md:17
#, fuzzy
msgid "Passing Strings"
msgstr "Pasar cuerdas"
#: src\SUMMARY.md:18
#, fuzzy
msgid "Iterating over an Option"
msgstr "Iterando sobre una opción"
#: src\SUMMARY.md:19
#, fuzzy
msgid "Pass Variables to Closure"
msgstr "Pasar variables al cierre"
#: src\SUMMARY.md:20
#, fuzzy
msgid "Privacy For Extensibility"
msgstr "Privacidad para extensibilidad"
#: src\SUMMARY.md:21
#, fuzzy
msgid "Easy doc initialization"
msgstr "Fácil inicialización de documentos"
#: src\SUMMARY.md:22
#, fuzzy
msgid "Temporary mutability"
msgstr "Mutabilidad temporal"
#: src\SUMMARY.md:23
#, fuzzy
msgid "Return consumed arg on error"
msgstr "Devolver argumento consumido en caso de error"
#: src\SUMMARY.md:25
#, fuzzy
msgid "Design Patterns"
msgstr "Patrones de diseño"
#: src\SUMMARY.md:26
#, fuzzy
msgid "Behavioural"
msgstr "conductual"
#: src\SUMMARY.md:27
#, fuzzy
msgid "Command"
msgstr "Dominio"
#: src\SUMMARY.md:28
#, fuzzy
msgid "Interpreter"
msgstr "Intérprete"
#: src\SUMMARY.md:29
#, fuzzy
msgid "Newtype"
msgstr "Nuevo tipo"
#: src\SUMMARY.md:30
#, fuzzy
msgid "RAII Guards"
msgstr "Guardias RAII"
#: src\SUMMARY.md:31
#, fuzzy
msgid "Strategy"
msgstr "Estrategia"
#: src\SUMMARY.md:32
#, fuzzy
msgid "Visitor"
msgstr "Visitante"
#: src\SUMMARY.md:33
#, fuzzy
msgid "Creational"
msgstr "Creacional"
#: src\SUMMARY.md:34
#, fuzzy
msgid "Builder"
msgstr "Constructor"
#: src\SUMMARY.md:35
#, fuzzy
msgid "Fold"
msgstr "Doblar"
#: src\SUMMARY.md:36
#, fuzzy
msgid "Structural"
msgstr "Estructural"
#: src\SUMMARY.md:37
#, fuzzy
msgid "Compose Structs"
msgstr "Componer estructuras"
#: src\SUMMARY.md:38
#, fuzzy
msgid "Prefer Small Crates"
msgstr "Preferir cajas pequeñas"
#: src\SUMMARY.md:39
#, fuzzy
msgid "Contain unsafety in small modules"
msgstr "Contener la inseguridad en pequeños módulos"
#: src\SUMMARY.md:41
#, fuzzy
msgid "Object-Based APIs"
msgstr "API basadas en objetos"
#: src\SUMMARY.md:42
#, fuzzy
msgid "Type Consolidation into Wrappers"
msgstr "Escriba la consolidación en contenedores"
#: src\SUMMARY.md:44
#, fuzzy
msgid "Anti-patterns"
msgstr "Anti-patrones"
#: src\SUMMARY.md:45
#, fuzzy
msgid "Clone to satisfy the borrow checker"
msgstr "Clonar para satisfacer el verificador de préstamo"
#: src\SUMMARY.md:46
#, fuzzy
msgid "#[deny(warnings)]"
msgstr "#[negar(advertencias)]"
#: src\SUMMARY.md:47
#, fuzzy
msgid "Deref Polymorphism"
msgstr "Polimorfismo Deref"
#: src\SUMMARY.md:49
#, fuzzy
msgid "Functional Programming"
msgstr "Programación funcional"
#: src\SUMMARY.md:50
#, fuzzy
msgid "Programming paradigms"
msgstr "Paradigmas de programación"
#: src\SUMMARY.md:51
#, fuzzy
msgid "Generics as Type Classes"
msgstr "Genéricos como clases de tipos"
#: src\SUMMARY.md:52
#, fuzzy
msgid "Lenses and Prisms"
msgstr "lentes y prismas"
#: src\SUMMARY.md:54
#, fuzzy
msgid "Additional Resources"
msgstr "Recursos adicionales"
#: src\SUMMARY.md:55
#, fuzzy
msgid "Design principles"
msgstr "Criterios de diseño"
#: src\intro.md:1
#, fuzzy
msgid "# Introduction"
msgstr "# Introducción"
#: src\intro.md:3
#, fuzzy
msgid "## Participation"
msgstr "## Participación"
#: src\intro.md:5
#, fuzzy
msgid ""
"If you are interested in contributing to this book, check out the\n"
"[contribution "
"guidelines](https://github.com/rust-unofficial/patterns/blob/master/CONTRIBUTING.md)."
msgstr ""
"Si está interesado en contribuir a este libro, consulte el\n"
"[directrices de "
"contribución](https://github.com/rust-unofficial/patterns/blob/master/CONTRIBUTING.md)."
#: src\intro.md:8
#, fuzzy
msgid "## Design patterns"
msgstr "## Patrones de diseño"
#: src\intro.md:10
#, fuzzy
msgid ""
"In software development, we often come across problems that share\n"
"similarities regardless of the environment they appear in. Although the\n"
"implementation details are crucial to solve the task at hand, we may\n"
"abstract from these particularities to find the common practices that\n"
"are generically applicable."
msgstr ""
"En el desarrollo de software, a menudo nos encontramos con problemas que "
"comparten\n"
"similitudes independientemente del entorno en el que aparecen. Aunque el\n"
"detalles de implementación son cruciales para resolver la tarea en cuestión, "
"podemos\n"
"abstraerse de estas particularidades para encontrar las prácticas comunes "
"que\n"
"son de aplicación genérica."
#: src\intro.md:16
#, fuzzy
msgid ""
"Design patterns are a collection of reusable and tested solutions to\n"
"recurring problems in engineering. They make our software more modular,\n"
"maintainable, and extensible. Moreover, these patterns provide a common\n"
"language for developers, making them an excellent tool for effective\n"
"communication when problem-solving in teams."
msgstr ""
"Los patrones de diseño son una colección de soluciones reutilizables y "
"probadas para\n"
"problemas recurrentes en ingeniería. Hacen que nuestro software sea más "
"modular,\n"
"mantenible y extensible. Además, estos patrones proporcionan un común\n"
"lenguaje para desarrolladores, lo que los convierte en una excelente "
"herramienta para\n"
"comunicación en la resolución de problemas en equipo."
#: src\intro.md:22 src\patterns/index.md:14
#, fuzzy
msgid "## Design patterns in Rust"
msgstr "## Patrones de diseño en Rust"
#: src\intro.md:24
#, fuzzy
msgid ""
"Rust is not object-oriented, and the combination of all its "
"characteristics,\n"
"such as functional elements, a strong type system, and the borrow checker,\n"
"makes it unique.\n"
"Because of this, Rust design patterns vary with respect to other\n"
"traditional object-oriented programming languages.\n"
"That's why we decided to write this book. We hope you enjoy reading it!\n"
"The book is divided in three main chapters:"
msgstr ""
"Rust no está orientado a objetos, y la combinación de todas sus "
"características,\n"
"tales como elementos funcionales, un sistema de tipo fuerte y el verificador "
"de préstamo,\n"
"lo hace único.\n"
"Debido a esto, los patrones de diseño de Rust varían con respecto a otros\n"
"lenguajes de programación tradicionales orientados a objetos.\n"
"Por eso decidimos escribir este libro. ¡Esperamos que disfrutes leyéndolo!\n"
"El libro se divide en tres capítulos principales:"
#: src\intro.md:32
#, fuzzy
msgid ""
"- [Idioms](./idioms/index.md): guidelines to follow when coding.\n"
" They are the social norms of the community.\n"
" You should break them only if you have a good reason for it.\n"
"- [Design patterns](./patterns/index.md): methods to solve common problems\n"
" when coding.\n"
"- [Anti-patterns](./anti_patterns/index.md): methods to solve common "
"problems\n"
" when coding.\n"
" However, while design patterns give us benefits,\n"
" anti-patterns create more problems."
msgstr ""
"- [Expresiones idiomáticas](./idioms/index.md): pautas a seguir al "
"codificar.\n"
" Son las normas sociales de la comunidad.\n"
" Debe romperlos solo si tiene una buena razón para ello.\n"
"- [Patrones de diseño] (./patrones/index.md): métodos para resolver "
"problemas comunes\n"
" al codificar.\n"
"- [Anti-patterns](./anti_patterns/index.md): métodos para resolver problemas "
"comunes\n"
" al codificar.\n"
" Sin embargo, mientras que los patrones de diseño nos dan beneficios,\n"
" los antipatrones crean más problemas."
#: src\translations.md:1
#, fuzzy
msgid "# Translations"
msgstr "# Traducciones"
#: src\translations.md:3
#, fuzzy
msgid ""
"We are utilizing "
"[mdbook-i18n-helper](https://github.com/google/mdbook-i18n-helpers).\n"
"Please read up on how to _add_ and _update_ translations in [their "
"repository](https://github.com/google/mdbook-i18n-helpers#creating-and-updating-translations)"
msgstr ""
"Estamos utilizando "
"[mdbook-i18n-helper](https://github.com/google/mdbook-i18n-helpers).\n"
"Lea cómo _agregar_ y _actualizar_ traducciones en [su "
"repositorio](https://github.com/google/mdbook-i18n-helpers#creating-and-updating-translations)"
#: src\translations.md:6
#, fuzzy
msgid "## External translations"
msgstr "## Traducciones externas"
#: src\translations.md:8
#, fuzzy
msgid "- [简体中文](https://fomalhauthmj.github.io/patterns/)"
msgstr "- [简体中文](https://fomalhauthmj.github.io/patterns/)"
#: src\translations.md:10
#, fuzzy
msgid ""
"If you want to add a translation, please open an issue in the\n"
"[main repository](https://github.com/rust-unofficial/patterns)."
msgstr ""
"Si desea agregar una traducción, abra un problema en el\n"
"[repositorio principal](https://github.com/rust-unofficial/patterns)."
#: src\idioms/index.md:1
#, fuzzy
msgid "# Idioms"
msgstr "# Modismos"
#: src\idioms/index.md:3
#, fuzzy
msgid ""
"[Idioms](https://en.wikipedia.org/wiki/Programming_idiom) are commonly used\n"
"styles, guidelines and patterns largely agreed upon by a community.\n"
"Writing idiomatic code allows other developers to understand better what is\n"
"happening."
msgstr ""
"[Los modismos] (https://en.wikipedia.org/wiki/Programming_idiom) se usan "
"comúnmente\n"
"estilos, pautas y patrones acordados en gran medida por una comunidad.\n"
"Escribir código idiomático permite que otros desarrolladores entiendan mejor "
"qué es\n"
"sucediendo."
#: src\idioms/index.md:8
#, fuzzy
msgid ""
"After all, the computer only cares about the machine code that is generated\n"
"by the compiler.\n"
"Instead, the source code is mainly beneficial to the developer.\n"
"So, since we have this abstraction layer, why not make it more readable?"
msgstr ""
"Después de todo, a la computadora solo le importa el código de máquina que "
"se genera.\n"
"por el compilador.\n"
"En cambio, el código fuente es principalmente beneficioso para el "
"desarrollador.\n"
"Entonces, ya que tenemos esta capa de abstracción, ¿por qué no hacerla más "
"legible?"
#: src\idioms/index.md:13
msgid ""
"Remember the [KISS "
"principle](https://en.wikipedia.org/wiki/KISS_principle):\n"
"\"Keep It Simple, Stupid\". It claims that \"most systems work best if they "
"are\n"
"kept simple rather than made complicated; therefore, simplicity should be a "
"key\n"
"goal in design, and unnecessary complexity should be avoided\"."
msgstr ""
#: src\idioms/index.md:18
#, fuzzy
msgid "> Code is there for humans, not computers, to understand."
msgstr ""
"> El código está ahí para que lo entiendan los humanos, no las computadoras."
#: src\idioms/coercion-arguments.md:1
#, fuzzy
msgid "# Use borrowed types for arguments"
msgstr "# Usar tipos prestados para argumentos"
#: src\idioms/coercion-arguments.md:3 src\idioms/concat-format.md:3
#: src\idioms/default.md:3 src\idioms/deref.md:3 src\idioms/dtor-finally.md:3
#: src\idioms/mem-replace.md:3 src\idioms/on-stack-dyn-dispatch.md:3
#: src\idioms/ffi/errors.md:3 src\idioms/ffi/accepting-strings.md:3
#: src\idioms/ffi/passing-strings.md:3 src\idioms/option-iter.md:3
#: src\idioms/pass-var-to-closure.md:3 src\idioms/priv-extend.md:3
#: src\idioms/temporary-mutability.md:3
#: src\idioms/return-consumed-arg-on-error.md:3
#: src\patterns/behavioural/command.md:3
#: src\patterns/behavioural/interpreter.md:3
#: src\patterns/behavioural/newtype.md:13 src\patterns/behavioural/RAII.md:3
#: src\patterns/behavioural/strategy.md:3 src\patterns/behavioural/visitor.md:3
#: src\patterns/creational/builder.md:3 src\patterns/creational/fold.md:3
#: src\patterns/structural/compose-structs.md:5
#: src\patterns/structural/small-crates.md:3
#: src\patterns/structural/unsafe-mods.md:3 src\patterns/ffi/export.md:3
#: src\patterns/ffi/wrappers.md:3 src\anti_patterns/borrow_clone.md:3
#: src\anti_patterns/deny-warnings.md:3 src\anti_patterns/deref.md:3
#: src\functional/generics-type-classes.md:3
#, fuzzy
msgid "## Description"
msgstr "## Descripción"
#: src\idioms/coercion-arguments.md:5
#, fuzzy
msgid ""
"Using a target of a deref coercion can increase the flexibility of your "
"code\n"
"when you are deciding which argument type to use for a function argument.\n"
"In this way, the function will accept more input types."
msgstr ""
"El uso de un objetivo de coerción de desref puede aumentar la flexibilidad "
"de su código\n"
"cuando está decidiendo qué tipo de argumento usar para un argumento de "
"función.\n"
"De esta forma, la función aceptará más tipos de entrada."
#: src\idioms/coercion-arguments.md:9
#, fuzzy
msgid ""
"This is not limited to slice-able or fat pointer types.\n"
"In fact, you should always prefer using the **borrowed type** over\n"
"**borrowing the owned type**.\n"
"Such as `&str` over `&String`, `&[T]` over `&Vec<T>`, or `&T` over `&Box<T>`."
msgstr ""
"Esto no se limita a los tipos de puntero gordo o rebanable.\n"
"De hecho, siempre debe preferir usar el **tipo prestado** en lugar de\n"
"**tomando prestado el tipo propio**.\n"
"Como `&str` sobre `&String`, `&[T]` sobre `&Vec<T>`, o `&T` sobre `&Box<T>`."
#: src\idioms/coercion-arguments.md:14
#, fuzzy
msgid ""
"Using borrowed types you can avoid layers of indirection for those "
"instances\n"
"where the owned type already provides a layer of indirection. For instance, "
"a\n"
"`String` has a layer of indirection, so a `&String` will have two layers of\n"
"indirection. We can avoid this by using `&str` instead, and letting "
"`&String`\n"
"coerce to a `&str` whenever the function is invoked."
msgstr ""
"Usando tipos prestados puede evitar capas de direccionamiento indirecto para "
"esas instancias\n"
"donde el tipo propio ya proporciona una capa de direccionamiento indirecto. "
"Por ejemplo, un\n"
"`String` tiene una capa de direccionamiento indirecto, por lo que `&String` "
"tendrá dos capas de\n"
"indirección Podemos evitar esto usando `&str` en su lugar, y dejando que "
"`&String`\n"
"coaccionar a `&str` cada vez que se invoca la función."
#: src\idioms/coercion-arguments.md:20 src\idioms/concat-format.md:10
#: src\idioms/default.md:20 src\idioms/deref.md:9 src\idioms/dtor-finally.md:9
#: src\idioms/mem-replace.md:11 src\idioms/on-stack-dyn-dispatch.md:10
#: src\idioms/pass-var-to-closure.md:12 src\idioms/priv-extend.md:18
#: src\idioms/temporary-mutability.md:12
#: src\idioms/return-consumed-arg-on-error.md:8
#: src\patterns/behavioural/command.md:18
#: src\patterns/behavioural/newtype.md:18 src\patterns/behavioural/RAII.md:11
#: src\patterns/behavioural/strategy.md:28
#: src\patterns/behavioural/visitor.md:13 src\patterns/creational/builder.md:7
#: src\patterns/creational/fold.md:12
#: src\patterns/structural/compose-structs.md:17
#: src\anti_patterns/borrow_clone.md:11 src\anti_patterns/deny-warnings.md:8
#: src\anti_patterns/deref.md:8 src\functional/generics-type-classes.md:38
#, fuzzy
msgid "## Example"
msgstr "## Ejemplo"
#: src\idioms/coercion-arguments.md:22
#, fuzzy
msgid ""
"For this example, we will illustrate some differences for using `&String` as "
"a\n"
"function argument versus using a `&str`, but the ideas apply as well to "
"using\n"
"`&Vec<T>` versus using a `&[T]` or using a `&Box<T>` versus a `&T`."
msgstr ""
"Para este ejemplo, ilustraremos algunas diferencias al usar `&String` como\n"
"argumento de función versus usar `&str`, pero las ideas se aplican también "
"al uso\n"
"`&Vec<T>` versus usar `&[T]` o usar `&Box<T>` versus `&T`."
#: src\idioms/coercion-arguments.md:26
#, fuzzy
msgid ""
"Consider an example where we wish to determine if a word contains three\n"
"consecutive vowels. We don't need to own the string to determine this, so "
"we\n"
"will take a reference."
msgstr ""
"Considere un ejemplo donde deseamos determinar si una palabra contiene tres\n"
"vocales consecutivas. No necesitamos ser dueños de la cadena para determinar "
"esto, así que\n"
"tomará una referencia."
#: src\idioms/coercion-arguments.md:30
#, fuzzy
msgid "The code might look something like this:"
msgstr "El código podría ser algo como esto:"
#: src\idioms/coercion-arguments.md:32
msgid ""
"```rust\n"
"fn three_vowels(word: &String) -> bool {\n"
" let mut vowel_count = 0;\n"
" for c in word.chars() {\n"
" match c {\n"
" 'a' | 'e' | 'i' | 'o' | 'u' => {\n"
" vowel_count += 1;\n"
" if vowel_count >= 3 {\n"
" return true\n"
" }\n"
" }\n"
" _ => vowel_count = 0\n"
" }\n"
" }\n"
" false\n"
"}\n"
"\n"
"fn main() {\n"
" let ferris = \"Ferris\".to_string();\n"
" let curious = \"Curious\".to_string();\n"
" println!(\"{}: {}\", ferris, three_vowels(&ferris));\n"
" println!(\"{}: {}\", curious, three_vowels(&curious));\n"
"\n"
" // This works fine, but the following two lines would fail:\n"
" // println!(\"Ferris: {}\", three_vowels(\"Ferris\"));\n"
" // println!(\"Curious: {}\", three_vowels(\"Curious\"));\n"
"\n"
"}\n"
"```"
msgstr ""
#: src\idioms/coercion-arguments.md:62
#, fuzzy
msgid ""
"This works fine because we are passing a `&String` type as a parameter.\n"
"If we remove the comments on the last two lines, the example will fail. "
"This\n"
"is because a `&str` type will not coerce to a `&String` type. We can fix "
"this\n"
"by simply modifying the type for our argument."
msgstr ""
"Esto funciona bien porque estamos pasando un tipo `&String` como parámetro.\n"
"Si eliminamos los comentarios de las dos últimas líneas, el ejemplo fallará. "
"Este\n"
"es porque un tipo `&str` no forzará a un tipo `&String`. podemos arreglar "
"esto\n"
"simplemente modificando el tipo de nuestro argumento."
#: src\idioms/coercion-arguments.md:67
#, fuzzy
msgid "For instance, if we change our function declaration to:"
msgstr "Por ejemplo, si cambiamos nuestra declaración de función a:"
#: src\idioms/coercion-arguments.md:69
msgid ""
"```rust, ignore\n"
"fn three_vowels(word: &str) -> bool {\n"
"```"
msgstr ""
#: src\idioms/coercion-arguments.md:73
#, fuzzy
msgid "then both versions will compile and print the same output."
msgstr "entonces ambas versiones compilarán e imprimirán el mismo resultado."
#: src\idioms/coercion-arguments.md:75
msgid ""
"```bash\n"
"Ferris: false\n"
"Curious: true\n"
"```"
msgstr ""
#: src\idioms/coercion-arguments.md:80
#, fuzzy
msgid ""
"But wait, that's not all! There is more to this story.\n"
"It's likely that you may say to yourself: that doesn't matter, I will never "
"be\n"
"using a `&'static str` as an input anyways (as we did when we used "
"`\"Ferris\"`).\n"
"Even ignoring this special example, you may still find that using `&str` "
"will\n"
"give you more flexibility than using a `&String`."
msgstr ""
"Pero espera, ¡eso no es todo! Hay más en esta historia.\n"
"Es probable que te digas a ti mismo: eso no importa, nunca seré\n"
"usando `&'static str` como entrada de todos modos (como hicimos cuando "
"usamos `\"Ferris\"`).\n"
"Incluso ignorando este ejemplo especial, aún puede encontrar que usar "
"`&str`\n"
"darle más flexibilidad que usar un `&String`."
#: src\idioms/coercion-arguments.md:86
#, fuzzy
msgid ""
"Let's now take an example where someone gives us a sentence, and we want to\n"
"determine if any of the words in the sentence contain three consecutive "
"vowels.\n"
"We probably should make use of the function we have already defined and "
"simply\n"
"feed in each word from the sentence."
msgstr ""
"Ahora tomemos un ejemplo en el que alguien nos da una oración y queremos\n"
"determinar si alguna de las palabras de la oración contiene tres vocales "
"consecutivas.\n"
"Probablemente deberíamos hacer uso de la función que ya hemos definido y "
"simplemente\n"
"Introduzca cada palabra de la oración."
#: src\idioms/coercion-arguments.md:91
#, fuzzy
msgid "An example of this could look like this:"
msgstr "Un ejemplo de esto podría verse así:"
#: src\idioms/coercion-arguments.md:93
msgid ""
"```rust\n"
"fn three_vowels(word: &str) -> bool {\n"
" let mut vowel_count = 0;\n"
" for c in word.chars() {\n"
" match c {\n"
" 'a' | 'e' | 'i' | 'o' | 'u' => {\n"
" vowel_count += 1;\n"
" if vowel_count >= 3 {\n"
" return true\n"
" }\n"
" }\n"
" _ => vowel_count = 0\n"
" }\n"
" }\n"
" false\n"
"}\n"
"\n"
"fn main() {\n"
" let sentence_string =\n"
" \"Once upon a time, there was a friendly curious crab named "
"Ferris\".to_string();\n"
" for word in sentence_string.split(' ') {\n"
" if three_vowels(word) {\n"
" println!(\"{} has three consecutive vowels!\", word);\n"
" }\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\idioms/coercion-arguments.md:121
#, fuzzy
msgid ""
"Running this example using our function declared with an argument type "
"`&str`\n"
"will yield"
msgstr ""
"Ejecutando este ejemplo usando nuestra función declarada con un tipo de "
"argumento `&str`\n"
"rendirá"
#: src\idioms/coercion-arguments.md:124
msgid ""
"```bash\n"
"curious has three consecutive vowels!\n"
"```"
msgstr ""
#: src\idioms/coercion-arguments.md:128
#, fuzzy
msgid ""
"However, this example will not run when our function is declared with an\n"
"argument type `&String`. This is because string slices are a `&str` and not "
"a\n"
"`&String` which would require an allocation to be converted to `&String` "
"which\n"
"is not implicit, whereas converting from `String` to `&str` is cheap and "
"implicit."
msgstr ""
"Sin embargo, este ejemplo no se ejecutará cuando nuestra función se declare "
"con un\n"
"tipo de argumento `&String`. Esto se debe a que los segmentos de cadena son "
"un `&str` y no un\n"
"`&String` que requeriría convertir una asignación a `&String` que\n"
"no es implícito, mientras que convertir de `String` a `&str` es económico e "
"implícito."
#: src\idioms/coercion-arguments.md:133 src\idioms/default.md:58
#: src\idioms/deref.md:76 src\idioms/dtor-finally.md:88
#: src\idioms/mem-replace.md:108 src\idioms/on-stack-dyn-dispatch.md:83
#: src\idioms/option-iter.md:46 src\idioms/priv-extend.md:120
#: src\patterns/behavioural/command.md:218
#: src\patterns/behavioural/interpreter.md:142
#: src\patterns/behavioural/newtype.md:104 src\patterns/behavioural/RAII.md:111
#: src\patterns/behavioural/strategy.md:174
#: src\patterns/behavioural/visitor.md:106
#: src\patterns/creational/builder.md:108 src\patterns/creational/fold.md:109
#: src\patterns/structural/small-crates.md:45
#: src\patterns/structural/unsafe-mods.md:32
#: src\anti_patterns/borrow_clone.md:68 src\anti_patterns/deny-warnings.md:96
#: src\anti_patterns/deref.md:123 src\functional/generics-type-classes.md:237
#, fuzzy
msgid "## See also"
msgstr "## Ver también"
#: src\idioms/coercion-arguments.md:135
#, fuzzy
msgid ""
"- [Rust Language Reference on Type "
"Coercions](https://doc.rust-lang.org/reference/type-coercions.html)\n"
"- For more discussion on how to handle `String` and `&str` see\n"
" [this blog series "
"(2015)](https://web.archive.org/web/20201112023149/https://hermanradtke.com/2015/05/03/string-vs-str-in-rust-functions.html)\n"
" by Herman J. Radtke III"
msgstr ""
"- [Referencia del lenguaje Rust sobre coerciones de "
"tipos](https://doc.rust-lang.org/reference/type-coercions.html)\n"
"- Para obtener más información sobre cómo manejar `String` y `&str`, "
"consulte\n"
" [esta serie de blogs "
"(2015)](https://web.archive.org/web/20201112023149/https://hermanradtke.com/2015/05/03/string-vs-str-in-rust-functions.html "
")\n"
" por Herman J. Radtke III"
#: src\idioms/concat-format.md:1
#, fuzzy
msgid "# Concatenating strings with `format!`"
msgstr "# Concatenar cadenas con `formato!`"
#: src\idioms/concat-format.md:5
#, fuzzy
msgid ""
"It is possible to build up strings using the `push` and `push_str` methods "
"on a\n"
"mutable `String`, or using its `+` operator. However, it is often more\n"
"convenient to use `format!`, especially where there is a mix of literal and\n"
"non-literal strings."
msgstr ""
"Es posible construir cadenas usando los métodos `push` y `push_str` en un\n"
"`String` mutable, o usando su operador `+`. Sin embargo, a menudo es más\n"
"conveniente usar `formato!`, especialmente donde hay una mezcla de literal "
"y\n"
"cadenas no literales."
#: src\idioms/concat-format.md:12
msgid ""
"```rust\n"
"fn say_hello(name: &str) -> String {\n"
" // We could construct the result string manually.\n"
" // let mut result = \"Hello \".to_owned();\n"
" // result.push_str(name);\n"
" // result.push('!');\n"
" // result\n"
"\n"
" // But using format! is better.\n"
" format!(\"Hello {}!\", name)\n"
"}\n"
"```"
msgstr ""
#: src\idioms/concat-format.md:25 src\idioms/deref.md:43
#: src\idioms/dtor-finally.md:42 src\idioms/mem-replace.md:83
#: src\idioms/on-stack-dyn-dispatch.md:48 src\idioms/ffi/errors.md:131
#: src\idioms/ffi/accepting-strings.md:68 src\idioms/ffi/passing-strings.md:68
#: src\idioms/pass-var-to-closure.md:48 src\idioms/temporary-mutability.md:38
#: src\idioms/return-consumed-arg-on-error.md:55
#: src\patterns/behavioural/newtype.md:66 src\patterns/behavioural/RAII.md:78
#: src\patterns/behavioural/strategy.md:96
#: src\patterns/creational/builder.md:68
#: src\patterns/structural/compose-structs.md:75
#: src\patterns/structural/small-crates.md:12
#: src\patterns/structural/unsafe-mods.md:11 src\patterns/ffi/export.md:111
#: src\patterns/ffi/wrappers.md:63 src\anti_patterns/deny-warnings.md:16
#: src\anti_patterns/deref.md:69 src\functional/generics-type-classes.md:210
#, fuzzy
msgid "## Advantages"
msgstr "## Ventajas"
#: src\idioms/concat-format.md:27
#, fuzzy
msgid ""
"Using `format!` is usually the most succinct and readable way to combine "
"strings."
msgstr ""
"Usar `format!` suele ser la forma más sucinta y legible de combinar cadenas."
#: src\idioms/concat-format.md:29 src\idioms/deref.md:50
#: src\idioms/dtor-finally.md:47 src\idioms/mem-replace.md:87
#: src\idioms/on-stack-dyn-dispatch.md:54 src\idioms/ffi/errors.md:136
#: src\idioms/ffi/accepting-strings.md:141
#: src\idioms/ffi/passing-strings.md:103 src\idioms/pass-var-to-closure.md:57
#: src\idioms/temporary-mutability.md:42
#: src\idioms/return-consumed-arg-on-error.md:59
#: src\patterns/behavioural/newtype.md:77
#: src\patterns/behavioural/strategy.md:104
#: src\patterns/creational/builder.md:76
#: src\patterns/structural/compose-structs.md:81
#: src\patterns/structural/small-crates.md:22
#: src\patterns/structural/unsafe-mods.md:17 src\patterns/ffi/export.md:234
#: src\patterns/ffi/wrappers.md:69 src\anti_patterns/deref.md:81
#: src\functional/generics-type-classes.md:221
#, fuzzy
msgid "## Disadvantages"
msgstr "## Desventajas"
#: src\idioms/concat-format.md:31
#, fuzzy
msgid ""
"It is usually not the most efficient way to combine strings - a series of "
"`push`\n"
"operations on a mutable string is usually the most efficient (especially if "
"the\n"
"string has been pre-allocated to the expected size)."
msgstr ""
"Por lo general, no es la forma más eficiente de combinar cadenas: una serie "
"de `push`\n"
"operaciones en una cadena mutable suele ser la más eficiente (especialmente "
"si el\n"
"cadena se ha preasignado al tamaño esperado)."
#: src\idioms/ctor.md:1
#, fuzzy
msgid "# Constructors\r"
msgstr "# Constructores\r"
#: src\idioms/ctor.md:3 src\idioms/rustdoc-init.md:3
#, fuzzy
msgid "## Description\r"
msgstr "## Descripción\r"
#: src\idioms/ctor.md:5
#, fuzzy
msgid ""
"Rust does not have constructors as a language construct. Instead, the\r\n"
"convention is to use an [associated function][associated function] `new` to "
"create an object:"
msgstr ""
"Rust no tiene constructores como una construcción de lenguaje. En cambio, "
"el\r\n"
"la convención es usar una [función asociada][función asociada] `nueva` para "
"crear un objeto:"
#: src\idioms/ctor.md:8
msgid ""
"````rust\r\n"
"/// Time in seconds.\r\n"
"///\r\n"
"/// # Example\r\n"
"///\r\n"
"/// ```\r\n"
"/// let s = Second::new(42);\r\n"
"/// assert_eq!(42, s.value());\r\n"
"/// ```\r\n"
"pub struct Second {\r\n"
" value: u64\r\n"
"}\r\n"
"\r\n"
"impl Second {\r\n"
" // Constructs a new instance of [`Second`].\r\n"
" // Note this is an associated function - no self.\r\n"
" pub fn new(value: u64) -> Self {\r\n"
" Self { value }\r\n"
" }\r\n"
"\r\n"
" /// Returns the value in seconds.\r\n"
" pub fn value(&self) -> u64 {\r\n"
" self.value\r\n"
" }\r\n"
"}\r\n"
"````"
msgstr ""
#: src\idioms/ctor.md:35
#, fuzzy
msgid "## Default Constructors\r"
msgstr "## Constructores predeterminados\r"
#: src\idioms/ctor.md:37
#, fuzzy
msgid ""
"Rust supports default constructors with the [`Default`][std-default] trait:"
msgstr ""
"Rust admite constructores predeterminados con el rasgo "
"[`Default`][std-default]:"
#: src\idioms/ctor.md:39
msgid ""
"````rust\r\n"
"/// Time in seconds.\r\n"
"///\r\n"
"/// # Example\r\n"
"///\r\n"
"/// ```\r\n"
"/// let s = Second::default();\r\n"
"/// assert_eq!(0, s.value());\r\n"
"/// ```\r\n"
"pub struct Second {\r\n"
" value: u64\r\n"
"}\r\n"
"\r\n"
"impl Second {\r\n"
" /// Returns the value in seconds.\r\n"
" pub fn value(&self) -> u64 {\r\n"
" self.value\r\n"
" }\r\n"
"}\r\n"
"\r\n"
"impl Default for Second {\r\n"
" fn default() -> Self {\r\n"
" Self { value: 0 }\r\n"
" }\r\n"
"}\r\n"
"````"
msgstr ""
#: src\idioms/ctor.md:66
#, fuzzy
msgid ""
"`Default` can also be derived if all types of all fields implement "
"`Default`,\r\n"
"like they do with `Second`:"
msgstr ""
"`Predeterminado` también se puede derivar si todos los tipos de todos los "
"campos implementan `Predeterminado`,\r\n"
"como lo hacen con `Second`:"
#: src\idioms/ctor.md:69
msgid ""
"````rust\r\n"
"/// Time in seconds.\r\n"
"///\r\n"
"/// # Example\r\n"
"///\r\n"
"/// ```\r\n"
"/// let s = Second::default();\r\n"
"/// assert_eq!(0, s.value());\r\n"
"/// ```\r\n"
"#[derive(Default)]\r\n"
"pub struct Second {\r\n"
" value: u64\r\n"
"}\r\n"
"\r\n"
"impl Second {\r\n"
" /// Returns the value in seconds.\r\n"
" pub fn value(&self) -> u64 {\r\n"
" self.value\r\n"
" }\r\n"
"}\r\n"
"````"
msgstr ""
#: src\idioms/ctor.md:91
#, fuzzy
msgid ""
"**Note:** It is common and expected for types to implement both\r\n"
"`Default` and an empty `new` constructor. `new` is the constructor\r\n"
"convention in Rust, and users expect it to exist, so if it is\r\n"
"reasonable for the basic constructor to take no arguments, then it\r\n"
"should, even if it is functionally identical to default."
msgstr ""
"**Nota:** Es común y se espera que los tipos implementen ambos\r\n"
"'Predeterminado' y un constructor 'nuevo' vacío. `nuevo` es el "
"constructor\r\n"
"convención en Rust, y los usuarios esperan que exista, por lo que si es\r\n"
"razonable que el constructor básico no tome argumentos, entonces\r\n"
"debería, incluso si es funcionalmente idéntico al predeterminado."
#: src\idioms/ctor.md:97
#, fuzzy
msgid ""
"**Hint:** The advantage of implementing or deriving `Default` is that your "
"type\r\n"
"can now be used where a `Default` implementation is required, most "
"prominently,\r\n"
"any of the [`*or_default` functions in the standard library][std-or-default]."
msgstr ""
"**Sugerencia:** La ventaja de implementar o derivar `Default` es que su "
"tipo\r\n"
"ahora se puede usar donde se requiere una implementación 'Predeterminada', "
"más prominentemente,\r\n"
"cualquiera de las funciones [`*or_default` en la biblioteca "
"estándar][std-or-default]."
#: src\idioms/ctor.md:101
#, fuzzy
msgid "## See also\r"
msgstr "## Ver también\r"
#: src\idioms/ctor.md:103
#, fuzzy
msgid ""
"- The [default idiom](default.md) for a more in-depth description of the\r\n"
" `Default` trait.\r\n"
"\r\n"
"- The [builder pattern](../patterns/creational/builder.md) for "
"constructing\r\n"
" objects where there are multiple configurations.\r\n"
"\r\n"
"- [API Guidelines/C-COMMON-TRAITS][API Guidelines/C-COMMON-TRAITS] for\r\n"
" implementing both, `Default` and `new`.\r\n"
"\r"
msgstr ""
"- El [modismo predeterminado](default.md) para una descripción más detallada "
"del\r\n"
" Rasgo 'predeterminado'.\r\n"
"\r\n"
"- El [patrón del constructor] (../patterns/creational/builder.md) para "
"construir\r\n"
" objetos donde hay múltiples configuraciones.\r\n"
"\r\n"
"- [Directrices API/C-COMMON-TRAITS][Directrices API/C-COMMON-TRAITS] para\r\n"
" implementando ambos, `Predeterminado` y `nuevo`.\r\n"
"\r"
#: src\idioms/default.md:1
#, fuzzy
msgid "# The `Default` Trait"
msgstr "# El rasgo `Por defecto`"
#: src\idioms/default.md:5
msgid ""
"Many types in Rust have a [constructor]. However, this is _specific_ to the\n"
"type; Rust cannot abstract over \"everything that has a `new()` method\". "
"To\n"
"allow this, the [`Default`] trait was conceived, which can be used with\n"
"containers and other generic types (e.g. see "
"[`Option::unwrap_or_default()`]).\n"
"Notably, some containers already implement it where applicable."
msgstr ""
#: src\idioms/default.md:11
#, fuzzy
msgid ""
"Not only do one-element containers like `Cow`, `Box` or `Arc` implement\n"
"`Default` for contained `Default` types, one can automatically\n"
"`#[derive(Default)]` for structs whose fields all implement it, so the more\n"
"types implement `Default`, the more useful it becomes."
msgstr ""
"No solo implementan contenedores de un elemento como `Cow`, `Box` o `Arc`\n"
"'Predeterminado' para los tipos 'Predeterminados' contenidos, uno puede "
"automáticamente\n"
"`#[derive(Default)]` para estructuras cuyos campos lo implementan, así que "
"cuanto más\n"
"tipos implementan `Default`, más útil se vuelve."
#: src\idioms/default.md:16
#, fuzzy
msgid ""
"On the other hand, constructors can take multiple arguments, while the\n"
"`default()` method does not. There can even be multiple constructors with\n"
"different names, but there can only be one `Default` implementation per type."
msgstr ""
"Por otro lado, los constructores pueden tomar múltiples argumentos, mientras "
"que los\n"
"El método `default()` no lo hace. Incluso puede haber múltiples "
"constructores con\n"
"nombres diferentes, pero solo puede haber una implementación "
"`Predeterminada` por tipo."
#: src\idioms/default.md:22
msgid ""
"```rust\n"
"use std::{path::PathBuf, time::Duration};\n"
"\n"
"// note that we can simply auto-derive Default here.\n"
"#[derive(Default, Debug, PartialEq)]\n"
"struct MyConfiguration {\n"
" // Option defaults to None\n"
" output: Option<PathBuf>,\n"
" // Vecs default to empty vector\n"
" search_path: Vec<PathBuf>,\n"
" // Duration defaults to zero time\n"
" timeout: Duration,\n"
" // bool defaults to false\n"
" check: bool,\n"
"}\n"
"\n"
"impl MyConfiguration {\n"
" // add setters here\n"
"}\n"
"\n"
"fn main() {\n"
" // construct a new instance with default values\n"
" let mut conf = MyConfiguration::default();\n"
" // do something with conf here\n"
" conf.check = true;\n"
" println!(\"conf = {:#?}\", conf);\n"
" \n"
" // partial initialization with default values, creates the same "
"instance\n"
" let conf1 = MyConfiguration {\n"
" check: true,\n"
" ..Default::default()\n"
" };\n"
" assert_eq!(conf, conf1);\n"
"}\n"
"```"
msgstr ""
#: src\idioms/default.md:60
#, fuzzy
msgid ""
"- The [constructor] idiom is another way to generate instances that may or "
"may\n"
" not be \"default\"\n"
"- The [`Default`] documentation (scroll down for the list of implementors)\n"
"- [`Option::unwrap_or_default()`]\n"
"- [`derive(new)`]"
msgstr ""
"- El lenguaje [constructor] es otra forma de generar instancias que pueden o "
"pueden\n"
" no ser \"predeterminado\"\n"
"- La documentación [`Default`] (desplácese hacia abajo para ver la lista de "
"implementadores)\n"
"- [`Opción::unwrap_or_default()`]\n"
"- [`derivar(nuevo)`]"
#: src\idioms/deref.md:1
#, fuzzy
msgid "# Collections are smart pointers"
msgstr "# Las colecciones son punteros inteligentes"
#: src\idioms/deref.md:5
#, fuzzy
msgid ""
"Use the [`Deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html)\n"
"trait to treat collections like smart pointers, offering owning\n"
"and borrowed views of data."
msgstr ""
"Utilice [`Deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html)\n"
"rasgo para tratar las colecciones como punteros inteligentes, ofreciendo "
"propiedad\n"
"y vistas prestadas de datos."
#: src\idioms/deref.md:11
msgid ""
"```rust,ignore\n"
"use std::ops::Deref;\n"
"\n"
"struct Vec<T> {\n"
" data: RawVec<T>,\n"
" //..\n"
"}\n"
"\n"
"impl<T> Deref for Vec<T> {\n"
" type Target = [T];\n"
"\n"
" fn deref(&self) -> &[T] {\n"
" //..\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\idioms/deref.md:28
#, fuzzy
msgid ""
"A `Vec<T>` is an owning collection of `T`s, while a slice (`&[T]`) is a "
"borrowed\n"
"collection of `T`s. Implementing `Deref` for `Vec` allows implicit "
"dereferencing\n"
"from `&Vec<T>` to `&[T]` and includes the relationship in auto-derefencing\n"
"searches. Most methods you might expect to be implemented for `Vec`s are "
"instead\n"
"implemented for slices."
msgstr ""
"Un `Vec<T>` es una colección propietaria de `T`s, mientras que un segmento "
"(`&[T]`) es un préstamo\n"
"colección de `T`s. La implementación de `Deref` para `Vec` permite la "
"desreferenciación implícita\n"
"de `&Vec<T>` a `&[T]` e incluye la relación en la eliminación automática de "
"referencias\n"
"búsquedas. La mayoría de los métodos que podría esperar que se implementen "
"para `Vec`s son en su lugar\n"
"implementado para rebanadas."
#: src\idioms/deref.md:34
#, fuzzy
msgid "Also `String` and `&str` have a similar relation."
msgstr "También `String` y `&str` tienen una relación similar."
#: src\idioms/deref.md:36 src\idioms/dtor-finally.md:32
#: src\idioms/mem-replace.md:57 src\idioms/on-stack-dyn-dispatch.md:37
#: src\idioms/ffi/accepting-strings.md:12 src\idioms/ffi/passing-strings.md:14
#: src\idioms/return-consumed-arg-on-error.md:43
#: src\patterns/behavioural/command.md:8
#: src\patterns/behavioural/interpreter.md:16
#: src\patterns/behavioural/newtype.md:56 src\patterns/behavioural/RAII.md:72
#: src\patterns/behavioural/strategy.md:19
#: src\patterns/behavioural/visitor.md:72 src\patterns/creational/builder.md:63
#: src\patterns/creational/fold.md:73
#: src\patterns/structural/compose-structs.md:71 src\patterns/ffi/export.md:15
#: src\anti_patterns/borrow_clone.md:30
#, fuzzy
msgid "## Motivation"
msgstr "## Motivación"
#: src\idioms/deref.md:38
#, fuzzy
msgid ""
"Ownership and borrowing are key aspects of the Rust language. Data "
"structures\n"
"must account for these semantics properly to give a good user\n"
"experience. When implementing a data structure that owns its data, offering "
"a\n"
"borrowed view of that data allows for more flexible APIs."
msgstr ""
"La propiedad y el préstamo son aspectos clave del lenguaje Rust. Estructuras "
"de datos\n"
"debe tener en cuenta esta semántica correctamente para dar a un buen "
"usuario\n"
"experiencia. Al implementar una estructura de datos que posee sus datos, "
"ofrecer una\n"
"La vista prestada de esos datos permite API más flexibles."
#: src\idioms/deref.md:45
#, fuzzy
msgid ""
"Most methods can be implemented only for the borrowed view, they are then\n"
"implicitly available for the owning view."
msgstr ""
"La mayoría de los métodos se pueden implementar solo para la vista prestada, "
"luego se\n"
"implícitamente disponible para la vista propietaria."
#: src\idioms/deref.md:48
#, fuzzy
msgid "Gives clients a choice between borrowing or taking ownership of data."
msgstr ""
"Brinda a los clientes la opción de tomar prestados o tomar posesión de los "
"datos."
#: src\idioms/deref.md:52
#, fuzzy
msgid ""
"Methods and traits only available via dereferencing are not taken into "
"account\n"
"when bounds checking, so generic programming with data structures using "
"this\n"
"pattern can get complex (see the `Borrow` and `AsRef` traits, etc.)."
msgstr ""
"No se tienen en cuenta los métodos y características que solo están "
"disponibles a través de la desreferenciación.\n"
"cuando se verifican los límites, por lo que la programación genérica con "
"estructuras de datos usa esto\n"
"El patrón puede volverse complejo (ver los rasgos `Borrow` y `AsRef`, etc.)."
#: src\idioms/deref.md:56 src\idioms/dtor-finally.md:61
#: src\idioms/mem-replace.md:97 src\idioms/on-stack-dyn-dispatch.md:68
#: src\idioms/priv-extend.md:85 src\patterns/behavioural/command.md:203
#: src\patterns/behavioural/interpreter.md:103
#: src\patterns/behavioural/newtype.md:85 src\patterns/behavioural/RAII.md:83
#: src\patterns/behavioural/strategy.md:110
#: src\patterns/behavioural/visitor.md:79 src\patterns/creational/builder.md:81
#: src\patterns/creational/fold.md:85
#: src\patterns/structural/compose-structs.md:89 src\anti_patterns/deref.md:102
#, fuzzy
msgid "## Discussion"
msgstr "## Discusión"
#: src\idioms/deref.md:58
#, fuzzy
msgid ""
"Smart pointers and collections are analogous: a smart pointer points to a "
"single\n"
"object, whereas a collection points to many objects. From the point of view "
"of\n"
"the type system, there is little difference between the two. A collection "
"owns\n"
"its data if the only way to access each datum is via the collection and the\n"
"collection is responsible for deleting the data (even in cases of shared\n"
"ownership, some kind of borrowed view may be appropriate). If a collection "
"owns\n"
"its data, it is usually useful to provide a view of the data as borrowed so "
"that\n"
"it can be referenced multiple times."
msgstr ""
"Los punteros inteligentes y las colecciones son análogos: un puntero "
"inteligente apunta a un solo\n"
"objeto, mientras que una colección apunta a muchos objetos. Desde el punto "
"de vista de\n"
"el sistema de tipos, hay poca diferencia entre los dos. Una colección posee\n"
"sus datos si la única forma de acceder a cada dato es a través de la "
"recopilación y el\n"
"recogida es responsable de la eliminación de los datos (incluso en los casos "
"de compartir\n"
"propiedad, algún tipo de vista prestada puede ser apropiado). Si una "
"colección posee\n"
"sus datos, por lo general es útil proporcionar una vista de los datos como "
"prestados para que\n"
"puede ser referenciado varias veces."
#: src\idioms/deref.md:67
#, fuzzy
msgid ""
"Most smart pointers (e.g., `Foo<T>`) implement `Deref<Target=T>`. However,\n"
"collections will usually dereference to a custom type. `[T]` and `str` have "
"some\n"
"language support, but in the general case, this is not necessary. `Foo<T>` "
"can\n"
"implement `Deref<Target=Bar<T>>` where `Bar` is a dynamically sized type "
"and\n"
"`&Bar<T>` is a borrowed view of the data in `Foo<T>`."
msgstr ""
"La mayoría de los punteros inteligentes (por ejemplo, `Foo<T>`) implementan "
"`Deref<Target=T>`. Sin embargo,\n"
"las colecciones por lo general dejarán de hacer referencia a un tipo "
"personalizado. `[T]` y `str` tienen algunos\n"
"soporte de idioma, pero en el caso general, esto no es necesario. `Foo<T>` "
"puede\n"
"implementar `Deref<Target=Bar<T>>` donde `Bar` es un tipo de tamaño dinámico "
"y\n"
"`&Bar<T>` es una vista prestada de los datos en `Foo<T>`."
#: src\idioms/deref.md:73
#, fuzzy
msgid ""
"Commonly, ordered collections will implement `Index` for `Range`s to "
"provide\n"
"slicing syntax. The target will be the borrowed view."
msgstr ""
"Comúnmente, las colecciones ordenadas implementarán `Index` para `Range`s "
"para proporcionar\n"
"sintaxis de corte. El objetivo será la vista prestada."
#: src\idioms/deref.md:78
#, fuzzy
msgid ""
"- [Deref polymorphism anti-pattern](../anti_patterns/deref.md).\n"
"- [Documentation for `Deref` "
"trait](https://doc.rust-lang.org/std/ops/trait.Deref.html)."
msgstr ""
"- [Antipatrón de polimorfismo de deref](../anti_patterns/deref.md).\n"
"- [Documentación para el rasgo "
"`Deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html)."
#: src\idioms/dtor-finally.md:1
#, fuzzy
msgid "# Finalisation in destructors"
msgstr "# Finalización en destructores"
#: src\idioms/dtor-finally.md:5
#, fuzzy
msgid ""
"Rust does not provide the equivalent to `finally` blocks - code that will "
"be\n"
"executed no matter how a function is exited. Instead, an object's destructor "
"can\n"
"be used to run code that must be run before exit."
msgstr ""
"Rust no proporciona el equivalente a los bloques `finally` - código que "
"será\n"
"se ejecuta sin importar cómo se sale de una función. En cambio, el "
"destructor de un objeto puede\n"
"usarse para ejecutar código que debe ejecutarse antes de salir."
#: src\idioms/dtor-finally.md:11
msgid ""
"```rust,ignore\n"
"fn bar() -> Result<(), ()> {\n"
" // These don't need to be defined inside the function.\n"
" struct Foo;\n"
"\n"
" // Implement a destructor for Foo.\n"
" impl Drop for Foo {\n"
" fn drop(&mut self) {\n"
" println!(\"exit\");\n"
" }\n"
" }\n"
"\n"
" // The dtor of _exit will run however the function `bar` is exited.\n"
" let _exit = Foo;\n"
" // Implicit return with `?` operator.\n"
" baz()?;\n"
" // Normal return.\n"
" Ok(())\n"
"}\n"
"```"
msgstr ""
#: src\idioms/dtor-finally.md:34
#, fuzzy
msgid ""
"If a function has multiple return points, then executing code on exit "
"becomes\n"
"difficult and repetitive (and thus bug-prone). This is especially the case "
"where\n"
"return is implicit due to a macro. A common case is the `?` operator which\n"
"returns if the result is an `Err`, but continues if it is `Ok`. `?` is used "
"as\n"
"an exception handling mechanism, but unlike Java (which has `finally`), "
"there is\n"
"no way to schedule code to run in both the normal and exceptional cases.\n"
"Panicking will also exit a function early."
msgstr ""
"Si una función tiene varios puntos de retorno, la ejecución del código al "
"salir se vuelve\n"
"difícil y repetitivo (y por lo tanto propenso a errores). Este es "
"especialmente el caso donde\n"
"el retorno es implícito debido a una macro. Un caso común es el operador `?` "
"que\n"
"devuelve si el resultado es `Err`, pero continúa si es `Ok`. `?` se utiliza "
"como\n"
"un mecanismo de manejo de excepciones, pero a diferencia de Java (que tiene "
"`finally`), hay\n"
"no hay forma de programar el código para que se ejecute tanto en casos "
"normales como excepcionales.\n"
"El pánico también hará que salga de una función antes de tiempo."
#: src\idioms/dtor-finally.md:44
#, fuzzy
msgid ""
"Code in destructors will (nearly) always be run - copes with panics, early\n"
"returns, etc."
msgstr ""
"El código en los destructores (casi) siempre se ejecutará: hace frente a "
"pánicos, temprano\n"
"devoluciones, etc"
#: src\idioms/dtor-finally.md:49
#, fuzzy
msgid ""
"It is not guaranteed that destructors will run. For example, if there is an\n"
"infinite loop in a function or if running a function crashes before exit.\n"
"Destructors are also not run in the case of a panic in an already panicking\n"
"thread. Therefore, destructors cannot be relied on as finalizers where it "
"is\n"
"absolutely essential that finalisation happens."
msgstr ""
"No se garantiza que los destructores funcionen. Por ejemplo, si hay un\n"
"bucle infinito en una función o si la ejecución de una función falla antes "
"de salir.\n"
"Los destructores tampoco se ejecutan en caso de pánico en un país que ya "
"está en pánico.\n"
"hilo. Por lo tanto, no se puede confiar en los destructores como "
"finalizadores donde es\n"
"absolutamente esencial que ocurra la finalización."
#: src\idioms/dtor-finally.md:55
#, fuzzy
msgid ""
"This pattern introduces some hard to notice, implicit code. Reading a "
"function\n"
"gives no clear indication of destructors to be run on exit. This can make\n"
"debugging tricky."
msgstr ""
"Este patrón introduce un código implícito difícil de notar. Lectura de una "
"función\n"
"no da una indicación clara de los destructores que se ejecutarán en la "
"salida. esto puede hacer\n"
"depuración complicada."
#: src\idioms/dtor-finally.md:59
#, fuzzy
msgid ""
"Requiring an object and `Drop` impl just for finalisation is heavy on "
"boilerplate."
msgstr ""
"Requerir un objeto y el impl `Drop` solo para la finalización es pesado en "
"el modelo."
#: src\idioms/dtor-finally.md:63
#, fuzzy
msgid ""
"There is some subtlety about how exactly to store the object used as a\n"
"finalizer. It must be kept alive until the end of the function and must then "
"be\n"
"destroyed. The object must always be a value or uniquely owned pointer "
"(e.g.,\n"
"`Box<Foo>`). If a shared pointer (such as `Rc`) is used, then the finalizer "
"can\n"
"be kept alive beyond the lifetime of the function. For similar reasons, the\n"
"finalizer should not be moved or returned."
msgstr ""
"Hay cierta sutileza sobre cómo almacenar exactamente el objeto utilizado "
"como\n"
"finalizador Debe mantenerse vivo hasta el final de la función y luego debe "
"ser\n"
"destruido. El objeto siempre debe ser un valor o un puntero de propiedad "
"única (por ejemplo,\n"
"`Cuadro<Foo>`). Si se usa un puntero compartido (como `Rc`), entonces el "
"finalizador puede\n"
"mantenerse vivo más allá del tiempo de vida de la función. Por razones "
"similares, el\n"
"el finalizador no debe moverse ni devolverse."
#: src\idioms/dtor-finally.md:70
#, fuzzy
msgid ""
"The finalizer must be assigned into a variable, otherwise it will be "
"destroyed\n"
"immediately, rather than when it goes out of scope. The variable name must "
"start\n"
"with `_` if the variable is only used as a finalizer, otherwise the "
"compiler\n"
"will warn that the finalizer is never used. However, do not call the "
"variable\n"
"`_` with no suffix - in that case it will be destroyed immediately."
msgstr ""
"El finalizador debe asignarse a una variable, de lo contrario, se destruirá\n"
"inmediatamente, en lugar de cuando se sale del alcance. El nombre de la "
"variable debe comenzar\n"
"con `_` si la variable solo se usa como finalizador, de lo contrario, el "
"compilador\n"
"advertirá que el finalizador nunca se utiliza. Sin embargo, no llame a la "
"variable\n"
"`_` sin sufijo - en ese caso será destruido inmediatamente."
#: src\idioms/dtor-finally.md:76
#, fuzzy
msgid ""
"In Rust, destructors are run when an object goes out of scope. This happens\n"
"whether we reach the end of block, there is an early return, or the program\n"
"panics. When panicking, Rust unwinds the stack running destructors for each\n"
"object in each stack frame. So, destructors get called even if the panic "
"happens\n"
"in a function being called."
msgstr ""
"En Rust, los destructores se ejecutan cuando un objeto queda fuera del "
"alcance. Esto pasa\n"
"ya sea que lleguemos al final del bloque, que haya un regreso anticipado o "
"que el programa\n"
"entra en pánico Cuando entra en pánico, Rust desenrolla la pila ejecutando "
"destructores para cada\n"
"objeto en cada marco de pila. Entonces, se llama a los destructores incluso "
"si ocurre el pánico.\n"
"en una función que se está llamando."
#: src\idioms/dtor-finally.md:82
#, fuzzy
msgid ""
"If a destructor panics while unwinding, there is no good action to take, so "
"Rust\n"
"aborts the thread immediately, without running further destructors. This "
"means\n"
"that destructors are not absolutely guaranteed to run. It also means that "
"you\n"
"must take extra care in your destructors not to panic, since it could leave\n"
"resources in an unexpected state."
msgstr ""
"Si un destructor entra en pánico mientras se desenrolla, no hay una buena "
"acción que tomar, por lo que Rust\n"
"aborta el subproceso inmediatamente, sin ejecutar más destructores. Esto "
"significa\n"
"que los destructores no están absolutamente garantizados para funcionar. "
"También significa que usted\n"
"debe tener especial cuidado en sus destructores para no entrar en pánico, ya "
"que podría salir\n"
"recursos en un estado inesperado."
#: src\idioms/dtor-finally.md:90
#, fuzzy
msgid "[RAII guards](../patterns/behavioural/RAII.md)."
msgstr "[Guardias RAII](../patrones/comportamiento/RAII.md)."
#: src\idioms/mem-replace.md:1
#, fuzzy
msgid "# `mem::{take(_), replace(_)}` to keep owned values in changed enums"
msgstr ""
"# `mem::{take(_), replace(_)}` para mantener los valores propios en las "
"enumeraciones modificadas"
#: src\idioms/mem-replace.md:5
#, fuzzy
msgid ""
"Say we have a `&mut MyEnum` which has (at least) two variants,\n"
"`A { name: String, x: u8 }` and `B { name: String }`. Now we want to change\n"
"`MyEnum::A` to a `B` if `x` is zero, while keeping `MyEnum::B` intact."
msgstr ""
"Digamos que tenemos un `&mut MyEnum` que tiene (al menos) dos variantes,\n"
"`A { nombre: Cadena, x: u8 }` y `B { nombre: Cadena }`. Ahora queremos "
"cambiar\n"
"`MyEnum::A` a `B` si `x` es cero, manteniendo `MyEnum::B` intacto."
#: src\idioms/mem-replace.md:9
#, fuzzy
msgid "We can do this without cloning the `name`."
msgstr "Podemos hacer esto sin clonar el `nombre`."
#: src\idioms/mem-replace.md:13
msgid ""
"```rust\n"
"use std::mem;\n"
"\n"
"enum MyEnum {\n"
" A { name: String, x: u8 },\n"
" B { name: String }\n"
"}\n"
"\n"
"fn a_to_b(e: &mut MyEnum) {\n"
" if let MyEnum::A { name, x: 0 } = e {\n"
" // this takes out our `name` and put in an empty String instead\n"
" // (note that empty strings don't allocate).\n"
" // Then, construct the new enum variant (which will\n"
" // be assigned to `*e`).\n"
" *e = MyEnum::B { name: mem::take(name) }\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\idioms/mem-replace.md:32
#, fuzzy
msgid "This also works with more variants:"
msgstr "Esto también funciona con más variantes:"
#: src\idioms/mem-replace.md:34
msgid ""
"```rust\n"
"use std::mem;\n"
"\n"
"enum MultiVariateEnum {\n"
" A { name: String },\n"
" B { name: String },\n"
" C,\n"
" D\n"
"}\n"
"\n"
"fn swizzle(e: &mut MultiVariateEnum) {\n"
" use MultiVariateEnum::*;\n"
" *e = match e {\n"
" // Ownership rules do not allow taking `name` by value, but we "
"cannot\n"
" // take the value out of a mutable reference, unless we replace it:\n"
" A { name } => B { name: mem::take(name) },\n"
" B { name } => A { name: mem::take(name) },\n"
" C => D,\n"
" D => C\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\idioms/mem-replace.md:59
#, fuzzy
msgid ""
"When working with enums, we may want to change an enum value in place, "
"perhaps\n"
"to another variant. This is usually done in two phases to keep the borrow\n"
"checker happy. In the first phase, we observe the existing value and look "
"at\n"
"its parts to decide what to do next. In the second phase we may "
"conditionally\n"
"change the value (as in the example above)."
msgstr ""
"Al trabajar con enumeraciones, es posible que deseemos cambiar un valor de "
"enumeración en su lugar, tal vez\n"
"a otra variante. Esto generalmente se hace en dos fases para mantener el "
"préstamo\n"
"corrector feliz. En la primera fase, observamos el valor existente y "
"miramos\n"
"sus partes para decidir qué hacer a continuación. En la segunda fase podemos "
"condicionalmente\n"
"cambiar el valor (como en el ejemplo anterior)."
#: src\idioms/mem-replace.md:65
#, fuzzy
msgid ""
"The borrow checker won't allow us to take out `name` of the enum (because\n"
"_something_ must be there.) We could of course `.clone()` name and put the "
"clone\n"
"into our `MyEnum::B`, but that would be an instance of the [Clone to satisfy "
"the borrow checker](../anti_patterns/borrow_clone.md) anti-pattern. Anyway, "
"we\n"
"can avoid the extra allocation by changing `e` with only a mutable borrow."
msgstr ""
"El verificador de préstamos no nos permitirá sacar el `nombre` de la "
"enumeración (porque\n"
"_algo_ debe estar allí.) Podríamos, por supuesto, el nombre `.clone()` y "
"poner el clon\n"
"en nuestro `MyEnum::B`, pero eso sería una instancia del antipatrón [Clonar "
"para satisfacer el comprobador de "
"préstamos](../anti_patterns/borrow_clone.md). De todos modos, nosotros\n"
"puede evitar la asignación adicional cambiando `e` con solo un préstamo "
"mutable."
#: src\idioms/mem-replace.md:70
#, fuzzy
msgid ""
"`mem::take` lets us swap out the value, replacing it with it's default "
"value,\n"
"and returning the previous value. For `String`, the default value is an "
"empty\n"
"`String`, which does not need to allocate. As a result, we get the original\n"
"`name` _as an owned value_. We can then wrap this in another enum."
msgstr ""
"`mem::take` nos permite intercambiar el valor, reemplazándolo con su valor "
"predeterminado,\n"
"y devolviendo el valor anterior. Para `String`, el valor predeterminado es "
"un vacío\n"
"`String`, que no es necesario asignar. Como resultado, obtenemos el "
"original.\n"
"`nombre` _como valor propio_. Luego podemos envolver esto en otra "
"enumeración."
#: src\idioms/mem-replace.md:75
#, fuzzy
msgid ""
"**NOTE:** `mem::replace` is very similar, but allows us to specify what to\n"
"replace the value with. An equivalent to our `mem::take` line would be\n"
"`mem::replace(name, String::new())`."
msgstr ""
"**NOTA:** `mem::replace` es muy similar, pero nos permite especificar qué\n"
"reemplace el valor con. Un equivalente a nuestra línea `mem::take` sería\n"
"`mem::replace(nombre, Cadena::nuevo())`."
#: src\idioms/mem-replace.md:79
#, fuzzy
msgid ""
"Note, however, that if we are using an `Option` and want to replace its\n"
"value with a `None`, `Option`s `take()` method provides a shorter and\n"
"more idiomatic alternative."
msgstr ""
"Tenga en cuenta, sin embargo, que si estamos usando una `Opción` y queremos "
"reemplazar su\n"
"valor con `Ninguno`, el método `take()` de `Option` proporciona un método "
"más corto y\n"
"alternativa más idiomática."
#: src\idioms/mem-replace.md:85
#, fuzzy
msgid ""
"Look ma, no allocation! Also you may feel like Indiana Jones while doing it."
msgstr ""
"¡Mira mamá, no hay asignación! También puedes sentirte como Indiana Jones "
"mientras lo haces."
#: src\idioms/mem-replace.md:89
#, fuzzy
msgid ""
"This gets a bit wordy. Getting it wrong repeatedly will make you hate the\n"
"borrow checker. The compiler may fail to optimize away the double store,\n"
"resulting in reduced performance as opposed to what you'd do in unsafe\n"
"languages."
msgstr ""
"Esto se pone un poco prolijo. Hacerlo mal repetidamente te hará odiar el\n"
"prestador de cheques. El compilador puede fallar al optimizar el almacén "
"doble,\n"
"lo que resulta en un rendimiento reducido en comparación con lo que haría en "
"un entorno inseguro\n"
"idiomas"
#: src\idioms/mem-replace.md:94
#, fuzzy
msgid ""
"Furthermore, the type you are taking needs to implement the [`Default` "
"trait](./default.md). However, if the type you're working with doesn't\n"
"implement this, you can instead use `mem::replace`."
msgstr ""
"Además, el tipo que está tomando debe implementar el [rasgo "
"`Predeterminado`] (./default.md). Sin embargo, si el tipo con el que está "
"trabajando no\n"
"implementar esto, en su lugar puede usar `mem::replace`."
#: src\idioms/mem-replace.md:99
#, fuzzy
msgid ""
"This pattern is only of interest in Rust. In GC'd languages, you'd take the\n"
"reference to the value by default (and the GC would keep track of refs), and "
"in\n"
"other low-level languages like C you'd simply alias the pointer and fix "
"things\n"
"later."
msgstr ""
"Este patrón solo es de interés en Rust. En los idiomas de GC, tomarías la\n"
"referencia al valor por defecto (y el GC haría un seguimiento de las "
"referencias), y en\n"
"otros lenguajes de bajo nivel como C simplemente haría un alias del puntero "
"y arreglaría las cosas\n"
"más tarde."
#: src\idioms/mem-replace.md:104
#, fuzzy
msgid ""
"However, in Rust, we have to do a little more work to do this. An owned "
"value\n"
"may only have one owner, so to take it out, we need to put something back in "
"\n"
"like Indiana Jones, replacing the artifact with a bag of sand."
msgstr ""
"Sin embargo, en Rust, tenemos que trabajar un poco más para hacer esto. Un "
"valor propio\n"
"Es posible que solo tenga un propietario, por lo que para sacarlo, debemos "
"volver a colocar algo:\n"
"como Indiana Jones, reemplazando el artefacto con una bolsa de arena."
#: src\idioms/mem-replace.md:110
#, fuzzy
msgid ""
"This gets rid of the [Clone to satisfy the borrow "
"checker](../anti_patterns/borrow_clone.md)\n"
"anti-pattern in a specific case."
msgstr ""
"Esto elimina el [Clonar para satisfacer el comprobador de "
"préstamo](../anti_patterns/borrow_clone.md)\n"
"anti-patrón en un caso específico."
#: src\idioms/on-stack-dyn-dispatch.md:1
#, fuzzy
msgid "# On-Stack Dynamic Dispatch"
msgstr "# Envío dinámico en la pila"
#: src\idioms/on-stack-dyn-dispatch.md:5
#, fuzzy
msgid ""
"We can dynamically dispatch over multiple values, however, to do so, we "
"need\n"
"to declare multiple variables to bind differently-typed objects. To extend "
"the\n"
"lifetime as necessary, we can use deferred conditional initialization, as "
"seen\n"
"below:"
msgstr ""
"Podemos despachar dinámicamente sobre múltiples valores, sin embargo, para "
"hacerlo, necesitamos\n"
"para declarar múltiples variables para vincular objetos de diferente tipo. "
"para extender el\n"
"vida útil según sea necesario, podemos usar la inicialización condicional "
"diferida, como se ve\n"
"abajo:"
#: src\idioms/on-stack-dyn-dispatch.md:12
msgid ""
"```rust\n"
"use std::io;\n"
"use std::fs;\n"
"\n"
"# fn main() -> Result<(), Box<dyn std::error::Error>> {\n"
"# let arg = \"-\";\n"
"\n"
"// These must live longer than `readable`, and thus are declared first:\n"
"let (mut stdin_read, mut file_read);\n"
"\n"
"// We need to ascribe the type to get dynamic dispatch.\n"
"let readable: &mut dyn io::Read = if arg == \"-\" {\n"
" stdin_read = io::stdin();\n"
" &mut stdin_read\n"
"} else {\n"
" file_read = fs::File::open(arg)?;\n"
" &mut file_read\n"
"};\n"
"\n"
"// Read from `readable` here.\n"
"\n"
"# Ok(())\n"
"# }\n"
"```"
msgstr ""
#: src\idioms/on-stack-dyn-dispatch.md:39
#, fuzzy
msgid ""
"Rust monomorphises code by default. This means a copy of the code will be\n"
"generated for each type it is used with and optimized independently. While "
"this\n"
"allows for very fast code on the hot path, it also bloats the code in "
"places\n"
"where performance is not of the essence, thus costing compile time and "
"cache\n"
"usage."
msgstr ""
"Rust monomorfiza el código por defecto. Esto significa que una copia del "
"código será\n"
"generado para cada tipo con el que se utiliza y optimizado de forma "
"independiente. Mientras esto\n"
"permite un código muy rápido en la ruta activa, también infla el código en "
"algunos lugares\n"
"donde el rendimiento no es esencial, lo que cuesta tiempo de compilación y "
"caché\n"
"uso."
#: src\idioms/on-stack-dyn-dispatch.md:45
#, fuzzy
msgid ""
"Luckily, Rust allows us to use dynamic dispatch, but we have to explicitly "
"ask\n"
"for it."
msgstr ""
"Afortunadamente, Rust nos permite usar el envío dinámico, pero tenemos que "
"preguntar explícitamente\n"
"para ello."
#: src\idioms/on-stack-dyn-dispatch.md:50
#, fuzzy
msgid ""
"We do not need to allocate anything on the heap. Neither do we need to\n"
"initialize something we won't use later, nor do we need to monomorphize the\n"
"whole code that follows to work with both `File` or `Stdin`."
msgstr ""
"No necesitamos asignar nada en el montón. Tampoco necesitamos\n"
"inicializar algo que no usaremos más tarde, ni necesitamos monomorfizar el\n"
"código completo que sigue para trabajar con `File` o `Stdin`."
#: src\idioms/on-stack-dyn-dispatch.md:56
#, fuzzy
msgid "The code needs more moving parts than the `Box`-based version:"
msgstr "El código necesita más partes móviles que la versión basada en `Box`:"
#: src\idioms/on-stack-dyn-dispatch.md:58
msgid ""
"```rust,ignore\n"
"// We still need to ascribe the type for dynamic dispatch.\n"
"let readable: Box<dyn io::Read> = if arg == \"-\" {\n"
" Box::new(io::stdin())\n"
"} else {\n"
" Box::new(fs::File::open(arg)?)\n"
"};\n"
"// Read from `readable` here.\n"
"```"
msgstr ""
#: src\idioms/on-stack-dyn-dispatch.md:70
#, fuzzy
msgid ""
"Rust newcomers will usually learn that Rust requires all variables to be\n"
"initialized _before use_, so it's easy to overlook the fact that _unused_\n"
"variables may well be uninitialized. Rust works quite hard to ensure that "
"this\n"
"works out fine and only the initialized values are dropped at the end of "
"their\n"
"scope."
msgstr ""
"Los recién llegados a Rust generalmente aprenderán que Rust requiere que "
"todas las variables sean\n"
"inicializado _antes de su uso_, por lo que es fácil pasar por alto el hecho "
"de que _unused_\n"
"las variables bien pueden no estar inicializadas. Rust trabaja muy duro para "
"garantizar que esto\n"
"funciona bien y solo los valores inicializados se eliminan al final de su\n"
"alcance."
#: src\idioms/on-stack-dyn-dispatch.md:76
#, fuzzy
msgid "The example meets all the constraints Rust places on us:"
msgstr "El ejemplo cumple con todas las restricciones que Rust nos impone:"
#: src\idioms/on-stack-dyn-dispatch.md:78
#, fuzzy
msgid ""
"- All variables are initialized before using (in this case borrowing) them\n"
"- Each variable only holds values of a single type. In our example, `stdin` "
"is\n"
" of type `Stdin`, `file` is of type `File` and `readable` is of type `&mut "
"dyn Read`\n"
"- Each borrowed value outlives all the references borrowed from it"
msgstr ""
"- Todas las variables se inicializan antes de usarlas (en este caso, "
"tomarlas prestadas)\n"
"- Cada variable solo contiene valores de un solo tipo. En nuestro ejemplo, "
"`stdin` es\n"
" de tipo `Stdin`, `file` es de tipo `File` y `readable` es de tipo `&mut "
"dyn Read`\n"
"- Cada valor prestado sobrevive a todas las referencias tomadas de él"
#: src\idioms/on-stack-dyn-dispatch.md:85
#, fuzzy
msgid ""
"- [Finalisation in destructors](dtor-finally.md) and\n"
" [RAII guards](../patterns/behavioural/RAII.md) can benefit from tight "
"control over\n"
" lifetimes.\n"
"- For conditionally filled `Option<&T>`s of (mutable) references, one can\n"
" initialize an `Option<T>` directly and use its [`.as_ref()`] method to get "
"an\n"
" optional reference."
msgstr ""
"- [Finalización en destructores](dtor-finally.md) y\n"
" [Guardias RAII](../patterns/behavioural/RAII.md) pueden beneficiarse de un "
"control estricto sobre\n"
" vidas\n"
"- Para `Option<&T>`s de referencias (mutables) rellenadas condicionalmente, "
"se puede\n"
" inicialice una `Option<T>` directamente y use su método [`.as_ref()`] para "
"obtener una\n"
" referencia opcional."
#: src\idioms/ffi/intro.md:1
#, fuzzy
msgid "# FFI Idioms"
msgstr "# modismos FFI"
#: src\idioms/ffi/intro.md:3
#, fuzzy
msgid ""
"Writing FFI code is an entire course in itself.\n"
"However, there are several idioms here that can act as pointers, and avoid\n"
"traps for inexperienced users of `unsafe` Rust."
msgstr ""
"Escribir código FFI es un curso completo en sí mismo.\n"
"Sin embargo, aquí hay varios modismos que pueden actuar como indicadores y "
"evitar\n"
"trampas para usuarios inexpertos de Rust `inseguro`."
#: src\idioms/ffi/intro.md:7
#, fuzzy
msgid "This section contains idioms that may be useful when doing FFI."
msgstr "Esta sección contiene modismos que pueden ser útiles al hacer FFI."
#: src\idioms/ffi/intro.md:9
#, fuzzy
msgid ""
"1. [Idiomatic Errors](./errors.md) - Error handling with integer codes and\n"
" sentinel return values (such as `NULL` pointers)\n"
"\n"
"2. [Accepting Strings](./accepting-strings.md) with minimal unsafe code\n"
"\n"
"3. [Passing Strings](./passing-strings.md) to FFI functions"
msgstr ""
"1. [Errores idiomáticos](./errors.md) - Manejo de errores con códigos "
"enteros y\n"
" valores de retorno centinela (como punteros `NULL`)\n"
"\n"
"2. [Accepting Strings](./accepting-strings.md) con código inseguro mínimo\n"
"\n"
"3. [Pasar cadenas] (./pasar cadenas.md) a funciones FFI"
#: src\idioms/ffi/errors.md:1
#, fuzzy
msgid "# Error Handling in FFI"
msgstr "# Manejo de errores en FFI"
#: src\idioms/ffi/errors.md:5
#, fuzzy
msgid ""
"In foreign languages like C, errors are represented by return codes.\n"
"However, Rust's type system allows much more rich error information to be\n"
"captured and propogated through a full type."
msgstr ""
"En idiomas extranjeros como C, los errores se representan mediante códigos "
"de retorno.\n"
"Sin embargo, el sistema de tipos de Rust permite obtener información de "
"error mucho más rica.\n"
"capturado y propagado a través de un tipo completo."
#: src\idioms/ffi/errors.md:9
#, fuzzy
msgid ""
"This best practice shows different kinds of error codes, and how to expose "
"them\n"
"in a usable way:"
msgstr ""
"Esta práctica recomendada muestra diferentes tipos de códigos de error y "
"cómo exponerlos\n"
"de una manera utilizable:"
#: src\idioms/ffi/errors.md:12
#, fuzzy
msgid ""
"1. Flat Enums should be converted to integers and returned as codes.\n"
"2. Structured Enums should be converted to an integer code with a string "
"error\n"
" message for detail.\n"
"3. Custom Error Types should become \"transparent\", with a C representation."
msgstr ""
"1. Las enumeraciones planas deben convertirse en números enteros y "
"devolverse como códigos.\n"
"2. Las enumeraciones estructuradas deben convertirse a un código entero con "
"un error de cadena\n"
" mensaje para el detalle.\n"
"3. Los tipos de error personalizados deben volverse \"transparentes\", con "
"una representación C."
#: src\idioms/ffi/errors.md:17 src\idioms/ffi/accepting-strings.md:29
#: src\idioms/ffi/passing-strings.md:26 src\patterns/ffi/export.md:40
#: src\patterns/ffi/wrappers.md:23
#, fuzzy
msgid "## Code Example"
msgstr "## Ejemplo de código"
#: src\idioms/ffi/errors.md:19
#, fuzzy
msgid "### Flat Enums"
msgstr "### Enumeraciones planas"
#: src\idioms/ffi/errors.md:21
msgid ""
"```rust,ignore\n"
"enum DatabaseError {\n"
" IsReadOnly = 1, // user attempted a write operation\n"
" IOError = 2, // user should read the C errno() for what it was\n"
" FileCorrupted = 3, // user should run a repair tool to recover it\n"
"}\n"
"\n"
"impl From<DatabaseError> for libc::c_int {\n"
" fn from(e: DatabaseError) -> libc::c_int {\n"
" (e as i8).into()\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\idioms/ffi/errors.md:35
#, fuzzy
msgid "### Structured Enums"
msgstr "### Enumeraciones estructuradas"
#: src\idioms/ffi/errors.md:37
msgid ""
"```rust,ignore\n"
"pub mod errors {\n"
" enum DatabaseError {\n"
" IsReadOnly,\n"
" IOError(std::io::Error),\n"
" FileCorrupted(String), // message describing the issue\n"
" }\n"
"\n"
" impl From<DatabaseError> for libc::c_int {\n"
" fn from(e: DatabaseError) -> libc::c_int {\n"
" match e {\n"
" DatabaseError::IsReadOnly => 1,\n"
" DatabaseError::IOError(_) => 2,\n"
" DatabaseError::FileCorrupted(_) => 3,\n"
" }\n"
" }\n"
" }\n"
"}\n"
"\n"
"pub mod c_api {\n"
" use super::errors::DatabaseError;\n"
"\n"
" #[no_mangle]\n"
" pub extern \"C\" fn db_error_description(\n"
" e: *const DatabaseError\n"
" ) -> *mut libc::c_char {\n"
"\n"
" let error: &DatabaseError = unsafe {\n"
" // SAFETY: pointer lifetime is greater than the current stack "
"frame\n"
" &*e\n"
" };\n"
"\n"
" let error_str: String = match error {\n"
" DatabaseError::IsReadOnly => {\n"
" format!(\"cannot write to read-only database\");\n"
" }\n"
" DatabaseError::IOError(e) => {\n"
" format!(\"I/O Error: {}\", e);\n"
" }\n"
" DatabaseError::FileCorrupted(s) => {\n"
" format!(\"File corrupted, run repair: {}\", &s);\n"
" }\n"
" };\n"
"\n"
" let c_error = unsafe {\n"
" // SAFETY: copying error_str to an allocated buffer with a NUL\n"
" // character at the end\n"
" let mut malloc: *mut u8 = libc::malloc(error_str.len() + 1) as "
"*mut _;\n"
"\n"
" if malloc.is_null() {\n"
" return std::ptr::null_mut();\n"
" }\n"
"\n"
" let src = error_str.as_bytes().as_ptr();\n"
"\n"
" std::ptr::copy_nonoverlapping(src, malloc, error_str.len());\n"
"\n"
" std::ptr::write(malloc.add(error_str.len()), 0);\n"
"\n"
" malloc as *mut libc::c_char\n"
" };\n"
"\n"
" c_error\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\idioms/ffi/errors.md:104
#, fuzzy
msgid "### Custom Error Types"
msgstr "### Tipos de errores personalizados"
#: src\idioms/ffi/errors.md:106
msgid ""
"```rust,ignore\n"
"struct ParseError {\n"
" expected: char,\n"
" line: u32,\n"
" ch: u16\n"
"}\n"
"\n"
"impl ParseError { /* ... */ }\n"
"\n"
"/* Create a second version which is exposed as a C structure */\n"
"#[repr(C)]\n"
"pub struct parse_error {\n"
" pub expected: libc::c_char,\n"
" pub line: u32,\n"
" pub ch: u16\n"
"}\n"
"\n"
"impl From<ParseError> for parse_error {\n"
" fn from(e: ParseError) -> parse_error {\n"
" let ParseError { expected, line, ch } = e;\n"
" parse_error { expected, line, ch }\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\idioms/ffi/errors.md:133
#, fuzzy
msgid ""
"This ensures that the foreign language has clear access to error "
"information\n"
"while not compromising the Rust code's API at all."
msgstr ""
"Esto asegura que el idioma extranjero tenga un acceso claro a la información "
"de error.\n"
"sin comprometer en absoluto la API del código Rust."
#: src\idioms/ffi/errors.md:138
#, fuzzy
msgid ""
"It's a lot of typing, and some types may not be able to be converted easily\n"
"to C."
msgstr ""
"Es mucho escribir, y es posible que algunos tipos no se puedan convertir "
"fácilmente\n"
"a c"
#: src\idioms/ffi/accepting-strings.md:1
#, fuzzy
msgid "# Accepting Strings"
msgstr "# Aceptar cadenas"
#: src\idioms/ffi/accepting-strings.md:5
#, fuzzy
msgid ""
"When accepting strings via FFI through pointers, there are two principles "
"that\n"
"should be followed:"
msgstr ""
"Al aceptar cadenas a través de FFI a través de punteros, hay dos principios "
"que\n"
"debe ser seguido:"
#: src\idioms/ffi/accepting-strings.md:8
#, fuzzy
msgid ""
"1. Keep foreign strings \"borrowed\", rather than copying them directly.\n"
"2. Minimize the amount of complexity and `unsafe` code involved in "
"converting\n"
" from a C-style string to native Rust strings."
msgstr ""
"1. Mantenga las cadenas extranjeras \"prestadas\", en lugar de copiarlas "
"directamente.\n"
"2. Minimice la cantidad de complejidad y el código \"inseguro\" involucrado "
"en la conversión\n"
" desde una cadena de estilo C hasta cadenas nativas de Rust."
#: src\idioms/ffi/accepting-strings.md:14
#, fuzzy
msgid ""
"The strings used in C have different behaviours to those used in Rust, "
"namely:"
msgstr ""
"Las cadenas utilizadas en C tienen comportamientos diferentes a los "
"utilizados en Rust, a saber:"
#: src\idioms/ffi/accepting-strings.md:16
#, fuzzy
msgid ""
"- C strings are null-terminated while Rust strings store their length\n"
"- C strings can contain any arbitrary non-zero byte while Rust strings must "
"be\n"
" UTF-8\n"
"- C strings are accessed and manipulated using `unsafe` pointer operations\n"
" while interactions with Rust strings go through safe methods"
msgstr ""
"- Las cadenas C terminan en nulo, mientras que las cadenas Rust almacenan su "
"longitud\n"
"- Las cadenas C pueden contener cualquier byte arbitrario distinto de cero, "
"mientras que las cadenas Rust deben ser\n"
" UTF-8\n"
"- Se accede a las cadenas C y se manipulan mediante operaciones de puntero "
"\"no seguras\".\n"
" mientras que las interacciones con cadenas de Rust pasan por métodos "
"seguros"
#: src\idioms/ffi/accepting-strings.md:22
#, fuzzy
msgid ""
"The Rust standard library comes with C equivalents of Rust's `String` and "
"`&str`\n"
"called `CString` and `&CStr`, that allow us to avoid a lot of the "
"complexity\n"
"and `unsafe` code involved in converting between C strings and Rust strings."
msgstr ""
"La biblioteca estándar de Rust viene con equivalentes en C de `String` y "
"`&str` de Rust\n"
"llamados `CString` y `&CStr`, que nos permiten evitar mucha de la "
"complejidad\n"
"y código 'inseguro' involucrado en la conversión entre cadenas C y cadenas "
"Rust."
#: src\idioms/ffi/accepting-strings.md:26
#, fuzzy
msgid ""
"The `&CStr` type also allows us to work with borrowed data, meaning passing\n"
"strings between Rust and C is a zero-cost operation."
msgstr ""
"El tipo `&CStr` también nos permite trabajar con datos prestados, lo que "
"significa pasar\n"
"cadenas entre Rust y C es una operación de costo cero."
#: src\idioms/ffi/accepting-strings.md:31
msgid ""
"```rust,ignore\n"
"pub mod unsafe_module {\n"
"\n"
" // other module content\n"
"\n"
" /// Log a message at the specified level.\n"
" ///\n"
" /// # Safety\n"
" ///\n"
" /// It is the caller's guarantee to ensure `msg`:\n"
" ///\n"
" /// - is not a null pointer\n"
" /// - points to valid, initialized data\n"
" /// - points to memory ending in a null byte\n"
" /// - won't be mutated for the duration of this function call\n"
" #[no_mangle]\n"
" pub unsafe extern \"C\" fn mylib_log(\n"
" msg: *const libc::c_char,\n"
" level: libc::c_int\n"
" ) {\n"
" let level: crate::LogLevel = match level { /* ... */ };\n"
"\n"
" // SAFETY: The caller has already guaranteed this is okay (see the\n"
" // `# Safety` section of the doc-comment).\n"
" let msg_str: &str = match std::ffi::CStr::from_ptr(msg).to_str() {\n"
" Ok(s) => s,\n"
" Err(e) => {\n"
" crate::log_error(\"FFI string conversion failed\");\n"
" return;\n"
" }\n"
" };\n"
"\n"
" crate::log(msg_str, level);\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\idioms/ffi/accepting-strings.md:70
#, fuzzy
msgid "The example is is written to ensure that:"
msgstr "El ejemplo está escrito para garantizar que:"
#: src\idioms/ffi/accepting-strings.md:72
#, fuzzy
msgid ""
"1. The `unsafe` block is as small as possible.\n"
"2. The pointer with an \"untracked\" lifetime becomes a \"tracked\" shared\n"
" reference"
msgstr ""
"1. El bloque \"inseguro\" es lo más pequeño posible.\n"
"2. El puntero con una vida útil \"sin seguimiento\" se convierte en un "
"puntero compartido \"seguido\"\n"
" referencia"
#: src\idioms/ffi/accepting-strings.md:76
#, fuzzy
msgid "Consider an alternative, where the string is actually copied:"
msgstr "Considere una alternativa, donde la cadena en realidad se copia:"
#: src\idioms/ffi/accepting-strings.md:78
msgid ""
"```rust,ignore\n"
"pub mod unsafe_module {\n"
"\n"
" // other module content\n"
"\n"
" pub extern \"C\" fn mylib_log(msg: *const libc::c_char, level: "
"libc::c_int) {\n"
" // DO NOT USE THIS CODE.\n"
" // IT IS UGLY, VERBOSE, AND CONTAINS A SUBTLE BUG.\n"
"\n"
" let level: crate::LogLevel = match level { /* ... */ };\n"
"\n"
" let msg_len = unsafe { /* SAFETY: strlen is what it is, I guess? */\n"
" libc::strlen(msg)\n"
" };\n"
"\n"
" let mut msg_data = Vec::with_capacity(msg_len + 1);\n"
"\n"
" let msg_cstr: std::ffi::CString = unsafe {\n"
" // SAFETY: copying from a foreign pointer expected to live\n"
" // for the entire stack frame into owned memory\n"
" std::ptr::copy_nonoverlapping(msg, msg_data.as_mut(), msg_len);\n"
"\n"
" msg_data.set_len(msg_len + 1);\n"
"\n"
" std::ffi::CString::from_vec_with_nul(msg_data).unwrap()\n"
" }\n"
"\n"
" let msg_str: String = unsafe {\n"
" match msg_cstr.into_string() {\n"
" Ok(s) => s,\n"
" Err(e) => {\n"
" crate::log_error(\"FFI string conversion failed\");\n"
" return;\n"
" }\n"
" }\n"
" };\n"
"\n"
" crate::log(&msg_str, level);\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\idioms/ffi/accepting-strings.md:120
#, fuzzy
msgid "This code in inferior to the original in two respects:"
msgstr "Este código es inferior al original en dos aspectos:"
#: src\idioms/ffi/accepting-strings.md:122
#, fuzzy
msgid ""
"1. There is much more `unsafe` code, and more importantly, more invariants "
"it\n"
" must uphold.\n"
"2. Due to the extensive arithmetic required, there is a bug in this version\n"
" that cases Rust `undefined behaviour`."
msgstr ""
"1. Hay mucho más código \"inseguro\" y, lo que es más importante, más "
"invariantes.\n"
" debe sostener.\n"
"2. Debido a la extensa aritmética requerida, hay un error en esta versión\n"
" que casos Rust `comportamiento indefinido`."
#: src\idioms/ffi/accepting-strings.md:127
#, fuzzy
msgid ""
"The bug here is a simple mistake in pointer arithmetic: the string was "
"copied,\n"
"all `msg_len` bytes of it. However, the `NUL` terminator at the end was not."
msgstr ""
"El error aquí es un simple error en la aritmética de punteros: la cadena fue "
"copiada,\n"
"todos los `msg_len` bytes del mismo. Sin embargo, el terminador `NUL` al "
"final no lo era."
#: src\idioms/ffi/accepting-strings.md:130
#, fuzzy
msgid ""
"The Vector then had its size _set_ to the length of the _zero padded string_ "
"--\n"
"rather than _resized_ to it, which could have added a zero at the end.\n"
"As a result, the last byte in the Vector is uninitialized memory.\n"
"When the `CString` is created at the bottom of the block, its read of the\n"
"Vector will cause `undefined behaviour`!"
msgstr ""
"Luego, el Vector tenía su tamaño _establecido_ en la longitud de la _cadena "
"con relleno cero_ --\n"
"en lugar de _redimensionarlo_, lo que podría haber agregado un cero al "
"final.\n"
"Como resultado, el último byte del Vector es una memoria no inicializada.\n"
"Cuando se crea el `CString` en la parte inferior del bloque, se lee el\n"
"¡El vector causará un \"comportamiento indefinido\"!"
#: src\idioms/ffi/accepting-strings.md:136
#, fuzzy
msgid ""
"Like many such issues, this would be difficult issue to track down.\n"
"Sometimes it would panic because the string was not `UTF-8`, sometimes it "
"would\n"
"put a weird character at the end of the string, sometimes it would just\n"
"completely crash."
msgstr ""
"Como muchos de estos problemas, este sería un problema difícil de rastrear.\n"
"A veces entraba en pánico porque la cadena no era `UTF-8`, a veces\n"
"poner un carácter extraño al final de la cadena, a veces simplemente\n"
"chocar completamente."
#: src\idioms/ffi/accepting-strings.md:143
#: src\idioms/ffi/passing-strings.md:105
#, fuzzy
msgid "None?"
msgstr "¿Ninguno?"
#: src\idioms/ffi/passing-strings.md:1
#, fuzzy
msgid "# Passing Strings"
msgstr "# Cuerdas de paso"
#: src\idioms/ffi/passing-strings.md:5
#, fuzzy
msgid ""
"When passing strings to FFI functions, there are four principles that should "
"be\n"
"followed:"
msgstr ""
"Al pasar cadenas a funciones FFI, hay cuatro principios que deben ser\n"
"seguido:"
#: src\idioms/ffi/passing-strings.md:8
#, fuzzy
msgid ""
"1. Make the lifetime of owned strings as long as possible.\n"
"2. Minimize `unsafe` code during the conversion.\n"
"3. If the C code can modify the string data, use `Vec` instead of "
"`CString`.\n"
"4. Unless the Foreign Function API requires it, the ownership of the string\n"
" should not transfer to the callee."
msgstr ""
"1. Haga que la vida útil de las cadenas propias sea lo más larga posible.\n"
"2. Minimice el código \"inseguro\" durante la conversión.\n"
"3. Si el código C puede modificar los datos de la cadena, use `Vec` en lugar "
"de `CString`.\n"
"4. A menos que la API de función externa lo requiera, la propiedad de la "
"cadena\n"
" no debe transferirse al destinatario."
#: src\idioms/ffi/passing-strings.md:16
#, fuzzy
msgid ""
"Rust has built-in support for C-style strings with its `CString` and `CStr`\n"
"types. However, there are different approaches one can take with strings "
"that\n"
"are being sent to a foreign function call from a Rust function."
msgstr ""
"Rust tiene soporte incorporado para cadenas de estilo C con su `CString` y "
"`CStr`\n"
"tipos Sin embargo, hay diferentes enfoques que uno puede tomar con cadenas "
"que\n"
"se envían a una llamada de función externa desde una función de Rust."
#: src\idioms/ffi/passing-strings.md:20
#, fuzzy
msgid ""
"The best practice is simple: use `CString` in such a way as to minimize\n"
"`unsafe` code. However, a secondary caveat is that\n"
"_the object must live long enough_, meaning the lifetime should be "
"maximized.\n"
"In addition, the documentation explains that \"round-tripping\" a `CString` "
"after\n"
"modification is UB, so additional work is necessary in that case."
msgstr ""
"La mejor práctica es simple: use `CString` de tal manera que minimice\n"
"Código `inseguro`. Sin embargo, una advertencia secundaria es que\n"
"_el objeto debe vivir lo suficiente_, lo que significa que la vida útil debe "
"maximizarse.\n"
"Además, la documentación explica que \"viajar de ida y vuelta\" un `CString` "
"después\n"
"la modificación es UB, por lo que se necesita trabajo adicional en ese caso."
#: src\idioms/ffi/passing-strings.md:28
msgid ""
"```rust,ignore\n"
"pub mod unsafe_module {\n"
"\n"
" // other module content\n"
"\n"
" extern \"C\" {\n"
" fn seterr(message: *const libc::c_char);\n"
" fn geterr(buffer: *mut libc::c_char, size: libc::c_int) -> "
"libc::c_int;\n"
" }\n"
"\n"
" fn report_error_to_ffi<S: Into<String>>(\n"
" err: S\n"
" ) -> Result<(), std::ffi::NulError>{\n"
" let c_err = std::ffi::CString::new(err.into())?;\n"
"\n"
" unsafe {\n"
" // SAFETY: calling an FFI whose documentation says the pointer "
"is\n"
" // const, so no modification should occur\n"
" seterr(c_err.as_ptr());\n"
" }\n"
"\n"
" Ok(())\n"
" // The lifetime of c_err continues until here\n"
" }\n"
"\n"
" fn get_error_from_ffi() -> Result<String, std::ffi::IntoStringError> {\n"
" let mut buffer = vec![0u8; 1024];\n"
" unsafe {\n"
" // SAFETY: calling an FFI whose documentation implies\n"
" // that the input need only live as long as the call\n"
" let written: usize = geterr(buffer.as_mut_ptr(), 1023).into();\n"
"\n"
" buffer.truncate(written + 1);\n"
" }\n"
"\n"
" std::ffi::CString::new(buffer).unwrap().into_string()\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\idioms/ffi/passing-strings.md:70
#, fuzzy
msgid "The example is written in a way to ensure that:"
msgstr "El ejemplo está escrito de manera que se asegure que:"
#: src\idioms/ffi/passing-strings.md:72
#, fuzzy
msgid ""
"1. The `unsafe` block is as small as possible.\n"
"2. The `CString` lives long enough.\n"
"3. Errors with typecasts are always propagated when possible."
msgstr ""
"1. El bloque \"inseguro\" es lo más pequeño posible.\n"
"2. El `CString` vive lo suficiente.\n"
"3. Los errores con typecasts siempre se propagan cuando es posible."
#: src\idioms/ffi/passing-strings.md:76
#, fuzzy
msgid ""
"A common mistake (so common it's in the documentation) is to not use the\n"
"variable in the first block:"
msgstr ""
"Un error común (tan común que está en la documentación) es no usar el\n"
"variable en el primer bloque:"
#: src\idioms/ffi/passing-strings.md:79
msgid ""
"```rust,ignore\n"
"pub mod unsafe_module {\n"
"\n"
" // other module content\n"
"\n"
" fn report_error<S: Into<String>>(err: S) -> Result<(), "
"std::ffi::NulError> {\n"
" unsafe {\n"
" // SAFETY: whoops, this contains a dangling pointer!\n"
" seterr(std::ffi::CString::new(err.into())?.as_ptr());\n"
" }\n"
" Ok(())\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\idioms/ffi/passing-strings.md:94
#, fuzzy
msgid ""
"This code will result in a dangling pointer, because the lifetime of the\n"
"`CString` is not extended by the pointer creation, unlike if a reference "
"were\n"
"created."
msgstr ""
"Este código dará como resultado un puntero colgante, porque la vida útil "
"del\n"
"'CString' no se extiende por la creación del puntero, a diferencia de si una "
"referencia fuera\n"
"creado."
#: src\idioms/ffi/passing-strings.md:98
#, fuzzy
msgid ""
"Another issue frequently raised is that the initialization of a 1k vector "
"of\n"
"zeroes is \"slow\". However, recent versions of Rust actually optimize that\n"
"particular macro to a call to `zmalloc`, meaning it is as fast as the "
"operating\n"
"system's ability to return zeroed memory (which is quite fast)."
msgstr ""
"Otro problema que se plantea con frecuencia es que la inicialización de un "
"vector de 1k de\n"
"ceros es \"lento\". Sin embargo, las versiones recientes de Rust en realidad "
"optimizan eso\n"
"macro particular a una llamada a `zmalloc`, lo que significa que es tan "
"rápido como el operador\n"
"la capacidad del sistema para devolver la memoria puesta a cero (lo cual es "
"bastante rápido)."
#: src\idioms/option-iter.md:1
#, fuzzy
msgid "# Iterating over an `Option`"
msgstr "# Iterando sobre una `Opción`"
#: src\idioms/option-iter.md:5
#, fuzzy
msgid ""
"`Option` can be viewed as a container that contains either zero or one\n"
"element. In particular, it implements the `IntoIterator` trait, and as such\n"
"can be used with generic code that needs such a type."
msgstr ""
"`Opción` se puede ver como un contenedor que contiene cero o uno\n"
"elemento. En particular, implementa el rasgo `IntoIterator`, y como tal\n"
"se puede usar con código genérico que necesita ese tipo."
#: src\idioms/option-iter.md:9 src\patterns/structural/small-crates.md:34
#: src\patterns/structural/unsafe-mods.md:22
#, fuzzy
msgid "## Examples"
msgstr "## Ejemplos"
#: src\idioms/option-iter.md:11
#, fuzzy
msgid ""
"Since `Option` implements `IntoIterator`, it can be used as an argument to\n"
"[`.extend()`](https://doc.rust-lang.org/std/iter/trait.Extend.html#tymethod.extend):"
msgstr ""
"Dado que `Option` implementa `IntoIterator`, se puede usar como argumento "
"para\n"
"[`.extend()`](https://doc.rust-lang.org/std/iter/trait.Extend.html#tymethod.extend):"
#: src\idioms/option-iter.md:14
msgid ""
"```rust\n"
"let turing = Some(\"Turing\");\n"
"let mut logicians = vec![\"Curry\", \"Kleene\", \"Markov\"];\n"
"\n"
"logicians.extend(turing);\n"
"\n"
"// equivalent to\n"
"if let Some(turing_inner) = turing {\n"
" logicians.push(turing_inner);\n"
"}\n"
"```"
msgstr ""
#: src\idioms/option-iter.md:26
#, fuzzy
msgid ""
"If you need to tack an `Option` to the end of an existing iterator, you can\n"
"pass it to "
"[`.chain()`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.chain):"
msgstr ""
"Si necesita agregar una `Opción` al final de un iterador existente, puede\n"
"páselo a "
"[`.chain()`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.chain):"
#: src\idioms/option-iter.md:29
msgid ""
"```rust\n"
"let turing = Some(\"Turing\");\n"
"let logicians = vec![\"Curry\", \"Kleene\", \"Markov\"];\n"
"\n"
"for logician in logicians.iter().chain(turing.iter()) {\n"
" println!(\"{} is a logician\", logician);\n"
"}\n"
"```"
msgstr ""
#: src\idioms/option-iter.md:38
#, fuzzy
msgid ""
"Note that if the `Option` is always `Some`, then it is more idiomatic to "
"use\n"
"[`std::iter::once`](https://doc.rust-lang.org/std/iter/fn.once.html) on the\n"
"element instead."
msgstr ""
"Tenga en cuenta que si la `Opción` siempre es `Algunos`, entonces es más "
"idiomático de usar\n"
"[`std::iter::once`](https://doc.rust-lang.org/std/iter/fn.once.html) en el\n"
"elemento en su lugar."
#: src\idioms/option-iter.md:42
#, fuzzy
msgid ""
"Also, since `Option` implements `IntoIterator`, it's possible to iterate "
"over\n"
"it using a `for` loop. This is equivalent to matching it with `if let "
"Some(..)`,\n"
"and in most cases you should prefer the latter."
msgstr ""
"Además, dado que `Option` implementa `IntoIterator`, es posible iterar "
"sobre\n"
"usando un bucle `for`. Esto es equivalente a emparejarlo con `if let "
"Some(...)`,\n"
"y en la mayoría de los casos deberías preferir lo último."
#: src\idioms/option-iter.md:48
#, fuzzy
msgid ""
"- [`std::iter::once`](https://doc.rust-lang.org/std/iter/fn.once.html) is "
"an\n"
" iterator which yields exactly one element. It's a more readable "
"alternative to\n"
" `Some(foo).into_iter()`.\n"
"\n"
"- "
"[`Iterator::filter_map`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter_map)\n"
" is a version of "
"[`Iterator::map`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map),\n"
" specialized to mapping functions which return `Option`.\n"
"\n"
"- The [`ref_slice`](https://crates.io/crates/ref_slice) crate provides "
"functions\n"
" for converting an `Option` to a zero- or one-element slice.\n"
"\n"
"- [Documentation for "
"`Option<T>`](https://doc.rust-lang.org/std/option/enum.Option.html)"
msgstr ""
"- [`std::iter::once`](https://doc.rust-lang.org/std/iter/fn.once.html) es "
"un\n"
" iterador que produce exactamente un elemento. Es una alternativa más "
"legible a\n"
" `Algunos(foo).into_iter()`.\n"
"\n"
"- "
"[`Iterador::filter_map`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter_map)\n"
" es una versión de "
"[`Iterator::map`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map),\n"
" especializado en funciones de mapeo que devuelven `Opción`.\n"
"\n"
"- La caja [`ref_slice`](https://crates.io/crates/ref_slice) proporciona "
"funciones\n"
" para convertir una `Opción` en una rebanada de cero o un elemento.\n"
"\n"
"- [Documentación para "
"`Option<T>`](https://doc.rust-lang.org/std/option/enum.Option.html)"
#: src\idioms/pass-var-to-closure.md:1
#, fuzzy
msgid "# Pass variables to closure"
msgstr "# Pasar variables al cierre"
#: src\idioms/pass-var-to-closure.md:5
#, fuzzy
msgid ""
"By default, closures capture their environment by borrowing. Or you can use\n"
"`move`-closure to move whole environment. However, often you want to move "
"just\n"
"some variables to closure, give it copy of some data, pass it by reference, "
"or\n"
"perform some other transformation."
msgstr ""
"De forma predeterminada, los cierres capturan su entorno tomando prestado. O "
"puedes usar\n"
"cierre `mover` para mover todo el entorno. Sin embargo, a menudo desea "
"moverse solo\n"
"algunas variables para el cierre, darle copia de algunos datos, pasarlo por "
"referencia, o\n"
"realizar alguna otra transformación."
#: src\idioms/pass-var-to-closure.md:10
#, fuzzy
msgid "Use variable rebinding in separate scope for that."
msgstr "Use la revinculación de variables en un alcance separado para eso."
#: src\idioms/pass-var-to-closure.md:14
#, fuzzy
msgid "Use"
msgstr "Usar"
#: src\idioms/pass-var-to-closure.md:16
msgid ""
"```rust\n"
"use std::rc::Rc;\n"
"\n"
"let num1 = Rc::new(1);\n"
"let num2 = Rc::new(2);\n"
"let num3 = Rc::new(3);\n"
"let closure = {\n"
" // `num1` is moved\n"
" let num2 = num2.clone(); // `num2` is cloned\n"
" let num3 = num3.as_ref(); // `num3` is borrowed\n"
" move || {\n"
" *num1 + *num2 + *num3;\n"
" }\n"
"};\n"
"```"
msgstr ""
#: src\idioms/pass-var-to-closure.md:32
#, fuzzy
msgid "instead of"
msgstr "en lugar de"
#: src\idioms/pass-var-to-closure.md:34
msgid ""
"```rust\n"
"use std::rc::Rc;\n"
"\n"
"let num1 = Rc::new(1);\n"
"let num2 = Rc::new(2);\n"
"let num3 = Rc::new(3);\n"
"\n"
"let num2_cloned = num2.clone();\n"
"let num3_borrowed = num3.as_ref();\n"
"let closure = move || {\n"
" *num1 + *num2_cloned + *num3_borrowed;\n"
"};\n"
"```"
msgstr ""
#: src\idioms/pass-var-to-closure.md:50
#, fuzzy
msgid ""
"Copied data are grouped together with closure definition, so their purpose "
"is\n"
"more clear, and they will be dropped immediately even if they are not "
"consumed\n"
"by closure."
msgstr ""
"Los datos copiados se agrupan junto con la definición de cierre, por lo que "
"su propósito es\n"
"más claras, y se dejarán caer inmediatamente incluso si no se consumen\n"
"por cierre."
#: src\idioms/pass-var-to-closure.md:54
#, fuzzy
msgid ""
"Closure uses same variable names as surrounding code whether data are copied "
"or\n"
"moved."
msgstr ""
"El cierre usa los mismos nombres de variables que el código circundante, ya "
"sea que los datos se copien o\n"
"movido."
#: src\idioms/pass-var-to-closure.md:59
#, fuzzy
msgid "Additional indentation of closure body."
msgstr "Muesca adicional del cuerpo del cierre."
#: src\idioms/priv-extend.md:1
#, fuzzy
msgid "# `#[non_exhaustive]` and private fields for extensibility"
msgstr "# `#[no_exhaustivo]` y campos privados para extensibilidad"
#: src\idioms/priv-extend.md:5
#, fuzzy
msgid ""
"A small set of scenarios exist where a library author may want to add "
"public\n"
"fields to a public struct or new variants to an enum without breaking "
"backwards\n"
"compatibility."
msgstr ""
"Existe un pequeño conjunto de escenarios en los que un autor de la "
"biblioteca puede querer agregar público\n"
"campos a una estructura pública o nuevas variantes a una enumeración sin "
"retroceder\n"
"compatibilidad."
#: src\idioms/priv-extend.md:9
#, fuzzy
msgid "Rust offers two solutions to this problem:"
msgstr "Rust ofrece dos soluciones a este problema:"
#: src\idioms/priv-extend.md:11
#, fuzzy
msgid ""
"- Use `#[non_exhaustive]` on `struct`s, `enum`s, and `enum` variants.\n"
" For extensive documentation on all the places where `#[non_exhaustive]` "
"can be\n"
" used, see [the "
"docs](https://doc.rust-lang.org/reference/attributes/type_system.html#the-non_exhaustive-attribute).\n"
"\n"
"- You may add a private field to a struct to prevent it from being directly\n"
" instantiated or matched against (see Alternative)"
msgstr ""
"- Use `#[non_exhaustive]` en las variantes `struct`s, `enum`s y `enum`.\n"
" Para obtener documentación detallada sobre todos los lugares donde "
"`#[non_exhaustive]` puede ser\n"
" utilizado, consulte [los documentos] "
"(https://doc.rust-lang.org/reference/attributes/type_system.html#the-non_exhaustive-attribute).\n"
"\n"
"- Puede agregar un campo privado a una estructura para evitar que sea "
"directamente\n"
" instanciado o comparado con (ver Alternativa)"
#: src\idioms/priv-extend.md:20
msgid ""
"```rust\n"
"mod a {\n"
" // Public struct.\n"
" #[non_exhaustive]\n"
" pub struct S {\n"
" pub foo: i32,\n"
" }\n"
" \n"
" #[non_exhaustive]\n"
" pub enum AdmitMoreVariants {\n"
" VariantA,\n"
" VariantB,\n"
" #[non_exhaustive]\n"
" VariantC { a: String }\n"
" }\n"
"}\n"
"\n"
"fn print_matched_variants(s: a::S) {\n"
" // Because S is `#[non_exhaustive]`, it cannot be named here and\n"
" // we must use `..` in the pattern.\n"
" let a::S { foo: _, ..} = s;\n"
" \n"
" let some_enum = a::AdmitMoreVariants::VariantA;\n"
" match some_enum {\n"
" a::AdmitMoreVariants::VariantA => println!(\"it's an A\"),\n"
" a::AdmitMoreVariants::VariantB => println!(\"it's a b\"),\n"
"\n"
" // .. required because this variant is non-exhaustive as well\n"
" a::AdmitMoreVariants::VariantC { a, .. } => println!(\"it's a c\"),\n"
"\n"
" // The wildcard match is required because more variants may be\n"
" // added in the future\n"
" _ => println!(\"it's a new variant\")\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\idioms/priv-extend.md:57
#, fuzzy
msgid "## Alternative: `Private fields` for structs"
msgstr "## Alternativa: `Campos privados` para estructuras"
#: src\idioms/priv-extend.md:59
#, fuzzy
msgid ""
"`#[non_exhaustive]` only works across crate boundaries.\n"
"Within a crate, the private field method may be used."
msgstr ""
"`#[non_exhaustive]` solo funciona a través de los límites de las cajas.\n"
"Dentro de una caja, se puede utilizar el método de campo privado."
#: src\idioms/priv-extend.md:62
#, fuzzy
msgid ""
"Adding a field to a struct is a mostly backwards compatible change.\n"
"However, if a client uses a pattern to deconstruct a struct instance, they\n"
"might name all the fields in the struct and adding a new one would break "
"that\n"
"pattern.\n"
"The client could name some fields and use `..` in the pattern, in which case "
"adding\n"
"another field is backwards compatible.\n"
"Making at least one of the struct's fields private forces clients to use the "
"latter\n"
"form of patterns, ensuring that the struct is future-proof."
msgstr ""
"Agregar un campo a una estructura es un cambio en su mayoría compatible con "
"versiones anteriores.\n"
"Sin embargo, si un cliente usa un patrón para deconstruir una instancia de "
"estructura,\n"
"podría nombrar todos los campos en la estructura y agregar uno nuevo "
"rompería eso\n"
"patrón.\n"
"El cliente podría nombrar algunos campos y usar `..` en el patrón, en cuyo "
"caso agregando\n"
"otro campo es compatible con versiones anteriores.\n"
"Hacer que al menos uno de los campos de la estructura sea privado obliga a "
"los clientes a usar este último\n"
"forma de patrones, asegurando que la estructura esté preparada para el "
"futuro."
#: src\idioms/priv-extend.md:71
#, fuzzy
msgid ""
"The downside of this approach is that you might need to add an otherwise "
"unneeded\n"
"field to the struct.\n"
"You can use the `()` type so that there is no runtime overhead and prepend "
"`_` to\n"
"the field name to avoid the unused field warning."
msgstr ""
"La desventaja de este enfoque es que es posible que deba agregar un\n"
"campo a la estructura.\n"
"Puede usar el tipo `()` para que no haya sobrecarga de tiempo de ejecución y "
"anteponer `_` a\n"
"el nombre del campo para evitar la advertencia de campo no utilizado."
#: src\idioms/priv-extend.md:76
msgid ""
"```rust\n"
"pub struct S {\n"
" pub a: i32,\n"
" // Because `b` is private, you cannot match on `S` without using `..` "
"and `S`\n"
" // cannot be directly instantiated or matched against\n"
" _b: ()\n"
"}\n"
"```"
msgstr ""
#: src\idioms/priv-extend.md:87
#, fuzzy
msgid ""
"On `struct`s, `#[non_exhaustive]` allows adding additional fields in a "
"backwards\n"
"compatible way.\n"
"It will also prevent clients from using the struct constructor, even if all "
"the\n"
"fields are public.\n"
"This may be helpful, but it's worth considering if you _want_ an additional "
"field\n"
"to be found by clients as a compiler error rather than something that may be "
"silently\n"
"undiscovered."
msgstr ""
"En `struct`s, `#[non_exhaustive]` permite agregar campos adicionales al "
"revés\n"
"forma compatible.\n"
"También evitará que los clientes usen el constructor de estructuras, incluso "
"si todos los\n"
"Los campos son públicos.\n"
"Esto puede ser útil, pero vale la pena considerarlo si _quiere_ un campo "
"adicional\n"
"ser encontrado por los clientes como un error del compilador en lugar de "
"algo que puede ser silenciosamente\n"
"sin descubrir"
#: src\idioms/priv-extend.md:95
#, fuzzy
msgid ""
"`#[non_exhaustive]` can be applied to enum variants as well.\n"
"A `#[non_exhaustive]` variant behaves in the same way as a "
"`#[non_exhaustive]` struct."
msgstr ""
"`#[non_exhaustive]` también se puede aplicar a las variantes de "
"enumeración.\n"
"Una variante `#[no_exhaustiva]` se comporta de la misma manera que una "
"estructura `#[no_exhaustiva]`."
#: src\idioms/priv-extend.md:98
#, fuzzy
msgid ""
"Use this deliberately and with caution: incrementing the major version when "
"adding\n"
"fields or variants is often a better option.\n"
"`#[non_exhaustive]` may be appropriate in scenarios where you're modeling an "
"external\n"
"resource that may change out-of-sync with your library, but is not a general "
"purpose\n"
"tool."
msgstr ""
"Use esto deliberadamente y con precaución: incrementando la versión "
"principal al agregar\n"
"campos o variantes suele ser una mejor opción.\n"
"`#[non_exhaustive]` puede ser apropiado en escenarios en los que está "
"modelando un\n"
"recurso que puede cambiar fuera de sincronización con su biblioteca, pero no "
"es un propósito general\n"
"herramienta."
#: src\idioms/priv-extend.md:104
#, fuzzy
msgid "### Disadvantages"
msgstr "### Desventajas"
#: src\idioms/priv-extend.md:106
#, fuzzy
msgid ""
"`#[non_exhaustive]` can make your code much less ergonomic to use, "
"especially when\n"
"forced to handle unknown enum variants.\n"
"It should only be used when these sorts of evolutions are required "
"**without**\n"
"incrementing the major version."
msgstr ""
"`#[non_exhaustive]` puede hacer que su código sea mucho menos ergonómico de "
"usar, especialmente cuando\n"
"forzado a manejar variantes de enumeración desconocidas.\n"
"Solo debe usarse cuando se requieren este tipo de evoluciones **sin**\n"
"incrementando la versión principal."
#: src\idioms/priv-extend.md:111
msgid ""
"When `#[non_exhaustive]` is applied to `enum`s, it forces clients to handle "
"a\n"
"wildcard variant.\n"
"If there is no sensible action to take in this case, this may lead to "
"awkward\n"
"code and code paths that are only executed in extremely rare circumstances.\n"
"If a client decides to `panic!()` in this scenario, it may have been better "
"to\n"
"expose this error at compile time.\n"
"In fact, `#[non_exhaustive]` forces clients to handle the \"Something else\" "
"case;\n"
"there is rarely a sensible action to take in this scenario."
msgstr ""
#: src\idioms/priv-extend.md:122
#, fuzzy
msgid ""
"- [RFC introducing #[non_exhaustive] attribute for enums and "
"structs](https://github.com/rust-lang/rfcs/blob/master/text/2008-non-exhaustive.md)"
msgstr ""
"- [RFC presenta el atributo #[no_exhaustivo] para enumeraciones y "
"estructuras](https://github.com/rust-lang/rfcs/blob/master/text/2008-non-exhaustive.md)"
#: src\idioms/rustdoc-init.md:1
#, fuzzy
msgid "# Easy doc initialization\r"
msgstr "# Fácil inicialización de documentos\r"
#: src\idioms/rustdoc-init.md:5
#, fuzzy
msgid ""
"If a struct takes significant effort to initialize when writing docs, it can "
"be\r\n"
"quicker to wrap your example with a helper function which takes the struct "
"as an\r\n"
"argument."
msgstr ""
"Si una estructura requiere un esfuerzo significativo para inicializarse al "
"escribir documentos, puede ser\r\n"
"más rápido para envolver su ejemplo con una función de ayuda que toma la "
"estructura como una\r\n"
"argumento."
#: src\idioms/rustdoc-init.md:9
#, fuzzy
msgid "## Motivation\r"
msgstr "## Motivación\r"
#: src\idioms/rustdoc-init.md:11
#, fuzzy
msgid ""
"Sometimes there is a struct with multiple or complicated parameters and "
"several\r\n"
"methods. Each of these methods should have examples."
msgstr ""
"A veces hay una estructura con parámetros múltiples o complicados y "
"varios\r\n"
"métodos. Cada uno de estos métodos debe tener ejemplos."
#: src\idioms/rustdoc-init.md:14
#, fuzzy
msgid "For example:"
msgstr "Por ejemplo:"
#: src\idioms/rustdoc-init.md:16
msgid ""
"````rust,ignore\r\n"
"struct Connection {\r\n"
" name: String,\r\n"
" stream: TcpStream,\r\n"
"}\r\n"
"\r\n"
"impl Connection {\r\n"
" /// Sends a request over the connection.\r\n"
" ///\r\n"
" /// # Example\r\n"
" /// ```no_run\r\n"
" /// # // Boilerplate are required to get an example working.\r\n"
" /// # let stream = TcpStream::connect(\"127.0.0.1:34254\");\r\n"
" /// # let connection = Connection { name: \"foo\".to_owned(), stream "
"};\r\n"
" /// # let request = Request::new(\"RequestId\", RequestType::Get, "
"\"payload\");\r\n"
" /// let response = connection.send_request(request);\r\n"
" /// assert!(response.is_ok());\r\n"
" /// ```\r\n"
" fn send_request(&self, request: Request) -> Result<Status, SendErr> {\r\n"
" // ...\r\n"
" }\r\n"
"\r\n"
" /// Oh no, all that boilerplate needs to be repeated here!\r\n"
" fn check_status(&self) -> Status {\r\n"
" // ...\r\n"
" }\r\n"
"}\r\n"
"````"
msgstr ""
#: src\idioms/rustdoc-init.md:45
#, fuzzy
msgid "## Example\r"
msgstr "## Ejemplo\r"
#: src\idioms/rustdoc-init.md:47
#, fuzzy
msgid ""
"Instead of typing all of this boilerplate to create a `Connection` and\r\n"
"`Request`, it is easier to just create a wrapping helper function which "
"takes\r\n"
"them as arguments:"
msgstr ""
"En lugar de escribir todo este texto repetitivo para crear una `Conexión` "
"y\r\n"
"`Solicitud`, es más fácil simplemente crear una función auxiliar de "
"envoltura que tome\r\n"
"ellos como argumentos:"
#: src\idioms/rustdoc-init.md:51
msgid ""
"````rust,ignore\r\n"
"struct Connection {\r\n"
" name: String,\r\n"
" stream: TcpStream,\r\n"
"}\r\n"
"\r\n"
"impl Connection {\r\n"
" /// Sends a request over the connection.\r\n"
" ///\r\n"
" /// # Example\r\n"
" /// ```\r\n"
" /// # fn call_send(connection: Connection, request: Request) {\r\n"
" /// let response = connection.send_request(request);\r\n"
" /// assert!(response.is_ok());\r\n"
" /// # }\r\n"
" /// ```\r\n"
" fn send_request(&self, request: Request) {\r\n"
" // ...\r\n"
" }\r\n"
"}\r\n"
"````"
msgstr ""
#: src\idioms/rustdoc-init.md:73
msgid ""
"**Note** in the above example the line `assert!(response.is_ok());` will "
"not\r\n"
"actually run while testing because it is inside a function which is never\r\n"
"invoked."
msgstr ""
#: src\idioms/rustdoc-init.md:77
#, fuzzy
msgid "## Advantages\r"
msgstr "## Ventajas\r"
#: src\idioms/rustdoc-init.md:79
#, fuzzy
msgid "This is much more concise and avoids repetitive code in examples."
msgstr "Esto es mucho más conciso y evita el código repetitivo en los ejemplos."
#: src\idioms/rustdoc-init.md:81
#, fuzzy
msgid "## Disadvantages\r"
msgstr "## Desventajas\r"
#: src\idioms/rustdoc-init.md:83
#, fuzzy
msgid ""
"As example is in a function, the code will not be tested. Though it will "
"still be\r\n"
"checked to make sure it compiles when running a `cargo test`. So this "
"pattern is\r\n"
"most useful when you need `no_run`. With this, you do not need to add "
"`no_run`."
msgstr ""
"Como el ejemplo está en una función, el código no se probará. Aunque seguirá "
"siendo\r\n"
"verificado para asegurarse de que compila cuando se ejecuta una `prueba de "
"carga`. Así que este patrón es\r\n"
"más útil cuando necesitas `no_run`. Con esto, no necesita agregar `no_run`."
#: src\idioms/rustdoc-init.md:87
#, fuzzy
msgid "## Discussion\r"
msgstr "## Discusión\r"
#: src\idioms/rustdoc-init.md:89
#, fuzzy
msgid "If assertions are not required this pattern works well."
msgstr "Si no se requieren aserciones, este patrón funciona bien."
#: src\idioms/rustdoc-init.md:91
#, fuzzy
msgid ""
"If they are, an alternative can be to create a public method to create a "
"helper\r\n"
"instance which is annotated with `#[doc(hidden)]` (so that users won't see "
"it).\r\n"
"Then this method can be called inside of rustdoc because it is part of "
"the\r\n"
"crate's public API."
msgstr ""
"Si lo son, una alternativa puede ser crear un método público para crear un "
"ayudante.\r\n"
"instancia que está anotada con `#[doc(hidden)]` (para que los usuarios no la "
"vean).\r\n"
"Entonces este método se puede llamar dentro de rustdoc porque es parte "
"del\r\n"
"API pública de crate."
#: src\idioms/temporary-mutability.md:1
#, fuzzy
msgid "# Temporary mutability"
msgstr "# Mutabilidad temporal"
#: src\idioms/temporary-mutability.md:5
#, fuzzy
msgid ""
"Often it is necessary to prepare and process some data, but after that data "
"are\n"
"only inspected and never modified. The intention can be made explicit by "
"redefining\n"
"the mutable variable as immutable."
msgstr ""
"A menudo es necesario preparar y procesar algunos datos, pero después de eso "
"los datos son\n"
"solo inspeccionado y nunca modificado. La intención puede hacerse explícita "
"redefiniendo\n"
"la variable mutable como inmutable."
#: src\idioms/temporary-mutability.md:9
#, fuzzy
msgid ""
"It can be done either by processing data within a nested block or by "
"redefining\n"
"the variable."
msgstr ""
"Se puede hacer procesando datos dentro de un bloque anidado o redefiniendo\n"
"La variable."
#: src\idioms/temporary-mutability.md:14
#, fuzzy
msgid "Say, vector must be sorted before usage."
msgstr "Digamos que el vector debe ordenarse antes de su uso."
#: src\idioms/temporary-mutability.md:16
#, fuzzy
msgid "Using nested block:"
msgstr "Usando bloque anidado:"
#: src\idioms/temporary-mutability.md:18
msgid ""
"```rust,ignore\n"
"let data = {\n"
" let mut data = get_vec();\n"
" data.sort();\n"
" data\n"
"};\n"
"\n"
"// Here `data` is immutable.\n"
"```"
msgstr ""
#: src\idioms/temporary-mutability.md:28
#, fuzzy
msgid "Using variable rebinding:"
msgstr "Usando el reenlace variable:"
#: src\idioms/temporary-mutability.md:30
msgid ""
"```rust,ignore\n"
"let mut data = get_vec();\n"
"data.sort();\n"
"let data = data;\n"
"\n"
"// Here `data` is immutable.\n"
"```"
msgstr ""
#: src\idioms/temporary-mutability.md:40
#, fuzzy
msgid ""
"Compiler ensures that you don't accidentally mutate data after some point."
msgstr ""
"El compilador garantiza que no mute accidentalmente los datos después de "
"algún momento."
#: src\idioms/temporary-mutability.md:44
#, fuzzy
msgid ""
"Nested block requires additional indentation of block body.\n"
"One more line to return data from block or redefine variable."
msgstr ""
"El bloque anidado requiere sangría adicional del cuerpo del bloque.\n"
"Una línea más para devolver datos del bloque o redefinir variable."
#: src\idioms/return-consumed-arg-on-error.md:1
#, fuzzy
msgid "# Return consumed argument on error"
msgstr "# Devolver argumento consumido en caso de error"
#: src\idioms/return-consumed-arg-on-error.md:5
#, fuzzy
msgid ""
"If a fallible function consumes (moves) an argument, return that argument "
"back inside\n"
"an error."
msgstr ""
"Si una función falible consume (mueve) un argumento, devuelva ese argumento "
"al interior\n"
"un error."
#: src\idioms/return-consumed-arg-on-error.md:10
msgid ""
"```rust\n"
"pub fn send(value: String) -> Result<(), SendError> {\n"
" println!(\"using {value} in a meaningful way\");\n"
" // Simulate non-deterministic fallible action.\n"
" use std::time::SystemTime;\n"
" let period = "
"SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();\n"
" if period.subsec_nanos() % 2 == 1 {\n"
" Ok(())\n"
" } else {\n"
" Err(SendError(value))\n"
" }\n"
"}\n"
"\n"
"pub struct SendError(String);\n"
"\n"
"fn main() {\n"
" let mut value = \"imagine this is very long string\".to_string();\n"
"\n"
" let success = 's: {\n"
" // Try to send value two times.\n"
" for _ in 0..2 {\n"
" value = match send(value) {\n"
" Ok(()) => break 's true,\n"
" Err(SendError(value)) => value,\n"
" }\n"
" }\n"
" false\n"
" };\n"
"\n"
" println!(\"success: {}\", success);\n"
"}\n"
"```"
msgstr ""
#: src\idioms/return-consumed-arg-on-error.md:45
#, fuzzy
msgid ""
"In case of error you may want to try some alternative way or to\n"
"retry action in case of non-deterministic function. But if the argument\n"
"is always consumed, you are forced to clone it on every call, which\n"
"is not very efficient."
msgstr ""
"En caso de error, es posible que desee probar alguna forma alternativa o\n"
"reintentar la acción en caso de función no determinista. Pero si el "
"argumento\n"
"siempre se consume, se ve obligado a clonarlo en cada llamada, lo que\n"
"no es muy eficiente."
#: src\idioms/return-consumed-arg-on-error.md:50
#, fuzzy
msgid ""
"The standard library uses this approach in e.g. `String::from_utf8` method.\n"
"When given a vector that doesn't contain valid UTF-8, a `FromUtf8Error`\n"
"is returned.\n"
"You can get original vector back using `FromUtf8Error::into_bytes` method."
msgstr ""
"La biblioteca estándar utiliza este enfoque en, p. Método "
"`String::from_utf8`.\n"
"Cuando se le da un vector que no contiene UTF-8 válido, un `FromUtf8Error`\n"
"es regresado.\n"
"Puede recuperar el vector original usando el método "
"`FromUtf8Error::into_bytes`."
#: src\idioms/return-consumed-arg-on-error.md:57
#, fuzzy
msgid "Better performance because of moving arguments whenever possible."
msgstr ""
"Mejor rendimiento debido a los argumentos en movimiento siempre que sea "
"posible."
#: src\idioms/return-consumed-arg-on-error.md:61
#, fuzzy
msgid "Slightly more complex error types."
msgstr "Tipos de error ligeramente más complejos."
#: src\patterns/index.md:1
#, fuzzy
msgid "# Design Patterns"
msgstr "# Patrones de diseño"
#: src\patterns/index.md:3
#, fuzzy
msgid ""
"[Design patterns](https://en.wikipedia.org/wiki/Software_design_pattern) "
"are\n"
"\"general reusable solutions to a commonly occurring problem within a given\n"
"context in software design\". Design patterns are a great way to describe "
"the\n"
"culture of a programming language. Design patterns are very "
"language-specific -\n"
"what is a pattern in one language may be unnecessary in another due to a\n"
"language feature, or impossible to express due to a missing feature."
msgstr ""
"[Patrones de diseño](https://en.wikipedia.org/wiki/Software_design_pattern) "
"son\n"
"\"soluciones generales reutilizables para un problema común dentro de un "
"determinado\n"
"contexto en el diseño de software\". Los patrones de diseño son una "
"excelente manera de describir el\n"
"cultura de un lenguaje de programación. Los patrones de diseño son muy "
"específicos del idioma:\n"
"lo que es un patrón en un idioma puede ser innecesario en otro debido a una\n"
"característica del idioma, o imposible de expresar debido a la falta de una "
"característica."
#: src\patterns/index.md:10
#, fuzzy
msgid ""
"If overused, design patterns can add unnecessary complexity to programs.\n"
"However, they are a great way to share intermediate and advanced level "
"knowledge\n"
"about a programming language."
msgstr ""
"Si se usan en exceso, los patrones de diseño pueden agregar una complejidad "
"innecesaria a los programas.\n"
"Sin embargo, son una excelente manera de compartir conocimientos de nivel "
"intermedio y avanzado.\n"
"sobre un lenguaje de programación."
#: src\patterns/index.md:16
#, fuzzy
msgid ""
"Rust has many unique features. These features give us great benefit by "
"removing\n"
"whole classes of problems. Some of them are also patterns that are _unique_ "
"to Rust."
msgstr ""
"Rust tiene muchas características únicas. Estas características nos brindan "
"un gran beneficio al eliminar\n"
"Clases enteras de problemas. Algunos de ellos también son patrones que son "
"_exclusivos_ de Rust."
#: src\patterns/index.md:19
#, fuzzy
msgid "## YAGNI"
msgstr "## YAGNI"
#: src\patterns/index.md:21
#, fuzzy
msgid ""
"YAGNI is an acronym that stands for `You Aren't Going to Need It`.\n"
"It's a vital software design principle to apply as you write code."
msgstr ""
"YAGNI es un acrónimo que significa `No lo vas a necesitar'.\n"
"Es un principio vital de diseño de software para aplicar mientras escribe "
"código."
#: src\patterns/index.md:24
#, fuzzy
msgid "> The best code I ever wrote was code I never wrote."
msgstr "> El mejor código que jamás escribí fue código que nunca escribí."
#: src\patterns/index.md:26
#, fuzzy
msgid ""
"If we apply YAGNI to design patterns, we see that the features of Rust allow "
"us to\n"
"throw out many patterns. For instance, there is no need for the [strategy "
"pattern](https://en.wikipedia.org/wiki/Strategy_pattern)\n"
"in Rust because we can just use "
"[traits](https://doc.rust-lang.org/book/traits.html)."
msgstr ""
"Si aplicamos YAGNI a los patrones de diseño, vemos que las características "
"de Rust nos permiten\n"
"tirar muchos patrones. Por ejemplo, no es necesario el [patrón de "
"estrategia] (https://en.wikipedia.org/wiki/Strategy_pattern)\n"
"en Rust porque solo podemos usar "
"[traits](https://doc.rust-lang.org/book/traits.html)."
#: src\patterns/behavioural/intro.md:1
#, fuzzy
msgid "# Behavioural Patterns"
msgstr "# Patrones de comportamiento"
#: src\patterns/behavioural/intro.md:3
#, fuzzy
msgid "From [Wikipedia](https://en.wikipedia.org/wiki/Behavioral_pattern):"
msgstr "De [Wikipedia](https://en.wikipedia.org/wiki/Behavioral_pattern):"
#: src\patterns/behavioural/intro.md:5
#, fuzzy
msgid ""
"> Design patterns that identify common communication patterns among "
"objects.\n"
"> By doing so, these patterns increase flexibility in carrying out "
"communication."
msgstr ""
"> Patrones de diseño que identifican patrones de comunicación comunes entre "
"objetos.\n"
"> Al hacerlo, estos patrones aumentan la flexibilidad en la realización de "
"la comunicación."
#: src\patterns/behavioural/command.md:1
#, fuzzy
msgid "# Command"
msgstr "# Dominio"
#: src\patterns/behavioural/command.md:5
#, fuzzy
msgid ""
"The basic idea of the Command pattern is to separate out actions into its "
"own\n"
"objects and pass them as parameters."
msgstr ""
"La idea básica del patrón Comando es separar las acciones en sus propias\n"
"objetos y pasarlos como parámetros."
#: src\patterns/behavioural/command.md:10
#, fuzzy
msgid ""
"Suppose we have a sequence of actions or transactions encapsulated as "
"objects.\n"
"We want these actions or commands to be executed or invoked in some order "
"later\n"
"at different time. These commands may also be triggered as a result of some "
"event.\n"
"For example, when a user pushes a button, or on arrival of a data packet.\n"
"In addition, these commands might be undoable. This may come in useful for\n"
"operations of an editor. We might want to store logs of executed commands so "
"that\n"
"we could reapply the changes later if the system crashes."
msgstr ""
"Supongamos que tenemos una secuencia de acciones o transacciones "
"encapsuladas como objetos.\n"
"Queremos que estas acciones o comandos se ejecuten o invoquen en algún orden "
"más adelante\n"
"en tiempo diferente. Estos comandos también pueden activarse como resultado "
"de algún evento.\n"
"Por ejemplo, cuando un usuario presiona un botón o cuando llega un paquete "
"de datos.\n"
"Además, estos comandos se pueden deshacer. Esto puede ser útil para\n"
"operaciones de un editor. Podríamos querer almacenar registros de comandos "
"ejecutados para que\n"
"podríamos volver a aplicar los cambios más tarde si el sistema falla."
#: src\patterns/behavioural/command.md:20
#, fuzzy
msgid ""
"Define two database operations `create table` and `add field`. Each of "
"these\n"
"operations is a command which knows how to undo the command, e.g., `drop "
"table`\n"
"and `remove field`. When a user invokes a database migration operation then "
"each\n"
"command is executed in the defined order, and when the user invokes the "
"rollback\n"
"operation then the whole set of commands is invoked in reverse order."
msgstr ""
"Defina dos operaciones de base de datos `crear tabla` y `agregar campo`. "
"Cada uno de estos\n"
"operaciones es un comando que sabe cómo deshacer el comando, por ejemplo, "
"`drop table`\n"
"y `eliminar campo`. Cuando un usuario invoca una operación de migración de "
"base de datos, cada\n"
"el comando se ejecuta en el orden definido, y cuando el usuario invoca la "
"reversión\n"
"operación, entonces todo el conjunto de comandos se invoca en orden inverso."
#: src\patterns/behavioural/command.md:26
#, fuzzy
msgid "## Approach: Using trait objects"
msgstr "## Enfoque: uso de objetos de rasgos"
#: src\patterns/behavioural/command.md:28
#, fuzzy
msgid ""
"We define a common trait which encapsulates our command with two operations\n"
"`execute` and `rollback`. All command `structs` must implement this trait."
msgstr ""
"Definimos un rasgo común que encapsula nuestro comando con dos operaciones\n"
"`ejecutar` y `retroceder`. Todas las `estructuras` de comando deben "
"implementar este rasgo."
#: src\patterns/behavioural/command.md:31
msgid ""
"```rust\n"
"pub trait Migration {\n"
" fn execute(&self) -> &str;\n"
" fn rollback(&self) -> &str;\n"
"}\n"
"\n"
"pub struct CreateTable;\n"
"impl Migration for CreateTable {\n"
" fn execute(&self) -> &str {\n"
" \"create table\"\n"
" }\n"
" fn rollback(&self) -> &str {\n"
" \"drop table\"\n"
" }\n"
"}\n"
"\n"
"pub struct AddField;\n"
"impl Migration for AddField {\n"
" fn execute(&self) -> &str {\n"
" \"add field\"\n"
" }\n"
" fn rollback(&self) -> &str {\n"
" \"remove field\"\n"
" }\n"
"}\n"
"\n"
"struct Schema {\n"
" commands: Vec<Box<dyn Migration>>,\n"
"}\n"
"\n"
"impl Schema {\n"
" fn new() -> Self {\n"
" Self { commands: vec![] }\n"
" }\n"
"\n"
" fn add_migration(&mut self, cmd: Box<dyn Migration>) {\n"
" self.commands.push(cmd);\n"
" }\n"
"\n"
" fn execute(&self) -> Vec<&str> {\n"
" self.commands.iter().map(|cmd| cmd.execute()).collect()\n"
" }\n"
" fn rollback(&self) -> Vec<&str> {\n"
" self.commands\n"
" .iter()\n"
" .rev() // reverse iterator's direction\n"
" .map(|cmd| cmd.rollback())\n"
" .collect()\n"
" }\n"
"}\n"
"\n"
"fn main() {\n"
" let mut schema = Schema::new();\n"
"\n"
" let cmd = Box::new(CreateTable);\n"
" schema.add_migration(cmd);\n"
" let cmd = Box::new(AddField);\n"
" schema.add_migration(cmd);\n"
"\n"
" assert_eq!(vec![\"create table\", \"add field\"], schema.execute());\n"
" assert_eq!(vec![\"remove field\", \"drop table\"], schema.rollback());\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/command.md:95
#, fuzzy
msgid "## Approach: Using function pointers"
msgstr "## Enfoque: uso de punteros de función"
#: src\patterns/behavioural/command.md:97
#, fuzzy
msgid ""
"We could follow another approach by creating each individual command as\n"
"a different function and store function pointers to invoke these functions "
"later\n"
"at a different time. Since function pointers implement all three traits "
"`Fn`,\n"
"`FnMut`, and `FnOnce` we could as well pass and store closures instead of\n"
"function pointers."
msgstr ""
"Podríamos seguir otro enfoque creando cada comando individual como\n"
"una función diferente y almacenar punteros de función para invocar estas "
"funciones más tarde\n"
"en un momento diferente. Dado que los punteros de función implementan los "
"tres rasgos `Fn`,\n"
"`FnMut` y `FnOnce` también podríamos pasar y almacenar cierres en lugar de\n"
"punteros de función."
#: src\patterns/behavioural/command.md:103
msgid ""
"```rust\n"
"type FnPtr = fn() -> String;\n"
"struct Command {\n"
" execute: FnPtr,\n"
" rollback: FnPtr,\n"
"}\n"
"\n"
"struct Schema {\n"
" commands: Vec<Command>,\n"
"}\n"
"\n"
"impl Schema {\n"
" fn new() -> Self {\n"
" Self { commands: vec![] }\n"
" }\n"
" fn add_migration(&mut self, execute: FnPtr, rollback: FnPtr) {\n"
" self.commands.push(Command { execute, rollback });\n"
" }\n"
" fn execute(&self) -> Vec<String> {\n"
" self.commands.iter().map(|cmd| (cmd.execute)()).collect()\n"
" }\n"
" fn rollback(&self) -> Vec<String> {\n"
" self.commands\n"
" .iter()\n"
" .rev()\n"
" .map(|cmd| (cmd.rollback)())\n"
" .collect()\n"
" }\n"
"}\n"
"\n"
"fn add_field() -> String {\n"
" \"add field\".to_string()\n"
"}\n"
"\n"
"fn remove_field() -> String {\n"
" \"remove field\".to_string()\n"
"}\n"
"\n"
"fn main() {\n"
" let mut schema = Schema::new();\n"
" schema.add_migration(|| \"create table\".to_string(), || \"drop "
"table\".to_string());\n"
" schema.add_migration(add_field, remove_field);\n"
" assert_eq!(vec![\"create table\", \"add field\"], schema.execute());\n"
" assert_eq!(vec![\"remove field\", \"drop table\"], schema.rollback());\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/command.md:150
#, fuzzy
msgid "## Approach: Using `Fn` trait objects"
msgstr "## Enfoque: Uso de objetos de rasgos `Fn`"
#: src\patterns/behavioural/command.md:152
#, fuzzy
msgid ""
"Finally, instead of defining a common command trait we could store\n"
"each command implementing the `Fn` trait separately in vectors."
msgstr ""
"Finalmente, en lugar de definir un rasgo de comando común, podríamos "
"almacenar\n"
"cada comando implementa el rasgo `Fn` por separado en vectores."
#: src\patterns/behavioural/command.md:155
msgid ""
"```rust\n"
"type Migration<'a> = Box<dyn Fn() -> &'a str>;\n"
"\n"
"struct Schema<'a> {\n"
" executes: Vec<Migration<'a>>,\n"
" rollbacks: Vec<Migration<'a>>,\n"
"}\n"
"\n"
"impl<'a> Schema<'a> {\n"
" fn new() -> Self {\n"
" Self {\n"
" executes: vec![],\n"
" rollbacks: vec![],\n"
" }\n"
" }\n"
" fn add_migration<E, R>(&mut self, execute: E, rollback: R)\n"
" where\n"
" E: Fn() -> &'a str + 'static,\n"
" R: Fn() -> &'a str + 'static,\n"
" {\n"
" self.executes.push(Box::new(execute));\n"
" self.rollbacks.push(Box::new(rollback));\n"
" }\n"
" fn execute(&self) -> Vec<&str> {\n"
" self.executes.iter().map(|cmd| cmd()).collect()\n"
" }\n"
" fn rollback(&self) -> Vec<&str> {\n"
" self.rollbacks.iter().rev().map(|cmd| cmd()).collect()\n"
" }\n"
"}\n"
"\n"
"fn add_field() -> &'static str {\n"
" \"add field\"\n"
"}\n"
"\n"
"fn remove_field() -> &'static str {\n"
" \"remove field\"\n"
"}\n"
"\n"
"fn main() {\n"
" let mut schema = Schema::new();\n"
" schema.add_migration(|| \"create table\", || \"drop table\");\n"
" schema.add_migration(add_field, remove_field);\n"
" assert_eq!(vec![\"create table\", \"add field\"], schema.execute());\n"
" assert_eq!(vec![\"remove field\", \"drop table\"], schema.rollback());\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/command.md:205
#, fuzzy
msgid ""
"If our commands are small and may be defined as functions or passed as a "
"closure\n"
"then using function pointers might be preferable since it does not exploit\n"
"dynamic dispatch. But if our command is a whole struct with a bunch of "
"functions\n"
"and variables defined as seperated module then using trait objects would be\n"
"more suitable. A case of application can be found in "
"[`actix`](https://actix.rs/),\n"
"which uses trait objects when it registers a handler function for routes.\n"
"In case of using `Fn` trait objects we can create and use commands in the "
"same\n"
"way as we used in case of function pointers."
msgstr ""
"Si nuestros comandos son pequeños y pueden definirse como funciones o "
"pasarse como cierre\n"
"entonces podría ser preferible usar punteros de función, ya que no explota\n"
"despacho dinámico. Pero si nuestro comando es una estructura completa con un "
"montón de funciones\n"
"y variables definidas como módulo separado, entonces usar objetos de rasgos "
"sería\n"
"mas apropiado. Se puede encontrar un caso de aplicación en "
"[`actix`](https://actix.rs/),\n"
"que usa objetos de rasgos cuando registra una función de controlador para "
"rutas.\n"
"En caso de usar objetos de rasgo `Fn` podemos crear y usar comandos en el "
"mismo\n"
"tal como lo usamos en el caso de los punteros de función."
#: src\patterns/behavioural/command.md:214
#, fuzzy
msgid ""
"As performance, there is always a trade-off between performance and code\n"
"simplicity and organisation. Static dispatch gives faster performance, "
"while\n"
"dynamic dispatch provides flexibility when we structure our application."
msgstr ""
"Como rendimiento, siempre hay una compensación entre el rendimiento y el "
"código.\n"
"sencillez y organización. El despacho estático proporciona un rendimiento "
"más rápido, mientras que\n"
"El despacho dinámico proporciona flexibilidad cuando estructuramos nuestra "
"aplicación."
#: src\patterns/behavioural/command.md:220
#, fuzzy
msgid ""
"- [Command pattern](https://en.wikipedia.org/wiki/Command_pattern)\n"
"\n"
"- [Another example for the `command` "
"pattern](https://web.archive.org/web/20210223131236/https://chercher.tech/rust/command-design-pattern-rust)"
msgstr ""
"- [Patrón de comando](https://en.wikipedia.org/wiki/Command_pattern)\n"
"\n"
"- [Otro ejemplo del patrón "
"`comando`](https://web.archive.org/web/20210223131236/https://chercher.tech/rust/command-design-pattern-rust)"
#: src\patterns/behavioural/interpreter.md:1
#, fuzzy
msgid "# Interpreter"
msgstr "# Intérprete"
#: src\patterns/behavioural/interpreter.md:5
#, fuzzy
msgid ""
"If a problem occurs very often and requires long and repetitive steps to "
"solve\n"
"it, then the problem instances might be expressed in a simple language and "
"an\n"
"interpreter object could solve it by interpreting the sentences written in "
"this\n"
"simple language."
msgstr ""
"Si un problema ocurre con mucha frecuencia y requiere pasos largos y "
"repetitivos para resolverlo\n"
"entonces las instancias del problema podrían expresarse en un lenguaje "
"simple y un\n"
"El objeto intérprete podría resolverlo interpretando las oraciones escritas "
"en este\n"
"lenguaje sencillo"
#: src\patterns/behavioural/interpreter.md:10
#, fuzzy
msgid "Basically, for any kind of problems we define:"
msgstr "Básicamente, para cualquier tipo de problema definimos:"
#: src\patterns/behavioural/interpreter.md:12
#, fuzzy
msgid ""
"- A [domain specific "
"language](https://en.wikipedia.org/wiki/Domain-specific_language),\n"
"- A grammar for this language,\n"
"- An interpreter that solves the problem instances."
msgstr ""
"- Un [idioma específico del "
"dominio](https://en.wikipedia.org/wiki/Domain-specific_language),\n"
"- Una gramática para este idioma,\n"
"- Un intérprete que resuelve las instancias del problema."
#: src\patterns/behavioural/interpreter.md:18
#, fuzzy
msgid ""
"Our goal is to translate simple mathematical expressions into postfix "
"expressions\n"
"(or [Reverse Polish "
"notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation))\n"
"For simplicity, our expressions consist of ten digits `0`, ..., `9` and two\n"
"operations `+`, `-`. For example, the expression `2 + 4` is translated into\n"
"`2 4 +`."
msgstr ""
"Nuestro objetivo es traducir expresiones matemáticas simples en expresiones "
"postfix\n"
"(o [notación polaca "
"inversa](https://en.wikipedia.org/wiki/Reverse_Polish_notation))\n"
"Para simplificar, nuestras expresiones constan de diez dígitos `0`, ..., `9` "
"y dos\n"
"operaciones `+`, `-`. Por ejemplo, la expresión `2 + 4` se traduce a\n"
"`2 4 +`."
#: src\patterns/behavioural/interpreter.md:24
#, fuzzy
msgid "## Context Free Grammar for our problem"
msgstr "## Gramática libre de contexto para nuestro problema"
#: src\patterns/behavioural/interpreter.md:26
#, fuzzy
msgid ""
"Our task is translating infix expressions into postfix ones. Let's define a "
"context\n"
"free grammar for a set of infix expressions over `0`, ..., `9`, `+`, and "
"`-`,\n"
"where:"
msgstr ""
"Nuestra tarea es traducir expresiones infijas a postfijas. Definamos un "
"contexto\n"
"gramática libre para un conjunto de expresiones infijas sobre `0`, ..., `9`, "
"`+` y `-`,\n"
"dónde:"
#: src\patterns/behavioural/interpreter.md:30
#, fuzzy
msgid ""
"- Terminal symbols: `0`, `...`, `9`, `+`, `-`\n"
"- Non-terminal symbols: `exp`, `term`\n"
"- Start symbol is `exp`\n"
"- And the following are production rules"
msgstr ""
"- Símbolos terminales: `0`, `...`, `9`, `+`, `-`\n"
"- Símbolos no terminales: `exp`, `term`\n"
"- El símbolo de inicio es `exp`\n"
"- Y las siguientes son reglas de producción."
#: src\patterns/behavioural/interpreter.md:35
msgid ""
"```ignore\n"
"exp -> exp + term\n"
"exp -> exp - term\n"
"exp -> term\n"
"term -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9\n"
"```"
msgstr ""
#: src\patterns/behavioural/interpreter.md:42
#, fuzzy
msgid ""
"**NOTE:** This grammar should be further transformed depending on what we "
"are going\n"
"to do with it. For example, we might need to remove left recursion. For "
"more\n"
"details please see [Compilers: Principles,Techniques, and "
"Tools](https://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools)\n"
"(aka Dragon Book)."
msgstr ""
"**NOTA:** Esta gramática debe transformarse aún más dependiendo de lo que "
"estemos haciendo\n"
"hacer con eso Por ejemplo, es posible que necesitemos eliminar la "
"recursividad por la izquierda. Para más\n"
"detalles, consulte [Compiladores: principios, técnicas y herramientas] "
"(https://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools)\n"
"(también conocido como Libro del Dragón)."
#: src\patterns/behavioural/interpreter.md:47
#, fuzzy
msgid "## Solution"
msgstr "## Solución"
#: src\patterns/behavioural/interpreter.md:49
#, fuzzy
msgid ""
"We simply implement a recursive descent parser. For simplicity's sake, the "
"code\n"
"panics when an expression is syntactically wrong (for example `2-34` or "
"`2+5-`\n"
"are wrong according to the grammar definition)."
msgstr ""
"Simplemente implementamos un analizador de descenso recursivo. En aras de la "
"simplicidad, el código\n"
"entra en pánico cuando una expresión es sintácticamente incorrecta (por "
"ejemplo, `2-34` o `2+5-`\n"
"están mal según la definición gramatical)."
#: src\patterns/behavioural/interpreter.md:53
msgid ""
"```rust\n"
"pub struct Interpreter<'a> {\n"
" it: std::str::Chars<'a>,\n"
"}\n"
"\n"
"impl<'a> Interpreter<'a> {\n"
"\n"
" pub fn new(infix: &'a str) -> Self {\n"
" Self { it: infix.chars() }\n"
" }\n"
"\n"
" fn next_char(&mut self) -> Option<char> {\n"
" self.it.next()\n"
" }\n"
"\n"
" pub fn interpret(&mut self, out: &mut String) {\n"
" self.term(out);\n"
"\n"
" while let Some(op) = self.next_char() {\n"
" if op == '+' || op == '-' {\n"
" self.term(out);\n"
" out.push(op);\n"
" } else {\n"
" panic!(\"Unexpected symbol '{}'\", op);\n"
" }\n"
" }\n"
" }\n"
"\n"
" fn term(&mut self, out: &mut String) {\n"
" match self.next_char() {\n"
" Some(ch) if ch.is_digit(10) => out.push(ch),\n"
" Some(ch) => panic!(\"Unexpected symbol '{}'\", ch),\n"
" None => panic!(\"Unexpected end of string\"),\n"
" }\n"
" }\n"
"}\n"
"\n"
"pub fn main() {\n"
" let mut intr = Interpreter::new(\"2+3\");\n"
" let mut postfix = String::new();\n"
" intr.interpret(&mut postfix);\n"
" assert_eq!(postfix, \"23+\");\n"
"\n"
" intr = Interpreter::new(\"1-2+3-4\");\n"
" postfix.clear();\n"
" intr.interpret(&mut postfix);\n"
" assert_eq!(postfix, \"12-3+4-\");\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/interpreter.md:105
#, fuzzy
msgid ""
"There may be a wrong perception that the Interpreter design pattern is about "
"design\n"
"grammars for formal languages and implementation of parsers for these "
"grammars.\n"
"In fact, this pattern is about expressing problem instances in a more "
"specific\n"
"way and implementing functions/classes/structs that solve these problem "
"instances.\n"
"Rust language has `macro_rules!` that allow us to define special syntax and "
"rules\n"
"on how to expand this syntax into source code."
msgstr ""
"Puede haber una percepción errónea de que el patrón de diseño del Intérprete "
"se trata de diseño\n"
"gramáticas para lenguajes formales e implementación de analizadores para "
"estas gramáticas.\n"
"De hecho, este patrón se trata de expresar instancias de problemas en una "
"forma más específica.\n"
"e implementando funciones/clases/estructuras que resuelven estas instancias "
"de problemas.\n"
"El lenguaje Rust tiene `macro_rules!` que nos permiten definir sintaxis y "
"reglas especiales\n"
"sobre cómo expandir esta sintaxis en el código fuente."
#: src\patterns/behavioural/interpreter.md:112
#, fuzzy
msgid ""
"In the following example we create a simple `macro_rules!` that computes\n"
"[Euclidean length](https://en.wikipedia.org/wiki/Euclidean_distance) of `n`\n"
"dimensional vectors. Writing `norm!(x,1,2)` might be easier to express and "
"more\n"
"efficient than packing `x,1,2` into a `Vec` and calling a function "
"computing\n"
"the length."
msgstr ""
"En el siguiente ejemplo, creamos un `macro_rules!` simple que calcula\n"
"[Longitud euclidiana](https://en.wikipedia.org/wiki/Euclidean_distance) de "
"`n`\n"
"vectores dimensionales. Escribir `norma!(x,1,2)` podría ser más fácil de "
"expresar y más\n"
"más eficiente que empaquetar `x,1,2` en un `Vec` y llamar a una función "
"informática\n"
"la longitud."
#: src\patterns/behavioural/interpreter.md:118
msgid ""
"```rust\n"
"macro_rules! norm {\n"
" ($($element:expr),*) => {\n"
" {\n"
" let mut n = 0.0;\n"
" $(\n"
" n += ($element as f64)*($element as f64);\n"
" )*\n"
" n.sqrt()\n"
" }\n"
" };\n"
"}\n"
"\n"
"fn main() {\n"
" let x = -3f64;\n"
" let y = 4f64;\n"
"\n"
" assert_eq!(3f64, norm!(x));\n"
" assert_eq!(5f64, norm!(x, y));\n"
" assert_eq!(0f64, norm!(0, 0, 0)); \n"
" assert_eq!(1f64, norm!(0.5, -0.5, 0.5, -0.5));\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/interpreter.md:144
#, fuzzy
msgid ""
"- [Interpreter pattern](https://en.wikipedia.org/wiki/Interpreter_pattern)\n"
"- [Context free "
"grammar](https://en.wikipedia.org/wiki/Context-free_grammar)\n"
"- [macro_rules!](https://doc.rust-lang.org/rust-by-example/macros.html)"
msgstr ""
"- [Patrón de intérprete](https://en.wikipedia.org/wiki/Interpreter_pattern)\n"
"- [Gramática libre de "
"contexto](https://en.wikipedia.org/wiki/Context-free_grammar)\n"
"- [macro_rules!](https://doc.rust-lang.org/rust-by-example/macros.html)"
#: src\patterns/behavioural/newtype.md:1
#, fuzzy
msgid "# Newtype"
msgstr "# Nuevo tipo"
#: src\patterns/behavioural/newtype.md:3
#, fuzzy
msgid ""
"What if in some cases we want a type to behave similar to another type or\n"
"enforce some behaviour at compile time when using only type aliases would\n"
"not be enough?"
msgstr ""
"¿Qué pasa si en algunos casos queremos que un tipo se comporte de manera "
"similar a otro tipo o\n"
"hacer cumplir algún comportamiento en tiempo de compilación cuando usar solo "
"alias de tipo sería\n"
"no ser suficiente?"
#: src\patterns/behavioural/newtype.md:7
#, fuzzy
msgid ""
"For example, if we want to create a custom `Display` implementation for "
"`String`\n"
"due to security considerations (e.g. passwords)."
msgstr ""
"Por ejemplo, si queremos crear una implementación `Display` personalizada "
"para `String`\n"
"debido a consideraciones de seguridad (por ejemplo, contraseñas)."
#: src\patterns/behavioural/newtype.md:10
#, fuzzy
msgid ""
"For such cases we could use the `Newtype` pattern to provide **type "
"safety**\n"
"and **encapsulation**."
msgstr ""
"Para tales casos, podríamos usar el patrón `Newtype` para proporcionar "
"**seguridad de tipo**\n"
"y **encapsulación**."
#: src\patterns/behavioural/newtype.md:15
#, fuzzy
msgid ""
"Use a tuple struct with a single field to make an opaque wrapper for a "
"type.\n"
"This creates a new type, rather than an alias to a type (`type` items)."
msgstr ""
"Use una estructura de tupla con un solo campo para crear un contenedor opaco "
"para un tipo.\n"
"Esto crea un nuevo tipo, en lugar de un alias para un tipo (elementos "
"`tipo`)."
#: src\patterns/behavioural/newtype.md:20
msgid ""
"```rust,ignore\n"
"// Some type, not necessarily in the same module or even crate.\n"
"struct Foo {\n"
" //..\n"
"}\n"
"\n"
"impl Foo {\n"
" // These functions are not present on Bar.\n"
" //..\n"
"}\n"
"\n"
"// The newtype.\n"
"pub struct Bar(Foo);\n"
"\n"
"impl Bar {\n"
" // Constructor.\n"
" pub fn new(\n"
" //..\n"
" ) -> Self {\n"
"\n"
" //..\n"
"\n"
" }\n"
"\n"
" //..\n"
"}\n"
"\n"
"fn main() {\n"
" let b = Bar::new(...);\n"
"\n"
" // Foo and Bar are type incompatible, the following do not type check.\n"
" // let f: Foo = b;\n"
" // let b: Bar = Foo { ... };\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/newtype.md:58
#, fuzzy
msgid ""
"The primary motivation for newtypes is abstraction. It allows you to share\n"
"implementation details between types while precisely controlling the "
"interface.\n"
"By using a newtype rather than exposing the implementation type as part of "
"an\n"
"API, it allows you to change implementation backwards compatibly."
msgstr ""
"La principal motivación para los nuevos tipos es la abstracción. Te permite "
"compartir\n"
"detalles de implementación entre tipos mientras controla con precisión la "
"interfaz.\n"
"Al usar un nuevo tipo en lugar de exponer el tipo de implementación como "
"parte de un\n"
"API, le permite cambiar la implementación de manera retrocompatible."
#: src\patterns/behavioural/newtype.md:63
#, fuzzy
msgid ""
"Newtypes can be used for distinguishing units, e.g., wrapping `f64` to give\n"
"distinguishable `Miles` and `Kilometres`."
msgstr ""
"Los tipos nuevos se pueden usar para distinguir unidades, por ejemplo, "
"envolviendo `f64` para dar\n"
"distinguibles `Millas` y `Kilómetros`."
#: src\patterns/behavioural/newtype.md:68
#, fuzzy
msgid ""
"The wrapped and wrapper types are not type compatible (as opposed to using\n"
"`type`), so users of the newtype will never 'confuse' the wrapped and "
"wrapper\n"
"types."
msgstr ""
"Los tipos wrapper y wrapper no son compatibles (a diferencia de usar\n"
"`tipo`), por lo que los usuarios del nuevo tipo nunca 'confundirán' el "
"envuelto y el envoltorio\n"
"tipos"
#: src\patterns/behavioural/newtype.md:72
#, fuzzy
msgid "Newtypes are a zero-cost abstraction - there is no runtime overhead."
msgstr ""
"Los tipos nuevos son una abstracción de costo cero: no hay sobrecarga de "
"tiempo de ejecución."
#: src\patterns/behavioural/newtype.md:74
#, fuzzy
msgid ""
"The privacy system ensures that users cannot access the wrapped type (if "
"the\n"
"field is private, which it is by default)."
msgstr ""
"El sistema de privacidad garantiza que los usuarios no puedan acceder al "
"tipo envuelto (si el\n"
"el campo es privado, que es por defecto)."
#: src\patterns/behavioural/newtype.md:79
#, fuzzy
msgid ""
"The downside of newtypes (especially compared with type aliases), is that "
"there\n"
"is no special language support. This means there can be _a lot_ of "
"boilerplate.\n"
"You need a 'pass through' method for every method you want to expose on the\n"
"wrapped type, and an impl for every trait you want to also be implemented "
"for\n"
"the wrapper type."
msgstr ""
"La desventaja de los nuevos tipos (especialmente en comparación con los "
"alias de tipo) es que no\n"
"no hay soporte de idioma especial. Esto significa que puede haber _mucho_ "
"repetitivo.\n"
"Necesita un método de 'paso a través' para cada método que desee exponer en "
"el\n"
"tipo envuelto, y un impl para cada rasgo que desea implementar también para\n"
"el tipo de envoltura."
#: src\patterns/behavioural/newtype.md:87
#, fuzzy
msgid ""
"Newtypes are very common in Rust code. Abstraction or representing units are "
"the\n"
"most common uses, but they can be used for other reasons:"
msgstr ""
"Los tipos nuevos son muy comunes en el código de Rust. Las unidades de "
"abstracción o representación son las\n"
"usos más comunes, pero pueden ser utilizados por otras razones:"
#: src\patterns/behavioural/newtype.md:90
#, fuzzy
msgid ""
"- restricting functionality (reduce the functions exposed or traits "
"implemented),\n"
"- making a type with copy semantics have move semantics,\n"
"- abstraction by providing a more concrete type and thus hiding internal "
"types,\n"
" e.g.,"
msgstr ""
"- restringir la funcionalidad (reducir las funciones expuestas o los rasgos "
"implementados),\n"
"- hacer que un tipo con semántica de copia tenga semántica de movimiento,\n"
"- abstracción proporcionando un tipo más concreto y ocultando así los tipos "
"internos,\n"
" p.ej.,"
#: src\patterns/behavioural/newtype.md:95
msgid ""
"```rust,ignore\n"
"pub struct Foo(Bar<T1, T2>);\n"
"```"
msgstr ""
#: src\patterns/behavioural/newtype.md:99
#, fuzzy
msgid ""
"Here, `Bar` might be some public, generic type and `T1` and `T2` are some "
"internal\n"
"types. Users of our module shouldn't know that we implement `Foo` by using a "
"`Bar`,\n"
"but what we're really hiding here is the types `T1` and `T2`, and how they "
"are used\n"
"with `Bar`."
msgstr ""
"Aquí, 'Bar' podría ser un tipo genérico público y 'T1' y 'T2' son algunos "
"internos.\n"
"tipos Los usuarios de nuestro módulo no deberían saber que implementamos "
"`Foo` usando una `Bar`,\n"
"pero lo que realmente estamos ocultando aquí son los tipos `T1` y `T2`, y "
"cómo se usan\n"
"con `Barra`."
#: src\patterns/behavioural/newtype.md:106
#, fuzzy
msgid ""
"- [Advanced Types in the "
"book](https://doc.rust-lang.org/book/ch19-04-advanced-types.html?highlight=newtype#using-the-newtype-pattern-for-type-safety-and-abstraction)\n"
"- [Newtypes in Haskell](https://wiki.haskell.org/Newtype)\n"
"- [Type "
"aliases](https://doc.rust-lang.org/stable/book/ch19-04-advanced-types.html#creating-type-synonyms-with-type-aliases)\n"
"- [derive_more](https://crates.io/crates/derive_more), a crate for deriving "
"many\n"
" builtin traits on newtypes.\n"
"- [The Newtype Pattern In "
"Rust](https://www.worthe-it.co.za/blog/2020-10-31-newtype-pattern-in-rust.html)"
msgstr ""
"- [Tipos avanzados en el "
"libro](https://doc.rust-lang.org/book/ch19-04-advanced-types.html?highlight=newtype#using-the-newtype-pattern-for-type-safety "
"-y-abstracción)\n"
"- [Nuevos tipos en Haskell](https://wiki.haskell.org/Newtype)\n"
"- [Escriba "
"alias](https://doc.rust-lang.org/stable/book/ch19-04-advanced-types.html#creating-type-synonyms-with-type-aliases)\n"
"- [derive_more](https://crates.io/crates/derive_more), una caja para derivar "
"muchos\n"
" rasgos incorporados en newtypes.\n"
"- [El patrón Newtype en "
"Rust](https://www.worthe-it.co.za/blog/2020-10-31-newtype-pattern-in-rust.html)"
#: src\patterns/behavioural/RAII.md:1
#, fuzzy
msgid "# RAII with guards"
msgstr "# RAII con guardias"
#: src\patterns/behavioural/RAII.md:5
#, fuzzy
msgid ""
"[RAII][wikipedia] stands for \"Resource Acquisition is Initialisation\" "
"which is a\n"
"terrible name. The essence of the pattern is that resource initialisation is "
"done\n"
"in the constructor of an object and finalisation in the destructor. This "
"pattern\n"
"is extended in Rust by using a RAII object as a guard of some resource and "
"relying\n"
"on the type system to ensure that access is always mediated by the guard "
"object."
msgstr ""
"[RAII][wikipedia] significa \"Adquisición de recursos es inicialización\", "
"que es una\n"
"terrible nombre La esencia del patrón es que la inicialización de recursos "
"se realiza\n"
"en el constructor de un objeto y finalización en el destructor. este patrón\n"
"se extiende en Rust usando un objeto RAII como guardián de algún recurso y "
"confiando\n"
"en el sistema de tipos para garantizar que el acceso siempre esté mediado "
"por el objeto guardián."
#: src\patterns/behavioural/RAII.md:13
#, fuzzy
msgid ""
"Mutex guards are the classic example of this pattern from the std library "
"(this\n"
"is a simplified version of the real implementation):"
msgstr ""
"Los protectores Mutex son el ejemplo clásico de este patrón de la biblioteca "
"estándar (este\n"
"es una versión simplificada de la implementación real):"
#: src\patterns/behavioural/RAII.md:16
msgid ""
"```rust,ignore\n"
"use std::ops::Deref;\n"
"\n"
"struct Foo {}\n"
"\n"
"struct Mutex<T> {\n"
" // We keep a reference to our data: T here.\n"
" //..\n"
"}\n"
"\n"
"struct MutexGuard<'a, T: 'a> {\n"
" data: &'a T,\n"
" //..\n"
"}\n"
"\n"
"// Locking the mutex is explicit.\n"
"impl<T> Mutex<T> {\n"
" fn lock(&self) -> MutexGuard<T> {\n"
" // Lock the underlying OS mutex.\n"
" //..\n"
"\n"
" // MutexGuard keeps a reference to self\n"
" MutexGuard {\n"
" data: self,\n"
" //..\n"
" }\n"
" }\n"
"}\n"
"\n"
"// Destructor for unlocking the mutex.\n"
"impl<'a, T> Drop for MutexGuard<'a, T> {\n"
" fn drop(&mut self) {\n"
" // Unlock the underlying OS mutex.\n"
" //..\n"
" }\n"
"}\n"
"\n"
"// Implementing Deref means we can treat MutexGuard like a pointer to T.\n"
"impl<'a, T> Deref for MutexGuard<'a, T> {\n"
" type Target = T;\n"
"\n"
" fn deref(&self) -> &T {\n"
" self.data\n"
" }\n"
"}\n"
"\n"
"fn baz(x: Mutex<Foo>) {\n"
" let xx = x.lock();\n"
" xx.foo(); // foo is a method on Foo.\n"
" // The borrow checker ensures we can't store a reference to the "
"underlying\n"
" // Foo which will outlive the guard xx.\n"
"\n"
" // x is unlocked when we exit this function and xx's destructor is "
"executed.\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/RAII.md:74
#, fuzzy
msgid ""
"Where a resource must be finalised after use, RAII can be used to do this\n"
"finalisation. If it is an error to access that resource after finalisation, "
"then\n"
"this pattern can be used to prevent such errors."
msgstr ""
"Cuando un recurso debe finalizarse después de su uso, se puede usar RAII "
"para hacer esto\n"
"finalización Si es un error acceder a ese recurso después de la "
"finalización, entonces\n"
"este patrón se puede utilizar para evitar tales errores."
#: src\patterns/behavioural/RAII.md:80
#, fuzzy
msgid ""
"Prevents errors where a resource is not finalised and where a resource is "
"used\n"
"after finalisation."
msgstr ""
"Previene errores donde un recurso no está finalizado y donde se usa un "
"recurso\n"
"después de la finalización."
#: src\patterns/behavioural/RAII.md:85
#, fuzzy
msgid ""
"RAII is a useful pattern for ensuring resources are properly deallocated or\n"
"finalised. We can make use of the borrow checker in Rust to statically "
"prevent\n"
"errors stemming from using resources after finalisation takes place."
msgstr ""
"RAII es un patrón útil para garantizar que los recursos se desasignen o\n"
"finalizado. Podemos hacer uso del verificador de préstamos en Rust para "
"evitar estáticamente\n"
"errores derivados del uso de recursos después de la finalización."
#: src\patterns/behavioural/RAII.md:89
#, fuzzy
msgid ""
"The core aim of the borrow checker is to ensure that references to data do "
"not\n"
"outlive that data. The RAII guard pattern works because the guard object\n"
"contains a reference to the underlying resource and only exposes such\n"
"references. Rust ensures that the guard cannot outlive the underlying "
"resource\n"
"and that references to the resource mediated by the guard cannot outlive "
"the\n"
"guard. To see how this works it is helpful to examine the signature of "
"`deref`\n"
"without lifetime elision:"
msgstr ""
"El objetivo principal del verificador de préstamos es garantizar que las "
"referencias a los datos no\n"
"sobrevivir a esos datos. El patrón de protección RAII funciona porque el "
"objeto de protección\n"
"contiene una referencia al recurso subyacente y solo expone tal\n"
"referencias Rust asegura que el guardia no puede sobrevivir al recurso "
"subyacente\n"
"y que las referencias al recurso mediado por la guardia no pueden sobrevivir "
"al\n"
"guardia. Para ver cómo funciona esto, es útil examinar la firma de `deref`\n"
"sin elisión de por vida:"
#: src\patterns/behavioural/RAII.md:97
msgid ""
"```rust,ignore\n"
"fn deref<'a>(&'a self) -> &'a T {\n"
" //..\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/RAII.md:103
#, fuzzy
msgid ""
"The returned reference to the resource has the same lifetime as `self` "
"(`'a`).\n"
"The borrow checker therefore ensures that the lifetime of the reference to "
"`T`\n"
"is shorter than the lifetime of `self`."
msgstr ""
"La referencia devuelta al recurso tiene la misma duración que `self` "
"(`'a`).\n"
"Por lo tanto, el verificador de préstamos garantiza que la vida útil de la "
"referencia a `T`\n"
"es más corto que el tiempo de vida de `sí mismo`."
#: src\patterns/behavioural/RAII.md:107
#, fuzzy
msgid ""
"Note that implementing `Deref` is not a core part of this pattern, it only "
"makes\n"
"using the guard object more ergonomic. Implementing a `get` method on the "
"guard\n"
"works just as well."
msgstr ""
"Tenga en cuenta que la implementación de `Deref` no es una parte central de "
"este patrón, solo hace\n"
"utilizando el objeto de guardia más ergonómico. Implementando un método "
"`get` en el guardia\n"
"funciona igual de bien."
#: src\patterns/behavioural/RAII.md:113
#, fuzzy
msgid "[Finalisation in destructors idiom](../../idioms/dtor-finally.md)"
msgstr "[Finalización en idioma de destructores](../../idioms/dtor-finally.md)"
#: src\patterns/behavioural/RAII.md:115
#, fuzzy
msgid ""
"RAII is a common pattern in C++: "
"[cppreference.com](http://en.cppreference.com/w/cpp/language/raii),\n"
"[wikipedia][wikipedia]."
msgstr ""
"RAII es un patrón común en C++: "
"[cppreference.com](http://en.cppreference.com/w/cpp/language/raii),\n"
"[wikipedia][wikipedia]."
#: src\patterns/behavioural/RAII.md:120
#, fuzzy
msgid ""
"[Style guide "
"entry](https://doc.rust-lang.org/1.0.0/style/ownership/raii.html)\n"
"(currently just a placeholder)."
msgstr ""
"[Entrada de guía de "
"estilo](https://doc.rust-lang.org/1.0.0/style/ownership/raii.html)\n"
"(actualmente solo un marcador de posición)."
#: src\patterns/behavioural/strategy.md:1
#, fuzzy
msgid "# Strategy (aka Policy)"
msgstr "# Estrategia (también conocida como Política)"
#: src\patterns/behavioural/strategy.md:5
#, fuzzy
msgid ""
"The [Strategy design "
"pattern](https://en.wikipedia.org/wiki/Strategy_pattern)\n"
"is a technique that enables separation of concerns.\n"
"It also allows to decouple software modules through [Dependency "
"Inversion](https://en.wikipedia.org/wiki/Dependency_inversion_principle)."
msgstr ""
"El [patrón de diseño de estrategia] "
"(https://en.wikipedia.org/wiki/Strategy_pattern)\n"
"es una técnica que permite la separación de preocupaciones.\n"
"También permite desacoplar módulos de software a través de [Inversión de "
"dependencia] (https://en.wikipedia.org/wiki/Dependency_inversion_principle)."
#: src\patterns/behavioural/strategy.md:9
#, fuzzy
msgid ""
"The basic idea behind the Strategy pattern is that, given an algorithm "
"solving\n"
"a particular problem, we define only the skeleton of the algorithm at an "
"abstract\n"
"level, and we separate the specific algorithms implementation into "
"different parts."
msgstr ""
"La idea básica detrás del patrón de estrategia es que, dado un algoritmo que "
"resuelve\n"
"un problema particular, definimos solo el esqueleto del algoritmo en un "
"resumen\n"
"nivel, y separamos la implementación del algoritmo específico en diferentes "
"partes."
#: src\patterns/behavioural/strategy.md:13
#, fuzzy
msgid ""
"In this way, a client using the algorithm may choose a specific "
"implementation,\n"
"while the general algorithm workflow remains the same. In other words, the "
"abstract\n"
"specification of the class does not depend on the specific implementation of "
"the\n"
"derived class, but specific implementation must adhere to the abstract "
"specification.\n"
"This is why we call it \"Dependency Inversion\"."
msgstr ""
"De esta forma, un cliente que utilice el algoritmo puede elegir una "
"implementación específica,\n"
"mientras que el flujo de trabajo general del algoritmo sigue siendo el "
"mismo. En otras palabras, el resumen\n"
"especificación de la clase no depende de la implementación específica de la\n"
"clase derivada, pero la implementación específica debe adherirse a la "
"especificación abstracta.\n"
"Es por eso que lo llamamos \"Inversión de Dependencia\"."
#: src\patterns/behavioural/strategy.md:21
#, fuzzy
msgid ""
"Imagine we are working on a project that generates reports every month.\n"
"We need the reports to be generated in different formats (strategies), "
"e.g.,\n"
"in `JSON` or `Plain Text` formats.\n"
"But things vary over time, and we don't know what kind of requirement we may "
"get\n"
"in the future. For example, we may need to generate our report in a "
"completely new\n"
"format, or just modify one of the existing formats."
msgstr ""
"Imagina que estamos trabajando en un proyecto que genera informes todos los "
"meses.\n"
"Necesitamos que los informes se generen en diferentes formatos "
"(estrategias), por ejemplo,\n"
"en formatos `JSON` o `Plain Text`.\n"
"Pero las cosas varían con el tiempo, y no sabemos qué tipo de requisito "
"podemos obtener\n"
"en el futuro. Por ejemplo, es posible que necesitemos generar nuestro "
"informe en un formato completamente nuevo.\n"
"formato, o simplemente modificar uno de los formatos existentes."
#: src\patterns/behavioural/strategy.md:30
#, fuzzy
msgid ""
"In this example our invariants (or abstractions) are `Context`, "
"`Formatter`,\n"
"and `Report`, while `Text` and `Json` are our strategy structs. These "
"strategies\n"
"have to implement the `Formatter` trait."
msgstr ""
"En este ejemplo, nuestras invariantes (o abstracciones) son `Context`, "
"`Formatter`,\n"
"y `Report`, mientras que `Text` y `Json` son nuestras estructuras de "
"estrategia. Estas estrategias\n"
"tiene que implementar el rasgo `Formatter`."
#: src\patterns/behavioural/strategy.md:34
msgid ""
"```rust\n"
"use std::collections::HashMap;\n"
"\n"
"type Data = HashMap<String, u32>;\n"
"\n"
"trait Formatter {\n"
" fn format(&self, data: &Data, buf: &mut String);\n"
"}\n"
"\n"
"struct Report;\n"
"\n"
"impl Report {\n"
" // Write should be used but we kept it as String to ignore error "
"handling\n"
" fn generate<T: Formatter>(g: T, s: &mut String) {\n"
" // backend operations...\n"
" let mut data = HashMap::new();\n"
" data.insert(\"one\".to_string(), 1);\n"
" data.insert(\"two\".to_string(), 2);\n"
" // generate report\n"
" g.format(&data, s);\n"
" }\n"
"}\n"
"\n"
"struct Text;\n"
"impl Formatter for Text {\n"
" fn format(&self, data: &Data, buf: &mut String) {\n"
" for (k, v) in data {\n"
" let entry = format!(\"{} {}\\n"
"\", k, v);\n"
" buf.push_str(&entry);\n"
" }\n"
" }\n"
"}\n"
"\n"
"struct Json;\n"
"impl Formatter for Json {\n"
" fn format(&self, data: &Data, buf: &mut String) {\n"
" buf.push('[');\n"
" for (k, v) in data.into_iter() {\n"
" let entry = format!(r#\"{{\"{}\":\"{}\"}}\"#, k, v);\n"
" buf.push_str(&entry);\n"
" buf.push(',');\n"
" }\n"
" if !data.is_empty() {\n"
" buf.pop(); // remove extra , at the end\n"
" }\n"
" buf.push(']');\n"
" }\n"
"}\n"
"\n"
"fn main() {\n"
" let mut s = String::from(\"\");\n"
" Report::generate(Text, &mut s);\n"
" assert!(s.contains(\"one 1\"));\n"
" assert!(s.contains(\"two 2\"));\n"
"\n"
" s.clear(); // reuse the same buffer\n"
" Report::generate(Json, &mut s);\n"
" assert!(s.contains(r#\"{\"one\":\"1\"}\"#));\n"
" assert!(s.contains(r#\"{\"two\":\"2\"}\"#));\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/strategy.md:98
#, fuzzy
msgid ""
"The main advantage is separation of concerns. For example, in this case "
"`Report`\n"
"does not know anything about specific implementations of `Json` and `Text`,\n"
"whereas the output implementations does not care about how data is "
"preprocessed,\n"
"stored, and fetched. The only thing they have to know is context and a "
"specific\n"
"trait and method to implement, i.e,`Formatter` and `run`."
msgstr ""
"La principal ventaja es la separación de preocupaciones. Por ejemplo, en "
"este caso `Informe`\n"
"no sabe nada sobre implementaciones específicas de `Json` y `Text`,\n"
"mientras que las implementaciones de salida no se preocupan por cómo se "
"preprocesan los datos,\n"
"almacenado y obtenido. Lo único que tienen que saber es el contexto y una "
"determinada\n"
"rasgo y método a implementar, es decir, `Formatter` y `run`."
#: src\patterns/behavioural/strategy.md:106
#, fuzzy
msgid ""
"For each strategy there must be implemented at least one module, so number "
"of modules\n"
"increases with number of strategies. If there are many strategies to choose "
"from\n"
"then users have to know how strategies differ from one another."
msgstr ""
"Para cada estrategia debe implementarse al menos un módulo, por lo que el "
"número de módulos\n"
"aumenta con el número de estrategias. Si hay muchas estrategias para elegir\n"
"luego los usuarios tienen que saber en qué se diferencian las estrategias "
"entre sí."
#: src\patterns/behavioural/strategy.md:112
#, fuzzy
msgid ""
"In the previous example all strategies are implemented in a single file.\n"
"Ways of providing different strategies includes:"
msgstr ""
"En el ejemplo anterior todas las estrategias se implementan en un solo "
"archivo.\n"
"Las formas de proporcionar diferentes estrategias incluyen:"
#: src\patterns/behavioural/strategy.md:115
#, fuzzy
msgid ""
"- All in one file (as shown in this example, similar to being separated as "
"modules)\n"
"- Separated as modules, E.g. `formatter::json` module, `formatter::text` "
"module\n"
"- Use compiler feature flags, E.g. `json` feature, `text` feature\n"
"- Separated as crates, E.g. `json` crate, `text` crate"
msgstr ""
"- Todo en un archivo (como se muestra en este ejemplo, similar a estar "
"separados como módulos)\n"
"- Separados como módulos, p. módulo `formateador::json`, módulo "
"`formateador::texto`\n"
"- Use indicadores de características del compilador, p. función `json`, "
"función `texto`\n"
"- Separados como cajas, p. caja `json`, caja `texto`"
#: src\patterns/behavioural/strategy.md:120
#, fuzzy
msgid ""
"Serde crate is a good example of the `Strategy` pattern in action. Serde "
"allows\n"
"[full customization](https://serde.rs/custom-serialization.html) of the "
"serialization\n"
"behavior by manually implementing `Serialize` and `Deserialize` traits for "
"our\n"
"type. For example, we could easily swap `serde_json` with `serde_cbor` since "
"they\n"
"expose similar methods. Having this makes the helper crate `serde_transcode` "
"much\n"
"more useful and ergonomic."
msgstr ""
"Serde crate es un buen ejemplo del patrón 'Estrategia' en acción. Serde "
"permite\n"
"[personalización completa](https://serde.rs/custom-serialization.html) de la "
"serialización\n"
"comportamiento implementando manualmente `Serialize` y `Deserialize` rasgos "
"para nuestro\n"
"tipo. Por ejemplo, podríamos intercambiar fácilmente `serde_json` con "
"`serde_cbor` ya que\n"
"exponer métodos similares. Tener esto hace que el asistente cree "
"`serde_transcode` mucho\n"
"más útil y ergonómico."
#: src\patterns/behavioural/strategy.md:127
#, fuzzy
msgid ""
"However, we don't need to use traits in order to design this pattern in Rust."
msgstr ""
"Sin embargo, no necesitamos usar rasgos para diseñar este patrón en Rust."
#: src\patterns/behavioural/strategy.md:129
#, fuzzy
msgid ""
"The following toy example demonstrates the idea of the Strategy pattern "
"using Rust\n"
"`closures`:"
msgstr ""
"El siguiente ejemplo de juguete demuestra la idea del patrón de estrategia "
"usando Rust\n"
"`cierres`:"
#: src\patterns/behavioural/strategy.md:132
msgid ""
"```rust\n"
"struct Adder;\n"
"impl Adder {\n"
" pub fn add<F>(x: u8, y: u8, f: F) -> u8\n"
" where\n"
" F: Fn(u8, u8) -> u8,\n"
" {\n"
" f(x, y)\n"
" }\n"
"}\n"
"\n"
"fn main() {\n"
" let arith_adder = |x, y| x + y;\n"
" let bool_adder = |x, y| {\n"
" if x == 1 || y == 1 {\n"
" 1\n"
" } else {\n"
" 0\n"
" }\n"
" };\n"
" let custom_adder = |x, y| 2 * x + y;\n"
"\n"
" assert_eq!(9, Adder::add(4, 5, arith_adder));\n"
" assert_eq!(0, Adder::add(0, 0, bool_adder));\n"
" assert_eq!(5, Adder::add(1, 3, custom_adder));\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/strategy.md:160
#, fuzzy
msgid "In fact, Rust already uses this idea for `Options`'s `map` method:"
msgstr "De hecho, Rust ya usa esta idea para el método `map` de `Options`:"
#: src\patterns/behavioural/strategy.md:162
msgid ""
"```rust\n"
"fn main() {\n"
" let val = Some(\"Rust\");\n"
"\n"
" let len_strategy = |s: &str| s.len();\n"
" assert_eq!(4, val.map(len_strategy).unwrap());\n"
"\n"
" let first_byte_strategy = |s: &str| s.bytes().next().unwrap();\n"
" assert_eq!(82, val.map(first_byte_strategy).unwrap());\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/strategy.md:176
#, fuzzy
msgid ""
"- [Strategy Pattern](https://en.wikipedia.org/wiki/Strategy_pattern)\n"
"- [Dependency "
"Injection](https://en.wikipedia.org/wiki/Dependency_injection)\n"
"- [Policy Based "
"Design](https://en.wikipedia.org/wiki/Modern_C++_Design#Policy-based_design)"
msgstr ""
"- [Patrón de estrategia](https://en.wikipedia.org/wiki/Strategy_pattern)\n"
"- [Inyección de "
"dependencia](https://en.wikipedia.org/wiki/Dependency_injection)\n"
"- [Diseño basado en políticas] "
"(https://en.wikipedia.org/wiki/Modern_C++_Design#Policy-based_design)"
#: src\patterns/behavioural/visitor.md:1
#, fuzzy
msgid "# Visitor"
msgstr "# Visitante"
#: src\patterns/behavioural/visitor.md:5
#, fuzzy
msgid ""
"A visitor encapsulates an algorithm that operates over a heterogeneous\n"
"collection of objects. It allows multiple different algorithms to be "
"written\n"
"over the same data without having to modify the data (or their primary\n"
"behaviour)."
msgstr ""
"Un visitante encapsula un algoritmo que opera sobre un heterogéneo\n"
"colección de objetos. Permite escribir múltiples algoritmos diferentes.\n"
"sobre los mismos datos sin tener que modificar los datos (o su principal\n"
"comportamiento)."
#: src\patterns/behavioural/visitor.md:10
#, fuzzy
msgid ""
"Furthermore, the visitor pattern allows separating the traversal of\n"
"a collection of objects from the operations performed on each object."
msgstr ""
"Además, el patrón de visitante permite separar el recorrido de\n"
"una colección de objetos de las operaciones realizadas en cada objeto."
#: src\patterns/behavioural/visitor.md:15
msgid ""
"```rust,ignore\n"
"// The data we will visit\n"
"mod ast {\n"
" pub enum Stmt {\n"
" Expr(Expr),\n"
" Let(Name, Expr),\n"
" }\n"
"\n"
" pub struct Name {\n"
" value: String,\n"
" }\n"
"\n"
" pub enum Expr {\n"
" IntLit(i64),\n"
" Add(Box<Expr>, Box<Expr>),\n"
" Sub(Box<Expr>, Box<Expr>),\n"
" }\n"
"}\n"
"\n"
"// The abstract visitor\n"
"mod visit {\n"
" use ast::*;\n"
"\n"
" pub trait Visitor<T> {\n"
" fn visit_name(&mut self, n: &Name) -> T;\n"
" fn visit_stmt(&mut self, s: &Stmt) -> T;\n"
" fn visit_expr(&mut self, e: &Expr) -> T;\n"
" }\n"
"}\n"
"\n"
"use visit::*;\n"
"use ast::*;\n"
"\n"
"// An example concrete implementation - walks the AST interpreting it as "
"code.\n"
"struct Interpreter;\n"
"impl Visitor<i64> for Interpreter {\n"
" fn visit_name(&mut self, n: &Name) -> i64 { panic!() }\n"
" fn visit_stmt(&mut self, s: &Stmt) -> i64 {\n"
" match *s {\n"
" Stmt::Expr(ref e) => self.visit_expr(e),\n"
" Stmt::Let(..) => unimplemented!(),\n"
" }\n"
" }\n"
"\n"
" fn visit_expr(&mut self, e: &Expr) -> i64 {\n"
" match *e {\n"
" Expr::IntLit(n) => n,\n"
" Expr::Add(ref lhs, ref rhs) => self.visit_expr(lhs) + "
"self.visit_expr(rhs),\n"
" Expr::Sub(ref lhs, ref rhs) => self.visit_expr(lhs) - "
"self.visit_expr(rhs),\n"
" }\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/visitor.md:69
#, fuzzy
msgid ""
"One could implement further visitors, for example a type checker, without "
"having\n"
"to modify the AST data."
msgstr ""
"Se podrían implementar más visitantes, por ejemplo, un verificador de tipos, "
"sin tener\n"
"para modificar los datos AST."
#: src\patterns/behavioural/visitor.md:74
#, fuzzy
msgid ""
"The visitor pattern is useful anywhere that you want to apply an algorithm "
"to\n"
"heterogeneous data. If data is homogeneous, you can use an iterator-like "
"pattern.\n"
"Using a visitor object (rather than a functional approach) allows the "
"visitor to\n"
"be stateful and thus communicate information between nodes."
msgstr ""
"El patrón de visitante es útil en cualquier lugar al que desee aplicar un "
"algoritmo\n"
"datos heterogéneos. Si los datos son homogéneos, puede usar un patrón "
"similar a un iterador.\n"
"El uso de un objeto de visitante (en lugar de un enfoque funcional) le "
"permite al visitante\n"
"tener estado y así comunicar información entre nodos."
#: src\patterns/behavioural/visitor.md:81
#, fuzzy
msgid ""
"It is common for the `visit_*` methods to return void (as opposed to in the\n"
"example). In that case it is possible to factor out the traversal code and "
"share\n"
"it between algorithms (and also to provide noop default methods). In Rust, "
"the\n"
"common way to do this is to provide `walk_*` functions for each datum. For\n"
"example,"
msgstr ""
"Es común que los métodos `visit_*` devuelvan void (a diferencia del método\n"
"ejemplo). En ese caso, es posible factorizar el código transversal y "
"compartir\n"
"entre algoritmos (y también para proporcionar métodos predeterminados de "
"noop). En óxido, el\n"
"La forma común de hacer esto es proporcionar funciones `walk_*` para cada "
"dato. Para\n"
"ejemplo,"
#: src\patterns/behavioural/visitor.md:87
msgid ""
"```rust,ignore\n"
"pub fn walk_expr(visitor: &mut Visitor, e: &Expr) {\n"
" match *e {\n"
" Expr::IntLit(_) => {},\n"
" Expr::Add(ref lhs, ref rhs) => {\n"
" visitor.visit_expr(lhs);\n"
" visitor.visit_expr(rhs);\n"
" }\n"
" Expr::Sub(ref lhs, ref rhs) => {\n"
" visitor.visit_expr(lhs);\n"
" visitor.visit_expr(rhs);\n"
" }\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\patterns/behavioural/visitor.md:103
#, fuzzy
msgid ""
"In other languages (e.g., Java) it is common for data to have an `accept` "
"method\n"
"which performs the same duty."
msgstr ""
"En otros lenguajes (por ejemplo, Java) es común que los datos tengan un "
"método `aceptar`\n"
"que cumple el mismo deber."
#: src\patterns/behavioural/visitor.md:108
#, fuzzy
msgid "The visitor pattern is a common pattern in most OO languages."
msgstr ""
"El patrón de visitante es un patrón común en la mayoría de los lenguajes OO."
#: src\patterns/behavioural/visitor.md:110
#, fuzzy
msgid "[Wikipedia article](https://en.wikipedia.org/wiki/Visitor_pattern)"
msgstr "[Artículo de Wikipedia](https://en.wikipedia.org/wiki/Visitor_pattern)"
#: src\patterns/behavioural/visitor.md:112
#, fuzzy
msgid ""
"The [fold](../creational/fold.md) pattern is similar to visitor but "
"produces\n"
"a new version of the visited data structure."
msgstr ""
"El patrón [fold](../creational/fold.md) es similar al visitante pero "
"produce\n"
"una nueva versión de la estructura de datos visitada."
#: src\patterns/creational/intro.md:1
#, fuzzy
msgid "# Creational Patterns"
msgstr "# Patrones de creación"
#: src\patterns/creational/intro.md:3
#, fuzzy
msgid "From [Wikipedia](https://en.wikipedia.org/wiki/Creational_pattern):"
msgstr "De [Wikipedia](https://en.wikipedia.org/wiki/Creational_pattern):"
#: src\patterns/creational/intro.md:5
#, fuzzy
msgid ""
"> Design patterns that deal with object creation mechanisms, trying to "
"create objects\n"
"> in a manner suitable to the situation. The basic form of object creation "
"could\n"
"> result in design problems or in added complexity to the design. Creational "
"design\n"
"> patterns solve this problem by somehow controlling this object creation."
msgstr ""
"> Patrones de diseño que se ocupan de los mecanismos de creación de objetos, "
"tratando de crear objetos\n"
"> de una manera adecuada a la situación. La forma básica de creación de "
"objetos podría\n"
"> resultar en problemas de diseño o en complejidad adicional al diseño. "
"diseño creacional\n"
"> los patrones resuelven este problema controlando de alguna manera la "
"creación de este objeto."
#: src\patterns/creational/builder.md:1
#, fuzzy
msgid "# Builder"
msgstr "# Constructor"
#: src\patterns/creational/builder.md:5
#, fuzzy
msgid "Construct an object with calls to a builder helper."
msgstr "Construya un objeto con llamadas a un asistente de construcción."
#: src\patterns/creational/builder.md:9
msgid ""
"```rust\n"
"#[derive(Debug, PartialEq)]\n"
"pub struct Foo {\n"
" // Lots of complicated fields.\n"
" bar: String,\n"
"}\n"
"\n"
"impl Foo {\n"
" // This method will help users to discover the builder\n"
" pub fn builder() -> FooBuilder {\n"
" FooBuilder::default()\n"
" }\n"
"}\n"
"\n"
"#[derive(Default)]\n"
"pub struct FooBuilder {\n"
" // Probably lots of optional fields.\n"
" bar: String,\n"
"}\n"
"\n"
"impl FooBuilder {\n"
" pub fn new(/* ... */) -> FooBuilder {\n"
" // Set the minimally required fields of Foo.\n"
" FooBuilder {\n"
" bar: String::from(\"X\"),\n"
" }\n"
" }\n"
"\n"
" pub fn name(mut self, bar: String) -> FooBuilder {\n"
" // Set the name on the builder itself, and return the builder by "
"value.\n"
" self.bar = bar;\n"
" self\n"
" }\n"
"\n"
" // If we can get away with not consuming the Builder here, that is an\n"
" // advantage. It means we can use the FooBuilder as a template for "
"constructing\n"
" // many Foos.\n"
" pub fn build(self) -> Foo {\n"
" // Create a Foo from the FooBuilder, applying all settings in "
"FooBuilder\n"
" // to Foo.\n"
" Foo { bar: self.bar }\n"
" }\n"
"}\n"
"\n"
"#[test]\n"
"fn builder_test() {\n"
" let foo = Foo {\n"
" bar: String::from(\"Y\"),\n"
" };\n"
" let foo_from_builder: Foo = "
"FooBuilder::new().name(String::from(\"Y\")).build();\n"
" assert_eq!(foo, foo_from_builder);\n"
"}\n"
"```"
msgstr ""
#: src\patterns/creational/builder.md:65
#, fuzzy
msgid ""
"Useful when you would otherwise require many constructors or where\n"
"construction has side effects."
msgstr ""
"Útil cuando de otro modo necesitaría muchos constructores o donde\n"
"la construcción tiene efectos secundarios."
#: src\patterns/creational/builder.md:70
#, fuzzy
msgid "Separates methods for building from other methods."
msgstr "Separa los métodos de construcción de otros métodos."
#: src\patterns/creational/builder.md:72
#, fuzzy
msgid "Prevents proliferation of constructors."
msgstr "Evita la proliferación de constructores."
#: src\patterns/creational/builder.md:74
#, fuzzy
msgid ""
"Can be used for one-liner initialisation as well as more complex "
"construction."
msgstr ""
"Se puede utilizar para la inicialización de una sola línea, así como para "
"construcciones más complejas."
#: src\patterns/creational/builder.md:78
#, fuzzy
msgid ""
"More complex than creating a struct object directly, or a simple "
"constructor\n"
"function."
msgstr ""
"Más complejo que crear un objeto de estructura directamente o un constructor "
"simple\n"
"función."
#: src\patterns/creational/builder.md:83
#, fuzzy
msgid ""
"This pattern is seen more frequently in Rust (and for simpler objects) than "
"in\n"
"many other languages because Rust lacks overloading. Since you can only have "
"a\n"
"single method with a given name, having multiple constructors is less nice "
"in\n"
"Rust than in C++, Java, or others."
msgstr ""
"Este patrón se ve con más frecuencia en Rust (y para objetos más simples) "
"que en\n"
"muchos otros lenguajes porque Rust carece de sobrecarga. Ya que solo puedes "
"tener un\n"
"método único con un nombre dado, tener múltiples constructores es menos "
"agradable en\n"
"Rust que en C++, Java u otros."
#: src\patterns/creational/builder.md:88
#, fuzzy
msgid ""
"This pattern is often used where the builder object is useful in its own "
"right,\n"
"rather than being just a builder. For example, see\n"
"[`std::process::Command`](https://doc.rust-lang.org/std/process/struct.Command.html)\n"
"is a builder for "
"[`Child`](https://doc.rust-lang.org/std/process/struct.Child.html)\n"
"(a process). In these cases, the `T` and `TBuilder` naming pattern is not "
"used."
msgstr ""
"Este patrón se usa a menudo cuando el objeto constructor es útil por derecho "
"propio,\n"
"en lugar de ser sólo un constructor. Por ejemplo, ver\n"
"[`std::process::Command`](https://doc.rust-lang.org/std/process/struct.Command.html)\n"
"es un constructor para "
"[`Child`](https://doc.rust-lang.org/std/process/struct.Child.html)\n"
"(un proceso). En estos casos, no se utiliza el patrón de nomenclatura `T` y "
"`TBuilder`."
#: src\patterns/creational/builder.md:94
#, fuzzy
msgid ""
"The example takes and returns the builder by value. It is often more "
"ergonomic\n"
"(and more efficient) to take and return the builder as a mutable reference. "
"The\n"
"borrow checker makes this work naturally. This approach has the advantage "
"that\n"
"one can write code like"
msgstr ""
"El ejemplo toma y devuelve el constructor por valor. A menudo es más "
"ergonómico.\n"
"(y más eficiente) para tomar y devolver el constructor como una referencia "
"mutable. El\n"
"El verificador de préstamos hace que esto funcione de forma natural. Este "
"enfoque tiene la ventaja de que\n"
"uno puede escribir código como"
#: src\patterns/creational/builder.md:99
msgid ""
"```rust,ignore\n"
"let mut fb = FooBuilder::new();\n"
"fb.a();\n"
"fb.b();\n"
"let f = fb.build();\n"
"```"
msgstr ""
#: src\patterns/creational/builder.md:106
#, fuzzy
msgid "as well as the `FooBuilder::new().a().b().build()` style."
msgstr "así como el estilo `FooBuilder::new().a().b().build()`."
#: src\patterns/creational/builder.md:110
#, fuzzy
msgid ""
"- [Description in the style "
"guide](https://web.archive.org/web/20210104103100/https://doc.rust-lang.org/1.12.0/style/ownership/builders.html)\n"
"- [derive_builder](https://crates.io/crates/derive_builder), a crate for "
"automatically\n"
" implementing this pattern while avoiding the boilerplate.\n"
"- [Constructor pattern](../../idioms/ctor.md) for when construction is "
"simpler.\n"
"- [Builder pattern "
"(wikipedia)](https://en.wikipedia.org/wiki/Builder_pattern)\n"
"- [Construction of complex "
"values](https://web.archive.org/web/20210104103000/https://rust-lang.github.io/api-guidelines/type-safety.html#c-builder)"
msgstr ""
"- [Descripción en la guía de "
"estilo](https://web.archive.org/web/20210104103100/https://doc.rust-lang.org/1.12.0/style/ownership/builders.html)\n"
"- [derive_builder](https://crates.io/crates/derive_builder), una caja para "
"automáticamente\n"
" implementar este patrón mientras se evita el repetitivo.\n"
"- [Patrón de constructor](../../idioms/ctor.md) para cuando la construcción "
"es más sencilla.\n"
"- [Patrón de constructor "
"(wikipedia)](https://en.wikipedia.org/wiki/Builder_pattern)\n"
"- [Construcción de valores "
"complejos](https://web.archive.org/web/20210104103000/https://rust-lang.github.io/api-guidelines/type-safety.html#c-builder)"
#: src\patterns/creational/fold.md:1
#, fuzzy
msgid "# Fold"
msgstr "# Doblar"
#: src\patterns/creational/fold.md:5
#, fuzzy
msgid ""
"Run an algorithm over each item in a collection of data to create a new "
"item,\n"
"thus creating a whole new collection."
msgstr ""
"Ejecute un algoritmo sobre cada elemento en una colección de datos para "
"crear un nuevo elemento,\n"
"creando así una colección completamente nueva."
#: src\patterns/creational/fold.md:8
#, fuzzy
msgid ""
"The etymology here is unclear to me. The terms 'fold' and 'folder' are used\n"
"in the Rust compiler, although it appears to me to be more like a map than "
"a\n"
"fold in the usual sense. See the discussion below for more details."
msgstr ""
"La etimología aquí no está clara para mí. Los términos 'doblar' y 'carpeta' "
"se utilizan\n"
"en el compilador de Rust, aunque me parece más un mapa que un\n"
"doblar en el sentido habitual. Consulte la discusión a continuación para "
"obtener más detalles."
#: src\patterns/creational/fold.md:14
msgid ""
"```rust,ignore\n"
"// The data we will fold, a simple AST.\n"
"mod ast {\n"
" pub enum Stmt {\n"
" Expr(Box<Expr>),\n"
" Let(Box<Name>, Box<Expr>),\n"
" }\n"
"\n"
" pub struct Name {\n"
" value: String,\n"
" }\n"
"\n"
" pub enum Expr {\n"
" IntLit(i64),\n"
" Add(Box<Expr>, Box<Expr>),\n"
" Sub(Box<Expr>, Box<Expr>),\n"
" }\n"
"}\n"
"\n"
"// The abstract folder\n"
"mod fold {\n"
" use ast::*;\n"
"\n"
" pub trait Folder {\n"
" // A leaf node just returns the node itself. In some cases, we can "
"do this\n"
" // to inner nodes too.\n"
" fn fold_name(&mut self, n: Box<Name>) -> Box<Name> { n }\n"
" // Create a new inner node by folding its children.\n"
" fn fold_stmt(&mut self, s: Box<Stmt>) -> Box<Stmt> {\n"
" match *s {\n"
" Stmt::Expr(e) => Box::new(Stmt::Expr(self.fold_expr(e))),\n"
" Stmt::Let(n, e) => Box::new(Stmt::Let(self.fold_name(n), "
"self.fold_expr(e))),\n"
" }\n"
" }\n"
" fn fold_expr(&mut self, e: Box<Expr>) -> Box<Expr> { ... }\n"
" }\n"
"}\n"
"\n"
"use fold::*;\n"
"use ast::*;\n"
"\n"
"// An example concrete implementation - renames every name to 'foo'.\n"
"struct Renamer;\n"
"impl Folder for Renamer {\n"
" fn fold_name(&mut self, n: Box<Name>) -> Box<Name> {\n"
" Box::new(Name { value: \"foo\".to_owned() })\n"
" }\n"
" // Use the default methods for the other nodes.\n"
"}\n"
"```"
msgstr ""
#: src\patterns/creational/fold.md:65
#, fuzzy
msgid ""
"The result of running the `Renamer` on an AST is a new AST identical to the "
"old\n"
"one, but with every name changed to `foo`. A real life folder might have "
"some\n"
"state preserved between nodes in the struct itself."
msgstr ""
"El resultado de ejecutar `Renamer` en un AST es un nuevo AST idéntico al "
"antiguo\n"
"one, pero con todos los nombres cambiados a `foo`. Una carpeta de la vida "
"real podría tener algunos\n"
"estado preservado entre nodos en la estructura misma."
#: src\patterns/creational/fold.md:69
#, fuzzy
msgid ""
"A folder can also be defined to map one data structure to a different (but\n"
"usually similar) data structure. For example, we could fold an AST into a "
"HIR\n"
"tree (HIR stands for high-level intermediate representation)."
msgstr ""
"También se puede definir una carpeta para asignar una estructura de datos a "
"otra diferente (pero\n"
"generalmente similar) estructura de datos. Por ejemplo, podríamos convertir "
"un AST en un HIR\n"
"árbol (HIR significa representación intermedia de alto nivel)."
#: src\patterns/creational/fold.md:75
#, fuzzy
msgid ""
"It is common to want to map a data structure by performing some operation "
"on\n"
"each node in the structure. For simple operations on simple data "
"structures,\n"
"this can be done using `Iterator::map`. For more complex operations, "
"perhaps\n"
"where earlier nodes can affect the operation on later nodes, or where "
"iteration\n"
"over the data structure is non-trivial, using the fold pattern is more\n"
"appropriate."
msgstr ""
"Es común querer mapear una estructura de datos realizando alguna operación "
"en\n"
"cada nodo de la estructura. Para operaciones simples en estructuras de datos "
"simples,\n"
"esto se puede hacer usando `Iterator::map`. Para operaciones más complejas, "
"tal vez\n"
"donde los nodos anteriores pueden afectar la operación en nodos posteriores, "
"o donde la iteración\n"
"sobre la estructura de datos no es trivial, usar el patrón de plegado es "
"más\n"
"adecuado."
#: src\patterns/creational/fold.md:82
#, fuzzy
msgid ""
"Like the visitor pattern, the fold pattern allows us to separate traversal "
"of a\n"
"data structure from the operations performed to each node."
msgstr ""
"Al igual que el patrón de visitante, el patrón de plegado nos permite "
"separar el recorrido de un\n"
"estructura de datos de las operaciones realizadas a cada nodo."
#: src\patterns/creational/fold.md:87
#, fuzzy
msgid ""
"Mapping data structures in this fashion is common in functional languages. "
"In OO\n"
"languages, it would be more common to mutate the data structure in place. "
"The\n"
"'functional' approach is common in Rust, mostly due to the preference for\n"
"immutability. Using fresh data structures, rather than mutating old ones, "
"makes\n"
"reasoning about the code easier in most circumstances."
msgstr ""
"Mapear estructuras de datos de esta manera es común en lenguajes "
"funcionales. en OO\n"
"idiomas, sería más común mutar la estructura de datos en su lugar. El\n"
"El enfoque 'funcional' es común en Rust, principalmente debido a la "
"preferencia por\n"
"inmutabilidad. El uso de estructuras de datos nuevas, en lugar de mutar las "
"antiguas, hace\n"
"razonar sobre el código es más fácil en la mayoría de las circunstancias."
#: src\patterns/creational/fold.md:93
#, fuzzy
msgid ""
"The trade-off between efficiency and reusability can be tweaked by changing "
"how\n"
"nodes are accepted by the `fold_*` methods."
msgstr ""
"La compensación entre la eficiencia y la reutilización se puede ajustar "
"cambiando cómo\n"
"los nodos son aceptados por los métodos `fold_*`."
#: src\patterns/creational/fold.md:96
#, fuzzy
msgid ""
"In the above example we operate on `Box` pointers. Since these own their "
"data\n"
"exclusively, the original copy of the data structure cannot be re-used. On "
"the\n"
"other hand if a node is not changed, reusing it is very efficient."
msgstr ""
"En el ejemplo anterior, operamos con punteros `Box`. Ya que estos son dueños "
"de sus datos\n"
"exclusivamente, la copia original de la estructura de datos no puede ser "
"reutilizada. Sobre el\n"
"Por otro lado, si un nodo no se cambia, reutilizarlo es muy eficiente."
#: src\patterns/creational/fold.md:100
msgid ""
"If we were to operate on borrowed references, the original data structure "
"can be\n"
"reused; however, a node must be cloned even if unchanged, which can be\n"
"expensive."
msgstr ""
#: src\patterns/creational/fold.md:104
#, fuzzy
msgid ""
"Using a reference counted pointer gives the best of both worlds - we can "
"reuse\n"
"the original data structure, and we don't need to clone unchanged nodes. "
"However,\n"
"they are less ergonomic to use and mean that the data structures cannot be\n"
"mutable."
msgstr ""
"El uso de un puntero contado de referencia ofrece lo mejor de ambos mundos: "
"podemos reutilizar\n"
"la estructura de datos original, y no necesitamos clonar nodos sin cambios. "
"Sin embargo,\n"
"son menos ergonómicos de usar y significan que las estructuras de datos no "
"pueden ser\n"
"mudable."
#: src\patterns/creational/fold.md:111
#, fuzzy
msgid ""
"Iterators have a `fold` method, however this folds a data structure into a\n"
"value, rather than into a new data structure. An iterator's `map` is more "
"like\n"
"this fold pattern."
msgstr ""
"Los iteradores tienen un método `doblar`, sin embargo, este dobla una "
"estructura de datos en una\n"
"valor, en lugar de en una nueva estructura de datos. El `mapa` de un "
"iterador es más como\n"
"este patrón de plegado."
#: src\patterns/creational/fold.md:115
#, fuzzy
msgid ""
"In other languages, fold is usually used in the sense of Rust's iterators,\n"
"rather than this pattern. Some functional languages have powerful constructs "
"for\n"
"performing flexible maps over data structures."
msgstr ""
"En otros lenguajes, fold se usa generalmente en el sentido de los iteradores "
"de Rust,\n"
"en lugar de este patrón. Algunos lenguajes funcionales tienen poderosas "
"construcciones para\n"
"realizar mapas flexibles sobre estructuras de datos."
#: src\patterns/creational/fold.md:119
#, fuzzy
msgid ""
"The [visitor](../behavioural/visitor.md) pattern is closely related to "
"fold.\n"
"They share the concept of walking a data structure performing an operation "
"on\n"
"each node. However, the visitor does not create a new data structure nor "
"consume\n"
"the old one."
msgstr ""
"El patrón [visitante](../behavioural/visitor.md) está estrechamente "
"relacionado con el pliegue.\n"
"Comparten el concepto de recorrer una estructura de datos realizando una "
"operación sobre\n"
"cada nodo. Sin embargo, el visitante no crea una nueva estructura de datos "
"ni consume\n"
"el viejo."
#: src\patterns/structural/intro.md:1
#, fuzzy
msgid "# Structural Patterns"
msgstr "# Patrones Estructurales"
#: src\patterns/structural/intro.md:3
#, fuzzy
msgid "From [Wikipedia](https://en.wikipedia.org/wiki/Structural_pattern):"
msgstr "De [Wikipedia](https://en.wikipedia.org/wiki/Structural_pattern):"
#: src\patterns/structural/intro.md:5
#, fuzzy
msgid ""
"> Design patterns that ease the design by identifying a simple way to "
"realize relationships\n"
"> among entities."
msgstr ""
"> Patrones de diseño que facilitan el diseño al identificar una forma "
"sencilla de realizar relaciones\n"
"> entre entidades."
#: src\patterns/structural/compose-structs.md:1
#, fuzzy
msgid "# Compose structs together for better borrowing"
msgstr "# Componer estructuras juntas para un mejor préstamo"
#: src\patterns/structural/compose-structs.md:3
#, fuzzy
msgid "TODO - this is not a very snappy name"
msgstr "TODO - este no es un nombre muy ágil"
#: src\patterns/structural/compose-structs.md:7
#, fuzzy
msgid ""
"Sometimes a large struct will cause issues with the borrow checker - "
"although\n"
"fields can be borrowed independently, sometimes the whole struct ends up "
"being\n"
"used at once, preventing other uses. A solution might be to decompose the "
"struct\n"
"into several smaller structs. Then compose these together into the original\n"
"struct. Then each struct can be borrowed separately and have more flexible\n"
"behaviour."
msgstr ""
"A veces, una estructura grande causará problemas con el verificador de "
"préstamos, aunque\n"
"los campos se pueden tomar prestados de forma independiente, a veces toda la "
"estructura termina siendo\n"
"utilizados de una sola vez, impidiendo otros usos. Una solución podría ser "
"descomponer la estructura\n"
"en varias estructuras más pequeñas. Luego componga estos juntos en el "
"original\n"
"estructura Luego, cada estructura se puede tomar prestada por separado y "
"tener más flexibilidad\n"
"comportamiento."
#: src\patterns/structural/compose-structs.md:14
#, fuzzy
msgid ""
"This will often lead to a better design in other ways: applying this design\n"
"pattern often reveals smaller units of functionality."
msgstr ""
"Esto a menudo conducirá a un mejor diseño de otras maneras: aplicar este "
"diseño\n"
"patrón a menudo revela unidades más pequeñas de funcionalidad."
#: src\patterns/structural/compose-structs.md:19
#, fuzzy
msgid ""
"Here is a contrived example of where the borrow checker foils us in our plan "
"to\n"
"use a struct:"
msgstr ""
"Aquí hay un ejemplo artificial de dónde el verificador de préstamos nos "
"frustra en nuestro plan para\n"
"usar una estructura:"
#: src\patterns/structural/compose-structs.md:22
msgid ""
"```rust\n"
"struct A {\n"
" f1: u32,\n"
" f2: u32,\n"
" f3: u32,\n"
"}\n"
"\n"
"fn foo(a: &mut A) -> &u32 { &a.f2 }\n"
"fn bar(a: &mut A) -> u32 { a.f1 + a.f3 }\n"
"\n"
"fn baz(a: &mut A) {\n"
" // The later usage of x causes a to be borrowed for the rest of the "
"function.\n"
" let x = foo(a);\n"
" // Borrow checker error:\n"
" // let y = bar(a); // ~ ERROR: cannot borrow `*a` as mutable more than "
"once\n"
" // at a time\n"
" println!(\"{}\", x);\n"
"}\n"
"```"
msgstr ""
#: src\patterns/structural/compose-structs.md:42
#, fuzzy
msgid ""
"We can apply this design pattern and refactor `A` into two smaller structs, "
"thus\n"
"solving the borrow checking issue:"
msgstr ""
"Podemos aplicar este patrón de diseño y refactorizar `A` en dos estructuras "
"más pequeñas, por lo tanto\n"
"resolviendo el problema de verificación de préstamo:"
#: src\patterns/structural/compose-structs.md:45
msgid ""
"```rust\n"
"// A is now composed of two structs - B and C.\n"
"struct A {\n"
" b: B,\n"
" c: C,\n"
"}\n"
"struct B {\n"
" f2: u32,\n"
"}\n"
"struct C {\n"
" f1: u32,\n"
" f3: u32,\n"
"}\n"
"\n"
"// These functions take a B or C, rather than A.\n"
"fn foo(b: &mut B) -> &u32 { &b.f2 }\n"
"fn bar(c: &mut C) -> u32 { c.f1 + c.f3 }\n"
"\n"
"fn baz(a: &mut A) {\n"
" let x = foo(&mut a.b);\n"
" // Now it's OK!\n"
" let y = bar(&mut a.c);\n"
" println!(\"{}\", x);\n"
"}\n"
"```"
msgstr ""
#: src\patterns/structural/compose-structs.md:73
#, fuzzy
msgid "TODO Why and where you should use the pattern"
msgstr "TODO Por qué y dónde deberías usar el patrón"
#: src\patterns/structural/compose-structs.md:77
#, fuzzy
msgid "Lets you work around limitations in the borrow checker."
msgstr "Le permite sortear las limitaciones del verificador de préstamos."
#: src\patterns/structural/compose-structs.md:79
#, fuzzy
msgid "Often produces a better design."
msgstr "A menudo produce un mejor diseño."
#: src\patterns/structural/compose-structs.md:83
#, fuzzy
msgid "Leads to more verbose code."
msgstr "Conduce a un código más detallado."
#: src\patterns/structural/compose-structs.md:85
#, fuzzy
msgid ""
"Sometimes, the smaller structs are not good abstractions, and so we end up "
"with\n"
"a worse design. That is probably a 'code smell', indicating that the "
"program\n"
"should be refactored in some way."
msgstr ""
"A veces, las estructuras más pequeñas no son buenas abstracciones, por lo "
"que terminamos con\n"
"un diseño peor. Eso es probablemente un 'olor a código', lo que indica que "
"el programa\n"
"debe ser refactorizado de alguna manera."
#: src\patterns/structural/compose-structs.md:91
#, fuzzy
msgid ""
"This pattern is not required in languages that don't have a borrow checker, "
"so\n"
"in that sense is unique to Rust. However, making smaller units of "
"functionality\n"
"often leads to cleaner code: a widely acknowledged principle of software\n"
"engineering, independent of the language."
msgstr ""
"Este patrón no es necesario en los idiomas que no tienen un verificador de "
"préstamos, por lo que\n"
"en ese sentido es exclusivo de Rust. Sin embargo, hacer unidades más "
"pequeñas de funcionalidad\n"
"a menudo conduce a un código más limpio: un principio de software "
"ampliamente reconocido\n"
"ingeniería, independiente del idioma."
#: src\patterns/structural/compose-structs.md:96
#, fuzzy
msgid ""
"This pattern relies on Rust's borrow checker to be able to borrow fields\n"
"independently of each other. In the example, the borrow checker knows that "
"`a.b`\n"
"and `a.c` are distinct and can be borrowed independently, it does not try "
"to\n"
"borrow all of `a`, which would make this pattern useless."
msgstr ""
"Este patrón se basa en el verificador de préstamos de Rust para poder tomar "
"prestados campos.\n"
"independientemente unos de otros. En el ejemplo, el verificador de préstamos "
"sabe que `a.b`\n"
"y `a.c` son distintos y se pueden tomar prestados de forma independiente, no "
"intenta\n"
"toma prestada toda `a`, lo que haría que este patrón fuera inútil."
#: src\patterns/structural/small-crates.md:1
#, fuzzy
msgid "# Prefer small crates"
msgstr "# Preferir cajas pequeñas"
#: src\patterns/structural/small-crates.md:5
#, fuzzy
msgid "Prefer small crates that do one thing well."
msgstr "Prefiere cajas pequeñas que hacen una sola cosa bien."
#: src\patterns/structural/small-crates.md:7
#, fuzzy
msgid ""
"Cargo and crates.io make it easy to add third-party libraries, much more so "
"than\n"
"in say C or C++. Moreover, since packages on crates.io cannot be edited or "
"removed\n"
"after publication, any build that works now should continue to work in the "
"future.\n"
"We should take advantage of this tooling, and use smaller, more fine-grained "
"dependencies."
msgstr ""
"Cargo y crates.io facilitan la adición de bibliotecas de terceros, mucho más "
"que\n"
"en decir C o C++. Además, dado que los paquetes en crates.io no se pueden "
"editar ni eliminar\n"
"después de la publicación, cualquier compilación que funcione ahora debería "
"continuar funcionando en el futuro.\n"
"Deberíamos aprovechar esta herramienta y usar dependencias más pequeñas y "
"detalladas."
#: src\patterns/structural/small-crates.md:14
#, fuzzy
msgid ""
"- Small crates are easier to understand, and encourage more modular code.\n"
"- Crates allow for re-using code between projects.\n"
" For example, the `url` crate was developed as part of the Servo browser "
"engine,\n"
" but has since found wide use outside the project.\n"
"- Since the compilation unit\n"
" of Rust is the crate, splitting a project into multiple crates can allow "
"more of\n"
" the code to be built in parallel."
msgstr ""
"- Las cajas pequeñas son más fáciles de entender y fomentan un código más "
"modular.\n"
"- Las cajas permiten reutilizar código entre proyectos.\n"
" Por ejemplo, la caja `url` se desarrolló como parte del motor del "
"navegador Servo,\n"
" pero desde entonces ha encontrado un amplio uso fuera del proyecto.\n"
"- Desde la unidad de compilación\n"
" de Rust es la caja, dividir un proyecto en varias cajas puede permitir más "
"de\n"
" el código que se construirá en paralelo."
#: src\patterns/structural/small-crates.md:24
#, fuzzy
msgid ""
"- This can lead to \"dependency hell\", when a project depends on multiple "
"conflicting\n"
" versions of a crate at the same time. For example, the `url` crate has "
"both versions\n"
" 1.0 and 0.5. Since the `Url` from `url:1.0` and the `Url` from `url:0.5` "
"are\n"
" different types, an HTTP client that uses `url:0.5` would not accept `Url` "
"values\n"
" from a web scraper that uses `url:1.0`.\n"
"- Packages on crates.io are not curated. A crate may be poorly written, "
"have\n"
" unhelpful documentation, or be outright malicious.\n"
"- Two small crates may be less optimized than one large one, since the "
"compiler\n"
" does not perform link-time optimization (LTO) by default."
msgstr ""
"- Esto puede conducir al \"infierno de la dependencia\", cuando un proyecto "
"depende de múltiples conflictos\n"
" versiones de una caja al mismo tiempo. Por ejemplo, la caja `url` tiene "
"ambas versiones\n"
" 1.0 y 0.5. Dado que la `Url` de `url:1.0` y la `Url` de `url:0.5` son\n"
" diferentes tipos, un cliente HTTP que usa `url:0.5` no aceptaría valores "
"`Url`\n"
" de un web scraper que usa `url:1.0`.\n"
"- Los paquetes en crates.io no están curados. Una caja puede estar mal "
"escrita, tener\n"
" documentación poco útil, o ser totalmente malicioso.\n"
"- Dos cajas pequeñas pueden estar menos optimizadas que una grande, ya que "
"el compilador\n"
" no realiza la optimización del tiempo de enlace (LTO) de forma "
"predeterminada."
#: src\patterns/structural/small-crates.md:36
#, fuzzy
msgid ""
"The [`ref_slice`](https://crates.io/crates/ref_slice) crate provides "
"functions\n"
"for converting `&T` to `&[T]`."
msgstr ""
"El cajón [`ref_slice`](https://crates.io/crates/ref_slice) proporciona "
"funciones\n"
"para convertir `&T` a `&[T]`."
#: src\patterns/structural/small-crates.md:39
#, fuzzy
msgid ""
"The [`url`](https://crates.io/crates/url) crate provides tools for working "
"with\n"
"URLs."
msgstr ""
"El cajón [`url`](https://crates.io/crates/url) proporciona herramientas para "
"trabajar con\n"
"URL."
#: src\patterns/structural/small-crates.md:42
#, fuzzy
msgid ""
"The [`num_cpus`](https://crates.io/crates/num_cpus) crate provides a "
"function to\n"
"query the number of CPUs on a machine."
msgstr ""
"El cajón [`num_cpus`](https://crates.io/crates/num_cpus) proporciona una "
"función para\n"
"consultar el número de CPU en una máquina."
#: src\patterns/structural/small-crates.md:47
#, fuzzy
msgid "- [crates.io: The Rust community crate host](https://crates.io/)"
msgstr ""
"- [crates.io: El host de cajas de la comunidad de Rust](https://crates.io/)"
#: src\patterns/structural/unsafe-mods.md:1
#, fuzzy
msgid "# Contain unsafety in small modules"
msgstr "# Contener la inseguridad en pequeños módulos"
#: src\patterns/structural/unsafe-mods.md:5
#, fuzzy
msgid ""
"If you have `unsafe` code, create the smallest possible module that can "
"uphold\n"
"the needed invariants to build a minimal safe interface upon the unsafety. "
"Embed\n"
"this into a larger module that contains only safe code and presents an "
"ergonomic\n"
"interface. Note that the outer module can contain unsafe functions and "
"methods\n"
"that call directly into the unsafe code. Users may use this to gain speed "
"benefits."
msgstr ""
"Si tiene un código \"inseguro\", cree el módulo más pequeño posible que "
"pueda mantener\n"
"las invariantes necesarias para construir una interfaz segura mínima sobre "
"la inseguridad. Empotrar\n"
"esto en un módulo más grande que contiene solo código seguro y presenta un "
"diseño ergonómico\n"
"interfaz. Tenga en cuenta que el módulo externo puede contener funciones y "
"métodos no seguros\n"
"que llaman directamente al código no seguro. Los usuarios pueden usar esto "
"para obtener beneficios de velocidad."
#: src\patterns/structural/unsafe-mods.md:13
#, fuzzy
msgid ""
"- This restricts the unsafe code that must be audited\n"
"- Writing the outer module is much easier, since you can count on the "
"guarantees\n"
" of the inner module"
msgstr ""
"- Esto restringe el código inseguro que debe ser auditado\n"
"- Escribir el módulo exterior es mucho más fácil, ya que puedes contar con "
"las garantías\n"
" del módulo interior"
#: src\patterns/structural/unsafe-mods.md:19
#, fuzzy
msgid ""
"- Sometimes, it may be hard to find a suitable interface.\n"
"- The abstraction may introduce inefficiencies."
msgstr ""
"- A veces, puede ser difícil encontrar una interfaz adecuada.\n"
"- La abstracción puede introducir ineficiencias."
#: src\patterns/structural/unsafe-mods.md:24
#, fuzzy
msgid ""
"- The [`toolshed`](https://docs.rs/toolshed) crate contains its unsafe "
"operations\n"
" in submodules, presenting a safe interface to users.\n"
"- `std`'s `String` class is a wrapper over `Vec<u8>` with the added "
"invariant\n"
" that the contents must be valid UTF-8. The operations on `String` ensure "
"this\n"
" behavior.\n"
" However, users have the option of using an `unsafe` method to create a "
"`String`,\n"
" in which case the onus is on them to guarantee the validity of the "
"contents."
msgstr ""
"- La caja [`toolshed`](https://docs.rs/toolshed) contiene sus operaciones "
"inseguras\n"
" en submódulos, presentando una interfaz segura para los usuarios.\n"
"- La clase `String` de `std` es un contenedor sobre `Vec<u8>` con el "
"invariante agregado\n"
" que el contenido debe ser UTF-8 válido. Las operaciones en `String` "
"aseguran esto\n"
" comportamiento.\n"
" Sin embargo, los usuarios tienen la opción de usar un método \"no seguro\" "
"para crear una \"Cadena\",\n"
" en cuyo caso corresponde a ellos garantizar la vigencia de los contenidos."
#: src\patterns/structural/unsafe-mods.md:34
#, fuzzy
msgid ""
"- [Ralf Jung's Blog about invariants in unsafe "
"code](https://www.ralfj.de/blog/2018/08/22/two-kinds-of-invariants.html)"
msgstr ""
"- [Blog de Ralf Jung sobre invariantes en código no "
"seguro](https://www.ralfj.de/blog/2018/08/22/two-kinds-of-invariants.html)"
#: src\patterns/ffi/intro.md:1
#, fuzzy
msgid "# FFI Patterns"
msgstr "# Patrones FFI"
#: src\patterns/ffi/intro.md:3
#, fuzzy
msgid ""
"Writing FFI code is an entire course in itself.\n"
"However, there are several idioms here that can act as pointers, and avoid "
"traps\n"
"for inexperienced users of unsafe Rust."
msgstr ""
"Escribir código FFI es un curso completo en sí mismo.\n"
"Sin embargo, aquí hay varios modismos que pueden actuar como indicadores y "
"evitar trampas.\n"
"para usuarios inexpertos de Rust inseguro."
#: src\patterns/ffi/intro.md:7
#, fuzzy
msgid "This section contains design patterns that may be useful when doing FFI."
msgstr ""
"Esta sección contiene patrones de diseño que pueden ser útiles al hacer FFI."
#: src\patterns/ffi/intro.md:9
#, fuzzy
msgid ""
"1. [Object-Based API](./export.md) design that has good memory safety "
"characteristics,\n"
" and a clean boundary of what is safe and what is unsafe\n"
"\n"
"2. [Type Consolidation into Wrappers](./wrappers.md) - group multiple Rust "
"types\n"
" together into an opaque \"object\""
msgstr ""
"1. Diseño de [API basada en objetos] (./export.md) que tiene buenas "
"características de seguridad de memoria,\n"
" y un límite limpio de lo que es seguro y lo que es inseguro\n"
"\n"
"2. [Consolidación de tipos en envoltorios] (./wrappers.md) - agrupa varios "
"tipos de Rust\n"
" juntos en un \"objeto\" opaco"
#: src\patterns/ffi/export.md:1
#, fuzzy
msgid "# Object-Based APIs"
msgstr "# API basadas en objetos"
#: src\patterns/ffi/export.md:5
#, fuzzy
msgid ""
"When designing APIs in Rust which are exposed to other languages, there are "
"some\n"
"important design principles which are contrary to normal Rust API design:"
msgstr ""
"Al diseñar API en Rust que están expuestas a otros lenguajes, hay algunos\n"
"principios de diseño importantes que son contrarios al diseño normal de la "
"API de Rust:"
#: src\patterns/ffi/export.md:8
#, fuzzy
msgid ""
"1. All Encapsulated types should be _owned_ by Rust, _managed_ by the user,\n"
" and _opaque_.\n"
"2. All Transactional data types should be _owned_ by the user, and "
"_transparent_.\n"
"3. All library behavior should be functions acting upon Encapsulated types.\n"
"4. All library behavior should be encapsulated into types not based on "
"structure,\n"
" but _provenance/lifetime_."
msgstr ""
"1. Todos los tipos encapsulados deben ser _propiedad_ de Rust, "
"_administrados_ por el usuario,\n"
" y _opaco_.\n"
"2. Todos los tipos de datos transaccionales deben ser _propiedad_ del "
"usuario y _transparentes_.\n"
"3. Todo el comportamiento de la biblioteca debe ser funciones que actúen "
"sobre tipos encapsulados.\n"
"4. Todo el comportamiento de la biblioteca debe encapsularse en tipos que no "
"se basen en la estructura,\n"
" pero _procedencia/tiempo de vida_."
#: src\patterns/ffi/export.md:17
#, fuzzy
msgid ""
"Rust has built-in FFI support to other languages.\n"
"It does this by providing a way for crate authors to provide C-compatible "
"APIs\n"
"through different ABIs (though that is unimportant to this practice)."
msgstr ""
"Rust tiene soporte FFI integrado para otros idiomas.\n"
"Lo hace al proporcionar una forma para que los autores de cajas proporcionen "
"API compatibles con C\n"
"a través de diferentes ABI (aunque eso no es importante para esta práctica)."
#: src\patterns/ffi/export.md:21
#, fuzzy
msgid ""
"Well-designed Rust FFI follows C API design principles, while compromising "
"the\n"
"design in Rust as little as possible. There are three goals with any foreign "
"API:"
msgstr ""
"Rust FFI bien diseñado sigue los principios de diseño de C API, al tiempo "
"que compromete la\n"
"diseño en Rust lo menos posible. Hay tres objetivos con cualquier API "
"extranjera:"
#: src\patterns/ffi/export.md:24
#, fuzzy
msgid ""
"1. Make it easy to use in the target language.\n"
"2. Avoid the API dictating internal unsafety on the Rust side as much as "
"possible.\n"
"3. Keep the potential for memory unsafety and Rust `undefined behaviour` as "
"small\n"
" as possible."
msgstr ""
"1. Facilite su uso en el idioma de destino.\n"
"2. Evite que la API dicte inseguridad interna en el lado de Rust tanto como "
"sea posible.\n"
"3. Mantenga el potencial de inseguridad de la memoria y el \"comportamiento "
"indefinido\" de Rust como pequeño\n"
" como sea posible."
#: src\patterns/ffi/export.md:29
#, fuzzy
msgid ""
"Rust code must trust the memory safety of the foreign language beyond a "
"certain\n"
"point. However, every bit of `unsafe` code on the Rust side is an "
"opportunity for\n"
"bugs, or to exacerbate `undefined behaviour`."
msgstr ""
"El código Rust debe confiar en la seguridad de la memoria del idioma "
"extranjero más allá de cierto\n"
"punto. Sin embargo, cada fragmento de código \"inseguro\" en el lado de Rust "
"es una oportunidad para\n"
"errores, o para exacerbar el \"comportamiento indefinido\"."
#: src\patterns/ffi/export.md:33
#, fuzzy
msgid ""
"For example, if a pointer provenance is wrong, that may be a segfault due "
"to\n"
"invalid memory access. But if it is manipulated by unsafe code, it could "
"become\n"
"full-blown heap corruption."
msgstr ""
"Por ejemplo, si la procedencia de un puntero es incorrecta, eso puede ser un "
"error de segmentación debido a\n"
"acceso a memoria inválido. Pero si es manipulado por un código no seguro, "
"podría volverse\n"
"corrupción del montón en toda regla."
#: src\patterns/ffi/export.md:37
#, fuzzy
msgid ""
"The Object-Based API design allows for writing shims that have good memory "
"safety\n"
"characteristics, and a clean boundary of what is safe and what is `unsafe`."
msgstr ""
"El diseño de la API basada en objetos permite escribir correcciones que "
"tienen buena seguridad de memoria\n"
"características, y un límite claro de lo que es seguro y lo que es "
"\"inseguro\"."
#: src\patterns/ffi/export.md:42
#, fuzzy
msgid ""
"The POSIX standard defines the API to access an on-file database, known as "
"[DBM](https://web.archive.org/web/20210105035602/https://www.mankier.com/0p/ndbm.h).\n"
"It is an excellent example of an \"object-based\" API."
msgstr ""
"El estándar POSIX define la API para acceder a una base de datos en archivo, "
"conocida como "
"[DBM](https://web.archive.org/web/20210105035602/https://www.mankier.com/0p/ndbm.h) "
".\n"
"Es un excelente ejemplo de una API \"basada en objetos\"."
#: src\patterns/ffi/export.md:45
#, fuzzy
msgid ""
"Here is the definition in C, which hopefully should be easy to read for "
"those\n"
"involved in FFI. The commentary below should help explain it for those who\n"
"miss the subtleties."
msgstr ""
"Aquí está la definición en C, que con suerte debería ser fácil de leer para "
"aquellos\n"
"involucrados en FFI. El comentario a continuación debería ayudar a "
"explicarlo para aquellos que\n"
"perder las sutilezas."
#: src\patterns/ffi/export.md:49
msgid ""
"```C\n"
"struct DBM;\n"
"typedef struct { void *dptr, size_t dsize } datum;\n"
"\n"
"int dbm_clearerr(DBM *);\n"
"void dbm_close(DBM *);\n"
"int dbm_delete(DBM *, datum);\n"
"int dbm_error(DBM *);\n"
"datum dbm_fetch(DBM *, datum);\n"
"datum dbm_firstkey(DBM *);\n"
"datum dbm_nextkey(DBM *);\n"
"DBM *dbm_open(const char *, int, mode_t);\n"
"int dbm_store(DBM *, datum, datum, int);\n"
"```"
msgstr ""
#: src\patterns/ffi/export.md:64
#, fuzzy
msgid "This API defines two types: `DBM` and `datum`."
msgstr "Esta API define dos tipos: `DBM` y `datum`."
#: src\patterns/ffi/export.md:66
#, fuzzy
msgid ""
"The `DBM` type was called an \"encapsulated\" type above.\n"
"It is designed to contain internal state, and acts as an entry point for "
"the\n"
"library's behavior."
msgstr ""
"El tipo `DBM` se denominó tipo \"encapsulado\" anteriormente.\n"
"Está diseñado para contener el estado interno y actúa como un punto de "
"entrada para el\n"
"comportamiento de la biblioteca."
#: src\patterns/ffi/export.md:70
#, fuzzy
msgid ""
"It is completely opaque to the user, who cannot create a `DBM` themselves "
"since\n"
"they don't know its size or layout. Instead, they must call `dbm_open`, and "
"that\n"
"only gives them _a pointer to one_."
msgstr ""
"Es completamente opaco para el usuario, que no puede crear un 'DBM' por sí "
"mismo ya que\n"
"no saben su tamaño o diseño. En su lugar, deben llamar a `dbm_open`, y eso\n"
"solo les da _un puntero a uno_."
#: src\patterns/ffi/export.md:74
#, fuzzy
msgid ""
"This means all `DBM`s are \"owned\" by the library in a Rust sense.\n"
"The internal state of unknown size is kept in memory controlled by the "
"library,\n"
"not the user. The user can only manage its life cycle with `open` and "
"`close`,\n"
"and perform operations on it with the other functions."
msgstr ""
"Esto significa que todos los 'DBM' son \"propiedad\" de la biblioteca en el "
"sentido de Rust.\n"
"El estado interno de tamaño desconocido se mantiene en la memoria controlada "
"por la biblioteca,\n"
"no el usuario. El usuario solo puede gestionar su ciclo de vida con `abrir` "
"y `cerrar`,\n"
"y realizar operaciones en él con las otras funciones."
#: src\patterns/ffi/export.md:79
#, fuzzy
msgid ""
"The `datum` type was called a \"transactional\" type above.\n"
"It is designed to facilitate the exchange of information between the library "
"and\n"
"its user."
msgstr ""
"El tipo `datum` se denominó tipo \"transaccional\" anteriormente.\n"
"Está diseñado para facilitar el intercambio de información entre la "
"biblioteca y\n"
"su usuario."
#: src\patterns/ffi/export.md:83
#, fuzzy
msgid ""
"The database is designed to store \"unstructured data\", with no pre-defined "
"length\n"
"or meaning. As a result, the `datum` is the C equivalent of a Rust slice: a "
"bunch\n"
"of bytes, and a count of how many there are. The main difference is that "
"there is\n"
"no type information, which is what `void` indicates."
msgstr ""
"La base de datos está diseñada para almacenar \"datos no estructurados\", "
"sin longitud predefinida\n"
"o significado. Como resultado, el `dato` es el equivalente en C de una "
"rebanada de Rust: un montón\n"
"de bytes, y un recuento de cuántos hay. La principal diferencia es que hay\n"
"sin información de tipo, que es lo que indica `void`."
#: src\patterns/ffi/export.md:88
#, fuzzy
msgid ""
"Keep in mind that this header is written from the library's point of view.\n"
"The user likely has some type they are using, which has a known size.\n"
"But the library does not care, and by the rules of C casting, any type "
"behind a\n"
"pointer can be cast to `void`."
msgstr ""
"Tenga en cuenta que este encabezado está escrito desde el punto de vista de "
"la biblioteca.\n"
"Es probable que el usuario tenga algún tipo que esté usando, que tenga un "
"tamaño conocido.\n"
"Pero a la biblioteca no le importa, y según las reglas de conversión de C, "
"cualquier tipo detrás de un\n"
"el puntero se puede convertir en `void`."
#: src\patterns/ffi/export.md:93
#, fuzzy
msgid ""
"As noted earlier, this type is _transparent_ to the user. But also, this "
"type is\n"
"_owned_ by the user.\n"
"This has subtle ramifications, due to that pointer inside it.\n"
"The question is, who owns the memory that pointer points to?"
msgstr ""
"Como se señaló anteriormente, este tipo es _transparente_ para el usuario. "
"Pero también, este tipo es\n"
"_propiedad_ del usuario.\n"
"Esto tiene ramificaciones sutiles, debido a ese puntero en su interior.\n"
"La pregunta es, ¿quién posee la memoria a la que apunta el puntero?"
#: src\patterns/ffi/export.md:98
#, fuzzy
msgid ""
"The answer for best memory safety is, \"the user\".\n"
"But in cases such as retrieving a value, the user does not know how to "
"allocate\n"
"it correctly (since they don't know how long the value is). In this case, "
"the library\n"
"code is expected to use the heap that the user has access to -- such as the "
"C library\n"
"`malloc` and `free` -- and then _transfer ownership_ in the Rust sense."
msgstr ""
"La respuesta para la mejor seguridad de la memoria es \"el usuario\".\n"
"Pero en casos como recuperar un valor, el usuario no sabe cómo asignar\n"
"correctamente (ya que no saben cuánto tiempo es el valor). En este caso, la "
"biblioteca.\n"
"Se espera que el código use el montón al que el usuario tiene acceso, como "
"la biblioteca C.\n"
"`malloc` y `free` -- y luego _transferir propiedad_ en el sentido de Rust."
#: src\patterns/ffi/export.md:104
#, fuzzy
msgid ""
"This may all seem speculative, but this is what a pointer means in C.\n"
"It means the same thing as Rust: \"user defined lifetime.\"\n"
"The user of the library needs to read the documentation in order to use it "
"correctly.\n"
"That said, there are some decisions that have fewer or greater consequences "
"if users\n"
"do it wrong. Minimizing those are what this best practice is about, and the "
"key\n"
"is to _transfer ownership of everything that is transparent_."
msgstr ""
"Todo esto puede parecer especulativo, pero esto es lo que significa un "
"puntero en C.\n"
"Significa lo mismo que Rust: \"vida útil definida por el usuario\".\n"
"El usuario de la biblioteca necesita leer la documentación para utilizarla "
"correctamente.\n"
"Dicho esto, hay algunas decisiones que tienen menos o mayores consecuencias "
"si los usuarios\n"
"hazlo mal Minimizarlos es de lo que se trata esta mejor práctica, y la "
"clave\n"
"es _transferir la propiedad de todo lo que es transparente_."
#: src\patterns/ffi/export.md:113
#, fuzzy
msgid ""
"This minimizes the number of memory safety guarantees the user must uphold "
"to a\n"
"relatively small number:"
msgstr ""
"Esto minimiza el número de garantías de seguridad de la memoria que el "
"usuario debe mantener a un nivel\n"
"número relativamente pequeño:"
#: src\patterns/ffi/export.md:116
#, fuzzy
msgid ""
"1. Do not call any function with a pointer not returned by `dbm_open` "
"(invalid\n"
" access or corruption).\n"
"2. Do not call any function on a pointer after close (use after free).\n"
"3. The `dptr` on any `datum` must be `NULL`, or point to a valid slice of "
"memory\n"
" at the advertised length."
msgstr ""
"1. No llame a ninguna función con un puntero no devuelto por `dbm_open` "
"(inválido\n"
" acceso o corrupción).\n"
"2. No llame a ninguna función en un puntero después de cerrar (usar después "
"de liberar).\n"
"3. El `dptr` en cualquier `datum` debe ser `NULL`, o apuntar a una porción "
"válida de memoria\n"
" en la longitud anunciada."
#: src\patterns/ffi/export.md:122
#, fuzzy
msgid ""
"In addition, it avoids a lot of pointer provenance issues.\n"
"To understand why, let us consider an alternative in some depth: key "
"iteration."
msgstr ""
"Además, evita muchos problemas de procedencia de punteros.\n"
"Para entender por qué, consideremos una alternativa con cierta profundidad: "
"iteración clave."
#: src\patterns/ffi/export.md:125
#, fuzzy
msgid ""
"Rust is well known for its iterators.\n"
"When implementing one, the programmer makes a separate type with a bounded "
"lifetime\n"
"to its owner, and implements the `Iterator` trait."
msgstr ""
"Rust es bien conocido por sus iteradores.\n"
"Al implementar uno, el programador crea un tipo separado con una vida útil "
"limitada\n"
"a su propietario, e implementa el rasgo `Iterator`."
#: src\patterns/ffi/export.md:129
#, fuzzy
msgid "Here is how iteration would be done in Rust for `DBM`:"
msgstr "Así es como se haría la iteración en Rust para `DBM`:"
#: src\patterns/ffi/export.md:131
msgid ""
"```rust,ignore\n"
"struct Dbm { ... }\n"
"\n"
"impl Dbm {\n"
" /* ... */\n"
" pub fn keys<'it>(&'it self) -> DbmKeysIter<'it> { ... }\n"
" /* ... */\n"
"}\n"
"\n"
"struct DbmKeysIter<'it> {\n"
" owner: &'it Dbm,\n"
"}\n"
"\n"
"impl<'it> Iterator for DbmKeysIter<'it> { ... }\n"
"```"
msgstr ""
#: src\patterns/ffi/export.md:147
#, fuzzy
msgid ""
"This is clean, idiomatic, and safe. thanks to Rust's guarantees.\n"
"However, consider what a straightforward API translation would look like:"
msgstr ""
"Esto es limpio, idiomático y seguro. gracias a las garantías de Rust.\n"
"Sin embargo, considere cómo se vería una traducción de API sencilla:"
#: src\patterns/ffi/export.md:150
msgid ""
"```rust,ignore\n"
"#[no_mangle]\n"
"pub extern \"C\" fn dbm_iter_new(owner: *const Dbm) -> *mut DbmKeysIter {\n"
" // THIS API IS A BAD IDEA! For real applications, use object-based "
"design instead.\n"
"}\n"
"#[no_mangle]\n"
"pub extern \"C\" fn dbm_iter_next(\n"
" iter: *mut DbmKeysIter,\n"
" key_out: *const datum\n"
") -> libc::c_int {\n"
" // THIS API IS A BAD IDEA! For real applications, use object-based "
"design instead.\n"
"}\n"
"#[no_mangle]\n"
"pub extern \"C\" fn dbm_iter_del(*mut DbmKeysIter) {\n"
" // THIS API IS A BAD IDEA! For real applications, use object-based "
"design instead.\n"
"}\n"
"```"
msgstr ""
#: src\patterns/ffi/export.md:168
#, fuzzy
msgid ""
"This API loses a key piece of information: the lifetime of the iterator must "
"not\n"
"exceed the lifetime of the `Dbm` object that owns it. A user of the library "
"could\n"
"use it in a way which causes the iterator to outlive the data it is "
"iterating on,\n"
"resulting in reading uninitialized memory."
msgstr ""
"Esta API pierde una pieza clave de información: la vida útil del iterador no "
"debe\n"
"exceda la vida útil del objeto `Dbm` que lo posee. Un usuario de la "
"biblioteca podría\n"
"úselo de una manera que haga que el iterador sobreviva a los datos en los "
"que está iterando,\n"
"resultando en la lectura de la memoria no inicializada."
#: src\patterns/ffi/export.md:173
#, fuzzy
msgid ""
"This example written in C contains a bug that will be explained afterwards:"
msgstr ""
"Este ejemplo escrito en C contiene un error que se explicará más adelante:"
#: src\patterns/ffi/export.md:175
msgid ""
"```C\n"
"int count_key_sizes(DBM *db) {\n"
" // DO NOT USE THIS FUNCTION. IT HAS A SUBTLE BUT SERIOUS BUG!\n"
" datum key;\n"
" int len = 0;\n"
"\n"
" if (!dbm_iter_new(db)) {\n"
" dbm_close(db);\n"
" return -1;\n"
" }\n"
"\n"
" int l;\n"
" while ((l = dbm_iter_next(owner, &key)) >= 0) { // an error is indicated "
"by -1\n"
" free(key.dptr);\n"
" len += key.dsize;\n"
" if (l == 0) { // end of the iterator\n"
" dbm_close(owner);\n"
" }\n"
" }\n"
" if l >= 0 {\n"
" return -1;\n"
" } else {\n"
" return len;\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\patterns/ffi/export.md:202
#, fuzzy
msgid ""
"This bug is a classic. Here's what happens when the iterator returns the\n"
"end-of-iteration marker:"
msgstr ""
"Este error es un clásico. Esto es lo que sucede cuando el iterador devuelve "
"el\n"
"marcador de fin de iteración:"
#: src\patterns/ffi/export.md:205
#, fuzzy
msgid ""
"1. The loop condition sets `l` to zero, and enters the loop because `0 >= "
"0`.\n"
"2. The length is incremented, in this case by zero.\n"
"3. The if statement is true, so the database is closed. There should be a "
"break\n"
" statement here.\n"
"4. The loop condition executes again, causing a `next` call on the closed "
"object."
msgstr ""
"1. La condición del bucle establece `l` en cero y entra en el bucle porque "
"`0 >= 0`.\n"
"2. La longitud se incrementa, en este caso por cero.\n"
"3. La declaración if es verdadera, por lo que la base de datos está cerrada. "
"debe haber un descanso\n"
" declaración aquí.\n"
"4. La condición de bucle se ejecuta de nuevo, provocando una llamada "
"`siguiente` en el objeto cerrado."
#: src\patterns/ffi/export.md:211
#, fuzzy
msgid ""
"The worst part about this bug?\n"
"If the Rust implementation was careful, this code will work most of the "
"time!\n"
"If the memory for the `Dbm` object is not immediately reused, an internal "
"check\n"
"will almost certainly fail, resulting in the iterator returning a `-1` "
"indicating\n"
"an error. But occasionally, it will cause a segmentation fault, or even "
"worse,\n"
"nonsensical memory corruption!"
msgstr ""
"¿La peor parte de este error?\n"
"Si la implementación de Rust fue cuidadosa, ¡este código funcionará la mayor "
"parte del tiempo!\n"
"Si la memoria para el objeto `Dbm` no se reutiliza de inmediato, una "
"verificación interna\n"
"es casi seguro que fallará, lo que hará que el iterador devuelva un `-1` que "
"indica\n"
"un error. Pero en ocasiones, provocará un fallo de segmentación, o peor "
"aún,\n"
"Corrupción de memoria sin sentido!"
#: src\patterns/ffi/export.md:218
#, fuzzy
msgid ""
"None of this can be avoided by Rust.\n"
"From its perspective, it put those objects on its heap, returned pointers to "
"them,\n"
"and gave up control of their lifetimes. The C code simply must \"play nice\"."
msgstr ""
"Rust no puede evitar nada de esto.\n"
"Desde su perspectiva, puso esos objetos en su montón, les devolvió "
"punteros,\n"
"y cedieron el control de sus vidas. El código C simplemente debe \"jugar "
"bien\"."
#: src\patterns/ffi/export.md:222
#, fuzzy
msgid ""
"The programmer must read and understand the API documentation.\n"
"While some consider that par for the course in C, a good API design can "
"mitigate\n"
"this risk. The POSIX API for `DBM` did this by _consolidating the ownership_ "
"of\n"
"the iterator with its parent:"
msgstr ""
"El programador debe leer y comprender la documentación de la API.\n"
"Mientras que algunos consideran que está a la par del curso en C, un buen "
"diseño de API puede mitigar\n"
"este riesgo La API POSIX para `DBM` hizo esto al _consolidar la propiedad_ "
"de\n"
"el iterador con su padre:"
#: src\patterns/ffi/export.md:227
msgid ""
"```C\n"
"datum dbm_firstkey(DBM *);\n"
"datum dbm_nextkey(DBM *);\n"
"```"
msgstr ""
#: src\patterns/ffi/export.md:232
#, fuzzy
msgid ""
"Thus, all the lifetimes were bound together, and such unsafety was prevented."
msgstr ""
"Por lo tanto, todas las vidas estaban unidas y se previno tal inseguridad."
#: src\patterns/ffi/export.md:236
#, fuzzy
msgid ""
"However, this design choice also has a number of drawbacks, which should be\n"
"considered as well."
msgstr ""
"Sin embargo, esta elección de diseño también tiene una serie de "
"inconvenientes, que deben ser\n"
"considerado también."
#: src\patterns/ffi/export.md:239
#, fuzzy
msgid ""
"First, the API itself becomes less expressive.\n"
"With POSIX DBM, there is only one iterator per object, and every call "
"changes\n"
"its state. This is much more restrictive than iterators in almost any "
"language,\n"
"even though it is safe. Perhaps with other related objects, whose lifetimes "
"are\n"
"less hierarchical, this limitation is more of a cost than the safety."
msgstr ""
"Primero, la propia API se vuelve menos expresiva.\n"
"Con POSIX DBM, solo hay un iterador por objeto y cada llamada cambia\n"
"su estado Esto es mucho más restrictivo que los iteradores en casi cualquier "
"idioma,\n"
"aunque sea seguro. Tal vez con otros objetos relacionados, cuyas vidas son\n"
"menos jerárquica, esta limitación es más costosa que la seguridad."
#: src\patterns/ffi/export.md:245
#, fuzzy
msgid ""
"Second, depending on the relationships of the API's parts, significant "
"design effort\n"
"may be involved. Many of the easier design points have other patterns "
"associated\n"
"with them:"
msgstr ""
"Segundo, dependiendo de las relaciones de las partes de la API, un esfuerzo "
"de diseño significativo\n"
"puede estar implicado. Muchos de los puntos de diseño más fáciles tienen "
"otros patrones asociados\n"
"con ellos:"
#: src\patterns/ffi/export.md:249
#, fuzzy
msgid ""
"- [Wrapper Type Consolidation](./wrappers.md) groups multiple Rust types "
"together\n"
" into an opaque \"object\"\n"
"\n"
"- [FFI Error Passing](../../idioms/ffi/errors.md) explains error handling "
"with integer\n"
" codes and sentinel return values (such as `NULL` pointers)\n"
"\n"
"- [Accepting Foreign Strings](../../idioms/ffi/accepting-strings.md) allows "
"accepting\n"
" strings with minimal unsafe code, and is easier to get right than\n"
" [Passing Strings to FFI](../../idioms/ffi/passing-strings.md)"
msgstr ""
"- [Consolidación de tipos de contenedor] (./wrappers.md) agrupa varios tipos "
"de Rust juntos\n"
" en un \"objeto\" opaco\n"
"\n"
"- [FFI Error Passing](../../idioms/ffi/errors.md) explica el manejo de "
"errores con enteros\n"
" códigos y valores de retorno de centinela (como punteros `NULL`)\n"
"\n"
"- [Accepting Foreign Strings](../../idioms/ffi/accepting-strings.md) permite "
"aceptar\n"
" cadenas con código inseguro mínimo, y es más fácil hacerlo bien que\n"
" [Pasar cadenas a FFI](../../idioms/ffi/passing-strings.md)"
#: src\patterns/ffi/export.md:259
#, fuzzy
msgid ""
"However, not every API can be done this way.\n"
"It is up to the best judgement of the programmer as to who their audience is."
msgstr ""
"Sin embargo, no todas las API se pueden hacer de esta manera.\n"
"Depende del mejor juicio del programador quién es su audiencia."
#: src\patterns/ffi/wrappers.md:1
#, fuzzy
msgid "# Type Consolidation into Wrappers"
msgstr "# Escriba la consolidación en contenedores"
#: src\patterns/ffi/wrappers.md:5
#, fuzzy
msgid ""
"This pattern is designed to allow gracefully handling multiple related "
"types,\n"
"while minimizing the surface area for memory unsafety."
msgstr ""
"Este patrón está diseñado para permitir el manejo elegante de múltiples "
"tipos relacionados,\n"
"mientras minimiza el área de superficie para la inseguridad de la memoria."
#: src\patterns/ffi/wrappers.md:8
#, fuzzy
msgid ""
"One of the cornerstones of Rust's aliasing rules is lifetimes.\n"
"This ensures that many patterns of access between types can be memory safe,\n"
"data race safety included."
msgstr ""
"Una de las piedras angulares de las reglas de aliasing de Rust son las "
"vidas.\n"
"Esto asegura que muchos patrones de acceso entre tipos puedan ser seguros "
"para la memoria,\n"
"seguridad de carrera de datos incluida."
#: src\patterns/ffi/wrappers.md:12
#, fuzzy
msgid ""
"However, when Rust types are exported to other languages, they are usually "
"transformed\n"
"into pointers. In Rust, a pointer means \"the user manages the lifetime of "
"the pointee.\"\n"
"It is their responsibility to avoid memory unsafety."
msgstr ""
"Sin embargo, cuando los tipos de Rust se exportan a otros lenguajes, "
"generalmente se transforman\n"
"en punteros. En Rust, un puntero significa \"el usuario administra la vida "
"útil del pointee\".\n"
"Es su responsabilidad evitar la inseguridad de la memoria."
#: src\patterns/ffi/wrappers.md:16
#, fuzzy
msgid ""
"Some level of trust in the user code is thus required, notably around "
"use-after-free\n"
"which Rust can do nothing about. However, some API designs place higher "
"burdens\n"
"than others on the code written in the other language."
msgstr ""
"Por lo tanto, se requiere cierto nivel de confianza en el código de usuario, "
"especialmente en torno al uso después de la liberación.\n"
"sobre el cual Rust no puede hacer nada. Sin embargo, algunos diseños de API "
"imponen mayores cargas\n"
"que otros en el código escrito en el otro idioma."
#: src\patterns/ffi/wrappers.md:20
#, fuzzy
msgid ""
"The lowest risk API is the \"consolidated wrapper\", where all possible "
"interactions\n"
"with an object are folded into a \"wrapper type\", while keeping the Rust "
"API clean."
msgstr ""
"La API de menor riesgo es el \"contenedor consolidado\", donde todas las "
"posibles interacciones\n"
"con un objeto se pliegan en un \"tipo contenedor\", mientras se mantiene "
"limpia la API de Rust."
#: src\patterns/ffi/wrappers.md:25
#, fuzzy
msgid ""
"To understand this, let us look at a classic example of an API to export: "
"iteration\n"
"through a collection."
msgstr ""
"Para entender esto, veamos un ejemplo clásico de una API para exportar: "
"iteración\n"
"a través de una colección."
#: src\patterns/ffi/wrappers.md:28
#, fuzzy
msgid "That API looks like this:"
msgstr "Esa API se ve así:"
#: src\patterns/ffi/wrappers.md:30
#, fuzzy
msgid ""
"1. The iterator is initialized with `first_key`.\n"
"2. Each call to `next_key` will advance the iterator.\n"
"3. Calls to `next_key` if the iterator is at the end will do nothing.\n"
"4. As noted above, the iterator is \"wrapped into\" the collection (unlike "
"the native\n"
" Rust API)."
msgstr ""
"1. El iterador se inicializa con `first_key`.\n"
"2. Cada llamada a `next_key` hará avanzar el iterador.\n"
"3. Las llamadas a `next_key` si el iterador está al final no harán nada.\n"
"4. Como se señaló anteriormente, el iterador está \"envuelto\" en la "
"colección (a diferencia del nativo\n"
" API de óxido)."
#: src\patterns/ffi/wrappers.md:36
#, fuzzy
msgid ""
"If the iterator implements `nth()` efficiently, then it is possible to make "
"it\n"
"ephemeral to each function call:"
msgstr ""
"Si el iterador implementa `nth()` de manera eficiente, entonces es posible "
"hacerlo\n"
"efímero a cada llamada de función:"
#: src\patterns/ffi/wrappers.md:39
msgid ""
"```rust,ignore\n"
"struct MySetWrapper {\n"
" myset: MySet,\n"
" iter_next: usize,\n"
"}\n"
"\n"
"impl MySetWrapper {\n"
" pub fn first_key(&mut self) -> Option<&Key> {\n"
" self.iter_next = 0;\n"
" self.next_key()\n"
" }\n"
" pub fn next_key(&mut self) -> Option<&Key> {\n"
" if let Some(next) = self.myset.keys().nth(self.iter_next) {\n"
" self.iter_next += 1;\n"
" Some(next)\n"
" } else {\n"
" None\n"
" }\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\patterns/ffi/wrappers.md:61
#, fuzzy
msgid "As a result, the wrapper is simple and contains no `unsafe` code."
msgstr ""
"Como resultado, el envoltorio es simple y no contiene código \"no seguro\"."
#: src\patterns/ffi/wrappers.md:65
#, fuzzy
msgid ""
"This makes APIs safer to use, avoiding issues with lifetimes between types.\n"
"See [Object-Based APIs](./export.md) for more on the advantages and "
"pitfalls\n"
"this avoids."
msgstr ""
"Esto hace que las API sean más seguras de usar, evitando problemas con la "
"vida útil entre tipos.\n"
"Consulte [API basadas en objetos] (./export.md) para obtener más información "
"sobre las ventajas y desventajas\n"
"esto evita."
#: src\patterns/ffi/wrappers.md:71
#, fuzzy
msgid ""
"Often, wrapping types is quite difficult, and sometimes a Rust API "
"compromise\n"
"would make things easier."
msgstr ""
"A menudo, envolver tipos es bastante difícil y, a veces, un compromiso de la "
"API de Rust\n"
"facilitaría las cosas."
#: src\patterns/ffi/wrappers.md:74
#, fuzzy
msgid ""
"As an example, consider an iterator which does not efficiently implement "
"`nth()`.\n"
"It would definitely be worth putting in special logic to make the object "
"handle\n"
"iteration internally, or to support a different access pattern efficiently "
"that\n"
"only the Foreign Function API will use."
msgstr ""
"Como ejemplo, considere un iterador que no implementa eficientemente "
"`nth()`.\n"
"Definitivamente valdría la pena poner una lógica especial para hacer que el "
"objeto maneje\n"
"iteración internamente, o para admitir un patrón de acceso diferente de "
"manera eficiente que\n"
"solo se utilizará la API de funciones externas."
#: src\patterns/ffi/wrappers.md:79
#, fuzzy
msgid "### Trying to Wrap Iterators (and Failing)"
msgstr "### Tratando de envolver iteradores (y fallando)"
#: src\patterns/ffi/wrappers.md:81
#, fuzzy
msgid ""
"To wrap any type of iterator into the API correctly, the wrapper would need "
"to\n"
"do what a C version of the code would do: erase the lifetime of the "
"iterator,\n"
"and manage it manually."
msgstr ""
"Para envolver cualquier tipo de iterador en la API correctamente, el "
"envoltorio tendría que\n"
"hacer lo que haría una versión C del código: borrar la vida útil del "
"iterador,\n"
"y administrarlo manualmente."
#: src\patterns/ffi/wrappers.md:85
#, fuzzy
msgid "Suffice it to say, this is _incredibly_ difficult."
msgstr "Baste decir que esto es _increíblemente_ difícil."
#: src\patterns/ffi/wrappers.md:87
#, fuzzy
msgid "Here is an illustration of just _one_ pitfall."
msgstr "Aquí hay una ilustración de solo _one_ escollo."
#: src\patterns/ffi/wrappers.md:89
#, fuzzy
msgid "A first version of `MySetWrapper` would look like this:"
msgstr "Una primera versión de `MySetWrapper` se vería así:"
#: src\patterns/ffi/wrappers.md:91
msgid ""
"```rust,ignore\n"
"struct MySetWrapper {\n"
" myset: MySet,\n"
" iter_next: usize,\n"
" // created from a transmuted Box<KeysIter + 'self>\n"
" iterator: Option<NonNull<KeysIter<'static>>>,\n"
"}\n"
"```"
msgstr ""
#: src\patterns/ffi/wrappers.md:100
#, fuzzy
msgid ""
"With `transmute` being used to extend a lifetime, and a pointer to hide it,\n"
"it's ugly already. But it gets even worse: _any other operation can cause\n"
"Rust `undefined behaviour`_."
msgstr ""
"Con 'transmutar' que se usa para extender la vida útil y un puntero para "
"ocultarlo,\n"
"ya es feo. Pero se pone aún peor: _cualquier otra operación puede causar\n"
"Rust `comportamiento indefinido`_."
#: src\patterns/ffi/wrappers.md:104
#, fuzzy
msgid ""
"Consider that the `MySet` in the wrapper could be manipulated by other\n"
"functions during iteration, such as storing a new value to the key it was\n"
"iterating over. The API doesn't discourage this, and in fact some similar C\n"
"libraries expect it."
msgstr ""
"Considere que `MySet` en el contenedor podría ser manipulado por otros\n"
"funciones durante la iteración, como almacenar un nuevo valor en la clave "
"que fue\n"
"iterando sobre. La API no desaconseja esto, y de hecho algunos C similares\n"
"las bibliotecas lo esperan."
#: src\patterns/ffi/wrappers.md:109
#, fuzzy
msgid "A simple implementation of `myset_store` would be:"
msgstr "Una implementación simple de `myset_store` sería:"
#: src\patterns/ffi/wrappers.md:111
msgid ""
"```rust,ignore\n"
"pub mod unsafe_module {\n"
"\n"
" // other module content\n"
"\n"
" pub fn myset_store(\n"
" myset: *mut MySetWrapper,\n"
" key: datum,\n"
" value: datum) -> libc::c_int {\n"
"\n"
" // DO NOT USE THIS CODE. IT IS UNSAFE TO DEMONSTRATE A PROLBEM.\n"
"\n"
" let myset: &mut MySet = unsafe { // SAFETY: whoops, UB occurs in "
"here!\n"
" &mut (*myset).myset\n"
" };\n"
"\n"
" /* ...check and cast key and value data... */\n"
"\n"
" match myset.store(casted_key, casted_value) {\n"
" Ok(_) => 0,\n"
" Err(e) => e.into()\n"
" }\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\patterns/ffi/wrappers.md:137
#, fuzzy
msgid ""
"If the iterator exists when this function is called, we have violated one of "
"Rust's\n"
"aliasing rules. According to Rust, the mutable reference in this block must "
"have\n"
"_exclusive_ access to the object. If the iterator simply exists, it's not "
"exclusive,\n"
"so we have `undefined behaviour`! "
msgstr ""
"Si el iterador existe cuando se llama a esta función, hemos violado una de "
"las reglas de Rust\n"
"reglas de alias. Según Rust, la referencia mutable en este bloque debe "
"tener\n"
"acceso _exclusivo_ al objeto. Si el iterador simplemente existe, no es "
"exclusivo,\n"
"¡así que tenemos un `comportamiento indefinido`!"
#: src\patterns/ffi/wrappers.md:142
#, fuzzy
msgid ""
"To avoid this, we must have a way of ensuring that mutable reference really "
"is exclusive.\n"
"That basically means clearing out the iterator's shared reference while it "
"exists,\n"
"and then reconstructing it. In most cases, that will still be less efficient "
"than\n"
"the C version."
msgstr ""
"Para evitar esto, debemos tener una forma de asegurar que la referencia "
"mutable sea realmente exclusiva.\n"
"Eso básicamente significa borrar la referencia compartida del iterador "
"mientras existe,\n"
"y luego reconstruirlo. En la mayoría de los casos, seguirá siendo menos "
"eficiente que\n"
"la versión C."
#: src\patterns/ffi/wrappers.md:147
#, fuzzy
msgid ""
"Some may ask: how can C do this more efficiently?\n"
"The answer is, it cheats. Rust's aliasing rules are the problem, and C "
"simply ignores\n"
"them for its pointers. In exchange, it is common to see code that is "
"declared\n"
"in the manual as \"not thread safe\" under some or all circumstances. In "
"fact,\n"
"the [GNU C "
"library](https://manpages.debian.org/buster/manpages/attributes.7.en.html)\n"
"has an entire lexicon dedicated to concurrent behavior!"
msgstr ""
"Algunos pueden preguntarse: ¿cómo puede C hacer esto de manera más "
"eficiente?\n"
"La respuesta es que hace trampa. Las reglas de alias de Rust son el "
"problema, y C simplemente ignora\n"
"ellos por sus punteros. A cambio, es común ver código que se declara\n"
"en el manual como \"no seguro para subprocesos\" en algunas o todas las "
"circunstancias. De hecho,\n"
"la [biblioteca GNU "
"C](https://manpages.debian.org/buster/manpages/attributes.7.en.html)\n"
"tiene un léxico completo dedicado al comportamiento concurrente!"
#: src\patterns/ffi/wrappers.md:154
#, fuzzy
msgid ""
"Rust would rather make everything memory safe all the time, for both safety "
"and\n"
"optimizations that C code cannot attain. Being denied access to certain "
"shortcuts\n"
"is the price Rust programmers need to pay."
msgstr ""
"Rust prefiere que todo sea seguro para la memoria todo el tiempo, tanto por "
"seguridad como por\n"
"optimizaciones que el código C no puede lograr. Ser denegado el acceso a "
"ciertos accesos directos\n"
"es el precio que los programadores de Rust deben pagar."
#: src\patterns/ffi/wrappers.md:158
#, fuzzy
msgid ""
"For the C programmers out there scratching their heads, the iterator need\n"
"not be read _during_ this code cause the UB. The exclusivity rule also "
"enables\n"
"compiler optimizations which may cause inconsistent observations by the "
"iterator's\n"
"shared reference (e.g. stack spills or reordering instructions for "
"efficiency).\n"
"These observations may happen _any time after_ the mutable reference is "
"created."
msgstr ""
"Para los programadores de C que se rascan la cabeza, el iterador necesita\n"
"no se leerá _durante_ este código causará la UB. La regla de exclusividad "
"también permite\n"
"optimizaciones del compilador que pueden causar observaciones inconsistentes "
"por parte del iterador\n"
"referencia compartida (por ejemplo, derrames de pilas o instrucciones de "
"reordenación para mayor eficiencia).\n"
"Estas observaciones pueden ocurrir _en cualquier momento después de_ que se "
"cree la referencia mutable."
#: src\anti_patterns/index.md:1
#, fuzzy
msgid "# Anti-patterns"
msgstr "# Anti-patrones"
#: src\anti_patterns/index.md:3
#, fuzzy
msgid ""
"An [anti-pattern](https://en.wikipedia.org/wiki/Anti-pattern) is a solution "
"to\n"
"a \"recurring problem that is usually ineffective and risks being highly\n"
"counterproductive\". Just as valuable as knowing how to solve a problem, is\n"
"knowing how _not_ to solve it. Anti-patterns give us great counter-examples "
"to\n"
"consider relative to design patterns. Anti-patterns are not confined to "
"code.\n"
"For example, a process can be an anti-pattern, too."
msgstr ""
"Un [antipatrón](https://en.wikipedia.org/wiki/Anti-pattern) es una solución "
"para\n"
"un \"problema recurrente que generalmente es ineficaz y corre el riesgo de "
"ser altamente\n"
"contraproducente\". Tan valioso como saber cómo resolver un problema, es\n"
"saber cómo _no_ resolverlo. Los antipatrones nos dan grandes contraejemplos "
"para\n"
"considerar en relación con los patrones de diseño. Los antipatrones no se "
"limitan al código.\n"
"Por ejemplo, un proceso también puede ser un antipatrón."
#: src\anti_patterns/borrow_clone.md:1
#, fuzzy
msgid "# Clone to satisfy the borrow checker"
msgstr "# Clonar para satisfacer el verificador de préstamo"
#: src\anti_patterns/borrow_clone.md:5
#, fuzzy
msgid ""
"The borrow checker prevents Rust users from developing otherwise unsafe code "
"by\n"
"ensuring that either: only one mutable reference exists, or potentially many "
"but\n"
"all immutable references exist. If the code written does not hold true to "
"these\n"
"conditions, this anti-pattern arises when the developer resolves the "
"compiler\n"
"error by cloning the variable."
msgstr ""
"El verificador de préstamos evita que los usuarios de Rust desarrollen "
"código que de otro modo no sería seguro.\n"
"asegurando que: solo existe una referencia mutable, o potencialmente muchas "
"pero\n"
"todas las referencias inmutables existen. Si el código escrito no es fiel a "
"estos\n"
"condiciones, este antipatrón surge cuando el desarrollador resuelve el "
"compilador\n"
"error al clonar la variable."
#: src\anti_patterns/borrow_clone.md:13
msgid ""
"```rust\n"
"// define any variable\n"
"let mut x = 5;\n"
"\n"
"// Borrow `x` -- but clone it first\n"
"let y = &mut (x.clone());\n"
"\n"
"// without the x.clone() two lines prior, this line would fail on compile "
"as\n"
"// x has been borrowed\n"
"// thanks to x.clone(), x was never borrowed, and this line will run.\n"
"println!(\"{}\", x);\n"
"\n"
"// perform some action on the borrow to prevent rust from optimizing this\n"
"//out of existence\n"
"*y += 1;\n"
"```"
msgstr ""
#: src\anti_patterns/borrow_clone.md:32
#, fuzzy
msgid ""
"It is tempting, particularly for beginners, to use this pattern to resolve\n"
"confusing issues with the borrow checker. However, there are serious\n"
"consequences. Using `.clone()` causes a copy of the data to be made. Any "
"changes\n"
"between the two are not synchronized -- as if two completely separate "
"variables\n"
"exist."
msgstr ""
"Es tentador, especialmente para los principiantes, usar este patrón para "
"resolver\n"
"Problemas confusos con el verificador de préstamos. Sin embargo, existen "
"graves\n"
"consecuencias. El uso de `.clone()` hace que se haga una copia de los datos. "
"Algún cambio\n"
"entre los dos no están sincronizados, como si dos variables completamente "
"separadas\n"
"existir."
#: src\anti_patterns/borrow_clone.md:38
#, fuzzy
msgid ""
"There are special cases -- `Rc<T>` is designed to handle clones "
"intelligently.\n"
"It internally manages exactly one copy of the data, and cloning it will "
"only\n"
"clone the reference."
msgstr ""
"Hay casos especiales: `Rc<T>` está diseñado para manejar clones de forma "
"inteligente.\n"
"Administra internamente exactamente una copia de los datos, y clonarlos "
"solo\n"
"clonar la referencia."
#: src\anti_patterns/borrow_clone.md:42
#, fuzzy
msgid ""
"There is also `Arc<T>` which provides shared ownership of a value of type T\n"
"that is allocated in the heap. Invoking `.clone()` on `Arc` produces a new "
"`Arc`\n"
"instance, which points to the same allocation on the heap as the source "
"`Arc`,\n"
"while increasing a reference count."
msgstr ""
"También existe `Arc<T>` que proporciona la propiedad compartida de un valor "
"de tipo T\n"
"que se asigna en el montón. Invocar `.clone()` en `Arc` produce un nuevo "
"`Arc`\n"
"instancia, que apunta a la misma asignación en el montón que la fuente "
"`Arc`,\n"
"mientras aumenta un recuento de referencia."
#: src\anti_patterns/borrow_clone.md:47
#, fuzzy
msgid ""
"In general, clones should be deliberate, with full understanding of the\n"
"consequences. If a clone is used to make a borrow checker error disappear,\n"
"that's a good indication this anti-pattern may be in use."
msgstr ""
"En general, los clones deben ser deliberados, con pleno conocimiento de los\n"
"consecuencias. Si se usa un clon para hacer que desaparezca un error del "
"comprobador de préstamo,\n"
"esa es una buena indicación de que este antipatrón puede estar en uso."
#: src\anti_patterns/borrow_clone.md:51
#, fuzzy
msgid ""
"Even though `.clone()` is an indication of a bad pattern, sometimes\n"
"**it is fine to write inefficient code**, in cases such as when:"
msgstr ""
"Aunque `.clone()` es una indicación de un mal patrón, a veces\n"
"**está bien escribir código ineficiente**, en casos como cuando:"
#: src\anti_patterns/borrow_clone.md:54
#, fuzzy
msgid ""
"- the developer is still new to ownership\n"
"- the code doesn't have great speed or memory constraints\n"
" (like hackathon projects or prototypes)\n"
"- satisfying the borrow checker is really complicated, and you prefer to\n"
" optimize readability over performance"
msgstr ""
"- el desarrollador aún es nuevo en la propiedad\n"
"- el código no tiene grandes limitaciones de velocidad o memoria\n"
" (como proyectos de hackathon o prototipos)\n"
"- satisfacer el verificador de préstamos es realmente complicado, y "
"prefieres\n"
" optimizar la legibilidad sobre el rendimiento"
#: src\anti_patterns/borrow_clone.md:60
#, fuzzy
msgid ""
"If an unnecessary clone is suspected, The [Rust Book's chapter on "
"Ownership](https://doc.rust-lang.org/book/ownership.html)\n"
"should be understood fully before assessing whether the clone is required or "
"not."
msgstr ""
"Si se sospecha de un clon innecesario, el [capítulo de Rust Book sobre "
"propiedad] (https://doc.rust-lang.org/book/ownership.html)\n"
"debe entenderse completamente antes de evaluar si el clon es necesario o no."
#: src\anti_patterns/borrow_clone.md:63
#, fuzzy
msgid ""
"Also be sure to always run `cargo clippy` in your project, which will detect "
"some\n"
"cases in which `.clone()` is not necessary, like "
"[1](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone),\n"
"[2](https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_copy),\n"
"[3](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone) or "
"[4](https://rust-lang.github.io/rust-clippy/master/index.html#clone_double_ref)."
msgstr ""
"También asegúrese de ejecutar siempre `cargo clippy` en su proyecto, que "
"detectará algunos\n"
"casos en los que `.clone()` no es necesario, como "
"[1](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone),\n"
"[2](https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_copy),\n"
"[3](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone) o "
"[4](https://rust-lang.github.io/rust-clippy/master "
"/index.html#clone_double_ref)."
#: src\anti_patterns/borrow_clone.md:70
#, fuzzy
msgid ""
"- [`mem::{take(_), replace(_)}` to keep owned values in changed "
"enums](../idioms/mem-replace.md)\n"
"- [`Rc<T>` documentation, which handles .clone() "
"intelligently](http://doc.rust-lang.org/std/rc/)\n"
"- [`Arc<T>` documentation, a thread-safe reference-counting "
"pointer](https://doc.rust-lang.org/std/sync/struct.Arc.html)\n"
"- [Tricks with ownership in "
"Rust](https://web.archive.org/web/20210120233744/https://xion.io/post/code/rust-borrowchk-tricks.html)"
msgstr ""
"- [`mem::{take(_), replace(_)}` para mantener los valores propios en las "
"enumeraciones modificadas](../idioms/mem-replace.md)\n"
"- [Documentación `Rc<T>`, que maneja .clone() "
"inteligentemente](http://doc.rust-lang.org/std/rc/)\n"
"- [Documentación de `Arc<T>`, un puntero de recuento de referencia seguro "
"para subprocesos] (https://doc.rust-lang.org/std/sync/struct.Arc.html)\n"
"- [Trucos con propiedad en "
"Rust](https://web.archive.org/web/20210120233744/https://xion.io/post/code/rust-borrowchk-tricks.html)"
#: src\anti_patterns/deny-warnings.md:1
#, fuzzy
msgid "# `#![deny(warnings)]`"
msgstr "# `#![negar(advertencias)]`"
#: src\anti_patterns/deny-warnings.md:5
#, fuzzy
msgid ""
"A well-intentioned crate author wants to ensure their code builds without\n"
"warnings. So they annotate their crate root with the following:"
msgstr ""
"Un autor de cajas bien intencionado quiere asegurarse de que su código se "
"construya sin\n"
"advertencias Así que anotan su raíz de caja con lo siguiente:"
#: src\anti_patterns/deny-warnings.md:10
msgid ""
"```rust\n"
"#![deny(warnings)]\n"
"\n"
"// All is well.\n"
"```"
msgstr ""
#: src\anti_patterns/deny-warnings.md:18
#, fuzzy
msgid "It is short and will stop the build if anything is amiss."
msgstr "Es breve y detendrá la compilación si algo anda mal."
#: src\anti_patterns/deny-warnings.md:20
#, fuzzy
msgid "## Drawbacks"
msgstr "## Inconvenientes"
#: src\anti_patterns/deny-warnings.md:22
#, fuzzy
msgid ""
"By disallowing the compiler to build with warnings, a crate author opts out "
"of\n"
"Rust's famed stability. Sometimes new features or old misfeatures need a "
"change\n"
"in how things are done, thus lints are written that `warn` for a certain "
"grace\n"
"period before being turned to `deny`."
msgstr ""
"Al no permitir que el compilador construya con advertencias, el autor de un "
"cajón opta por no participar\n"
"La famosa estabilidad de Rust. A veces, las nuevas características o las "
"antiguas características incorrectas necesitan un cambio.\n"
"en cómo se hacen las cosas, así se escriben hilachas que `advierten` para "
"cierta gracia\n"
"antes de pasar a `denegar`."
#: src\anti_patterns/deny-warnings.md:27
#, fuzzy
msgid ""
"For example, it was discovered that a type could have two `impl`s with the "
"same\n"
"method. This was deemed a bad idea, but in order to make the transition "
"smooth,\n"
"the `overlapping-inherent-impls` lint was introduced to give a warning to "
"those\n"
"stumbling on this fact, before it becomes a hard error in a future release."
msgstr ""
"Por ejemplo, se descubrió que un tipo podía tener dos `impl`s con el mismo\n"
"método. Esto se consideró una mala idea, pero para que la transición sea "
"fluida,\n"
"el lint `overlapping-inherent-impls` se introdujo para dar una advertencia a "
"aquellos\n"
"tropezando con este hecho, antes de que se convierta en un error grave en "
"una versión futura."
#: src\anti_patterns/deny-warnings.md:32
#, fuzzy
msgid ""
"Also sometimes APIs get deprecated, so their use will emit a warning where\n"
"before there was none."
msgstr ""
"Además, a veces las API quedan obsoletas, por lo que su uso emitirá una "
"advertencia donde\n"
"antes no había ninguno."
#: src\anti_patterns/deny-warnings.md:35
#, fuzzy
msgid ""
"All this conspires to potentially break the build whenever something changes."
msgstr ""
"Todo esto conspira para potencialmente romper la compilación cada vez que "
"algo cambia."
#: src\anti_patterns/deny-warnings.md:37
#, fuzzy
msgid ""
"Furthermore, crates that supply additional lints (e.g. [rust-clippy]) can "
"no\n"
"longer be used unless the annotation is removed. This is mitigated with\n"
"[--cap-lints]. The `--cap-lints=warn` command line argument, turns all "
"`deny`\n"
"lint errors into warnings."
msgstr ""
"Además, las cajas que suministren pelusas adicionales (por ejemplo, "
"[rust-clippy]) no pueden\n"
"ya no se utilizará a menos que se elimine la anotación. Esto se mitiga con\n"
"[--cap-pelusas]. El argumento de la línea de comando `--cap-lints=warn` "
"convierte todo `deny`\n"
"lint errores en advertencias."
#: src\anti_patterns/deny-warnings.md:42
#: src\functional/generics-type-classes.md:227
#, fuzzy
msgid "## Alternatives"
msgstr "## Alternativas"
#: src\anti_patterns/deny-warnings.md:44
#, fuzzy
msgid ""
"There are two ways of tackling this problem: First, we can decouple the "
"build\n"
"setting from the code, and second, we can name the lints we want to deny\n"
"explicitly."
msgstr ""
"Hay dos formas de abordar este problema: primero, podemos desacoplar la "
"compilación\n"
"configuración del código, y segundo, podemos nombrar las pelusas que "
"queremos denegar\n"
"explícitamente."
#: src\anti_patterns/deny-warnings.md:48
#, fuzzy
msgid "The following command line will build with all warnings set to `deny`:"
msgstr ""
"La siguiente línea de comando se construirá con todas las advertencias "
"configuradas en \"denegar\":"
#: src\anti_patterns/deny-warnings.md:50
#, fuzzy
msgid "`RUSTFLAGS=\"-D warnings\" cargo build`"
msgstr "`RUSTFLAGS=\"-D advertencias\" construcción de carga`"
#: src\anti_patterns/deny-warnings.md:52
#, fuzzy
msgid ""
"This can be done by any individual developer (or be set in a CI tool like\n"
"Travis, but remember that this may break the build when something changes)\n"
"without requiring a change to the code."
msgstr ""
"Esto lo puede hacer cualquier desarrollador individual (o se puede "
"configurar en una herramienta de CI como\n"
"Travis, pero recuerda que esto puede romper la compilación cuando algo "
"cambia)\n"
"sin requerir un cambio en el código."
#: src\anti_patterns/deny-warnings.md:56
#, fuzzy
msgid ""
"Alternatively, we can specify the lints that we want to `deny` in the code.\n"
"Here is a list of warning lints that is (hopefully) safe to deny (as of "
"Rustc 1.48.0):"
msgstr ""
"Alternativamente, podemos especificar los lints que queremos `denegar` en el "
"código.\n"
"Aquí hay una lista de pelusas de advertencia que (con suerte) son seguras de "
"negar (a partir de Rustc 1.48.0):"
#: src\anti_patterns/deny-warnings.md:59
msgid ""
"```rust,ignore\n"
"#![deny(bad_style,\n"
" const_err,\n"
" dead_code,\n"
" improper_ctypes,\n"
" non_shorthand_field_patterns,\n"
" no_mangle_generic_items,\n"
" overflowing_literals,\n"
" path_statements,\n"
" patterns_in_fns_without_body,\n"
" private_in_public,\n"
" unconditional_recursion,\n"
" unused,\n"
" unused_allocation,\n"
" unused_comparisons,\n"
" unused_parens,\n"
" while_true)]\n"
"```"
msgstr ""
#: src\anti_patterns/deny-warnings.md:78
#, fuzzy
msgid "In addition, the following `allow`ed lints may be a good idea to `deny`:"
msgstr ""
"Además, las siguientes pelusas \"permitidas\" pueden ser una buena idea para "
"\"denegar\":"
#: src\anti_patterns/deny-warnings.md:80
msgid ""
"```rust,ignore\n"
"#![deny(missing_debug_implementations,\n"
" missing_docs,\n"
" trivial_casts,\n"
" trivial_numeric_casts,\n"
" unused_extern_crates,\n"
" unused_import_braces,\n"
" unused_qualifications,\n"
" unused_results)]\n"
"```"
msgstr ""
#: src\anti_patterns/deny-warnings.md:91
#, fuzzy
msgid "Some may also want to add `missing-copy-implementations` to their list."
msgstr ""
"Algunos también pueden querer agregar \"implementaciones de copias "
"faltantes\" a su lista."
#: src\anti_patterns/deny-warnings.md:93
#, fuzzy
msgid ""
"Note that we explicitly did not add the `deprecated` lint, as it is fairly\n"
"certain that there will be more deprecated APIs in the future."
msgstr ""
"Tenga en cuenta que no agregamos explícitamente la pelusa `obsoleta`, ya que "
"es bastante\n"
"seguro de que habrá más API obsoletas en el futuro."
#: src\anti_patterns/deny-warnings.md:98
#, fuzzy
msgid ""
"- [A collection of all clippy "
"lints](https://rust-lang.github.io/rust-clippy/master)\n"
"- [deprecate attribute] documentation\n"
"- Type `rustc -W help` for a list of lints on your system. Also type\n"
" `rustc --help` for a general list of options\n"
"- [rust-clippy] is a collection of lints for better Rust code"
msgstr ""
"- [Una colección de todas las pelusas cortadas] "
"(https://rust-lang.github.io/rust-clippy/master)\n"
"- Documentación de [atributo en desuso]\n"
"- Escriba `rustc -W help` para obtener una lista de pelusas en su sistema. "
"También escriba\n"
" `rustc --help` para una lista general de opciones\n"
"- [rust-clippy] es una colección de pelusas para mejorar el código de Rust"
#: src\anti_patterns/deref.md:1
#, fuzzy
msgid "# `Deref` polymorphism"
msgstr "# Polimorfismo `Deref`"
#: src\anti_patterns/deref.md:5
#, fuzzy
msgid ""
"Misuse the `Deref` trait to emulate inheritance between structs, and thus "
"reuse\n"
"methods."
msgstr ""
"Usar incorrectamente el rasgo `Deref` para emular la herencia entre "
"estructuras y, por lo tanto, reutilizar\n"
"métodos."
#: src\anti_patterns/deref.md:10
#, fuzzy
msgid ""
"Sometimes we want to emulate the following common pattern from OO languages "
"such\n"
"as Java:"
msgstr ""
"A veces queremos emular el siguiente patrón común de los lenguajes OO como\n"
"como Java:"
#: src\anti_patterns/deref.md:13
msgid ""
"```java\n"
"class Foo {\n"
" void m() { ... }\n"
"}\n"
"\n"
"class Bar extends Foo {}\n"
"\n"
"public static void main(String[] args) {\n"
" Bar b = new Bar();\n"
" b.m();\n"
"}\n"
"```"
msgstr ""
#: src\anti_patterns/deref.md:26
#, fuzzy
msgid "We can use the deref polymorphism anti-pattern to do so:"
msgstr "Podemos usar el antipatrón de polimorfismo deref para hacerlo:"
#: src\anti_patterns/deref.md:28
msgid ""
"```rust\n"
"use std::ops::Deref;\n"
"\n"
"struct Foo {}\n"
"\n"
"impl Foo {\n"
" fn m(&self) {\n"
" //..\n"
" }\n"
"}\n"
"\n"
"struct Bar {\n"
" f: Foo,\n"
"}\n"
"\n"
"impl Deref for Bar {\n"
" type Target = Foo;\n"
" fn deref(&self) -> &Foo {\n"
" &self.f\n"
" }\n"
"}\n"
"\n"
"fn main() {\n"
" let b = Bar { f: Foo {} };\n"
" b.m();\n"
"}\n"
"```"
msgstr ""
#: src\anti_patterns/deref.md:56
#, fuzzy
msgid ""
"There is no struct inheritance in Rust. Instead we use composition and "
"include\n"
"an instance of `Foo` in `Bar` (since the field is a value, it is stored "
"inline,\n"
"so if there were fields, they would have the same layout in memory as the "
"Java\n"
"version (probably, you should use `#[repr(C)]` if you want to be sure))."
msgstr ""
"No hay herencia de estructuras en Rust. En su lugar, usamos composición e "
"incluimos\n"
"una instancia de `Foo` en `Bar` (dado que el campo es un valor, se almacena "
"en línea,\n"
"entonces, si hubiera campos, tendrían el mismo diseño en la memoria que "
"Java\n"
"versión (probablemente, debería usar `#[repr(C)]` si quiere estar seguro))."
#: src\anti_patterns/deref.md:61
#, fuzzy
msgid ""
"In order to make the method call work we implement `Deref` for `Bar` with "
"`Foo`\n"
"as the target (returning the embedded `Foo` field). That means that when we\n"
"dereference a `Bar` (for example, using `*`) then we will get a `Foo`. That "
"is\n"
"pretty weird. Dereferencing usually gives a `T` from a reference to `T`, "
"here we\n"
"have two unrelated types. However, since the dot operator does implicit\n"
"dereferencing, it means that the method call will search for methods on "
"`Foo` as\n"
"well as `Bar`."
msgstr ""
"Para hacer que la llamada al método funcione, implementamos `Deref` para "
"`Bar` con `Foo`\n"
"como objetivo (devolviendo el campo `Foo` incrustado). Eso significa que "
"cuando nosotros\n"
"desreferenciar una `Bar` (por ejemplo, usando `*`) entonces obtendremos un "
"`Foo`. Eso es\n"
"bastante raro. La desreferenciación generalmente da una `T` de una "
"referencia a `T`, aquí\n"
"tienen dos tipos no relacionados. Sin embargo, dado que el operador punto "
"hace implícito\n"
"desreferenciación, significa que la llamada al método buscará métodos en "
"`Foo` como\n"
"así como `Bar`."
#: src\anti_patterns/deref.md:71
#, fuzzy
msgid "You save a little boilerplate, e.g.,"
msgstr "Te ahorras un poco de texto repetitivo, por ejemplo,"
#: src\anti_patterns/deref.md:73
msgid ""
"```rust,ignore\n"
"impl Bar {\n"
" fn m(&self) {\n"
" self.f.m()\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\anti_patterns/deref.md:83
#, fuzzy
msgid ""
"Most importantly this is a surprising idiom - future programmers reading "
"this in\n"
"code will not expect this to happen. That's because we are misusing the "
"`Deref`\n"
"trait rather than using it as intended (and documented, etc.). It's also "
"because\n"
"the mechanism here is completely implicit."
msgstr ""
"Lo más importante es que este es un idioma sorprendente: los futuros "
"programadores que lean esto en\n"
"el código no esperará que esto suceda. Eso es porque estamos haciendo un mal "
"uso de `Deref`\n"
"rasgo en lugar de usarlo según lo previsto (y documentado, etc.). también es "
"porque\n"
"el mecanismo aquí es completamente implícito."
#: src\anti_patterns/deref.md:88
#, fuzzy
msgid ""
"This pattern does not introduce subtyping between `Foo` and `Bar` like\n"
"inheritance in Java or C++ does. Furthermore, traits implemented by `Foo` "
"are\n"
"not automatically implemented for `Bar`, so this pattern interacts badly "
"with\n"
"bounds checking and thus generic programming."
msgstr ""
"Este patrón no introduce subtipos entre `Foo` y `Bar` como\n"
"la herencia en Java o C++ sí. Además, los rasgos implementados por `Foo` "
"son\n"
"no se implementa automáticamente para `Bar`, por lo que este patrón "
"interactúa mal con\n"
"verificación de límites y, por lo tanto, programación genérica."
#: src\anti_patterns/deref.md:93
#, fuzzy
msgid ""
"Using this pattern gives subtly different semantics from most OO languages "
"with\n"
"regards to `self`. Usually it remains a reference to the sub-class, with "
"this\n"
"pattern it will be the 'class' where the method is defined."
msgstr ""
"El uso de este patrón proporciona una semántica sutilmente diferente de la "
"mayoría de los lenguajes OO con\n"
"en lo que respecta a 'uno mismo'. Por lo general, sigue siendo una "
"referencia a la subclase, con esto\n"
"patrón será la 'clase' donde se define el método."
#: src\anti_patterns/deref.md:97
#, fuzzy
msgid ""
"Finally, this pattern only supports single inheritance, and has no notion "
"of\n"
"interfaces, class-based privacy, or other inheritance-related features. So, "
"it\n"
"gives an experience that will be subtly surprising to programmers used to "
"Java\n"
"inheritance, etc."
msgstr ""
"Finalmente, este patrón solo admite herencia única y no tiene noción de\n"
"interfaces, privacidad basada en clases u otras características relacionadas "
"con la herencia. Por lo que\n"
"brinda una experiencia que sorprenderá sutilmente a los programadores "
"acostumbrados a Java\n"
"herencia, etc"
#: src\anti_patterns/deref.md:104
#, fuzzy
msgid ""
"There is no one good alternative. Depending on the exact circumstances it "
"might\n"
"be better to re-implement using traits or to write out the facade methods "
"to\n"
"dispatch to `Foo` manually. We do intend to add a mechanism for inheritance\n"
"similar to this to Rust, but it is likely to be some time before it reaches\n"
"stable Rust. See these "
"[blog](http://aturon.github.io/blog/2015/09/18/reuse/)\n"
"[posts](http://smallcultfollowing.com/babysteps/blog/2015/10/08/virtual-structs-part-4-extended-enums-and-thin-traits/)\n"
"and this [RFC issue](https://github.com/rust-lang/rfcs/issues/349) for more "
"details."
msgstr ""
"No hay una buena alternativa. Dependiendo de las circunstancias exactas, "
"podría\n"
"sería mejor volver a implementar usando rasgos o escribir los métodos de "
"fachada para\n"
"enviar a `Foo` manualmente. Tenemos la intención de agregar un mecanismo "
"para la herencia.\n"
"similar a esto para Rust, pero es probable que pase algún tiempo antes de "
"que llegue\n"
"Roya estable. Ver estos "
"[blog](http://aturon.github.io/blog/2015/09/18/reuse/)\n"
"[publicaciones] "
"(http://smallcultfollowing.com/babysteps/blog/2015/10/08/virtual-structs-part-4-extended-enums-and-thin-traits/)\n"
"y este [problema de RFC] (https://github.com/rust-lang/rfcs/issues/349) para "
"obtener más detalles."
#: src\anti_patterns/deref.md:112
#, fuzzy
msgid ""
"The `Deref` trait is designed for the implementation of custom pointer "
"types.\n"
"The intention is that it will take a pointer-to-`T` to a `T`, not convert\n"
"between different types. It is a shame that this isn't (probably cannot be)\n"
"enforced by the trait definition."
msgstr ""
"El rasgo `Deref` está diseñado para la implementación de tipos de punteros "
"personalizados.\n"
"La intención es que tomará un puntero a `T` a `T`, no convertir\n"
"entre diferentes tipos. Es una pena que esto no sea (probablemente no puede "
"ser)\n"
"reforzado por la definición de rasgo."
#: src\anti_patterns/deref.md:117
#, fuzzy
msgid ""
"Rust tries to strike a careful balance between explicit and implicit "
"mechanisms,\n"
"favouring explicit conversions between types. Automatic dereferencing in the "
"dot\n"
"operator is a case where the ergonomics strongly favour an implicit "
"mechanism,\n"
"but the intention is that this is limited to degrees of indirection, not\n"
"conversion between arbitrary types."
msgstr ""
"Rust intenta lograr un equilibrio cuidadoso entre los mecanismos explícitos "
"e implícitos,\n"
"favoreciendo conversiones explícitas entre tipos. Eliminación automática de "
"referencias en el punto\n"
"operador es un caso donde la ergonomía favorece fuertemente un mecanismo "
"implícito,\n"
"pero la intención es que esto se limite a grados de indirección, no\n"
"conversión entre tipos arbitrarios."
#: src\anti_patterns/deref.md:125
#, fuzzy
msgid ""
"- [Collections are smart pointers idiom](../idioms/deref.md).\n"
"- Delegation crates for less boilerplate like "
"[delegate](https://crates.io/crates/delegate)\n"
" or [ambassador](https://crates.io/crates/ambassador)\n"
"- [Documentation for `Deref` "
"trait](https://doc.rust-lang.org/std/ops/trait.Deref.html)."
msgstr ""
"- [Las colecciones son modismos de punteros "
"inteligentes](../idioms/deref.md).\n"
"- Cajas de delegación para menos repetitivo como "
"[delegate](https://crates.io/crates/delegate)\n"
" o [embajador](https://crates.io/crates/ambassador)\n"
"- [Documentación para el rasgo "
"`Deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html)."
#: src\functional/index.md:1
#, fuzzy
msgid "# Functional Usage of Rust"
msgstr "# Uso funcional de Rust"
#: src\functional/index.md:3
#, fuzzy
msgid ""
"Rust is an imperative language, but it follows many\n"
"[functional "
"programming](https://en.wikipedia.org/wiki/Functional_programming) paradigms."
msgstr ""
"Rust es un lenguaje imperativo, pero sigue muchos\n"
"[programación "
"funcional](https://en.wikipedia.org/wiki/Functional_programming) paradigmas."
#: src\functional/index.md:6
#, fuzzy
msgid ""
"> In computer science, _functional programming_ is a programming paradigm "
"where\n"
"> programs are constructed by applying and composing functions.\n"
"> It is a declarative programming paradigm in which function definitions "
"are\n"
"> trees of expressions that each return a value, rather than a sequence of\n"
"> imperative statements which change the state of the program."
msgstr ""
"> En informática, la _programación funcional_ es un paradigma de "
"programación donde\n"
"> los programas se construyen aplicando y componiendo funciones.\n"
"> Es un paradigma de programación declarativa en el que las definiciones de "
"funciones son\n"
"> árboles de expresiones que devuelven un valor, en lugar de una secuencia "
"de\n"
"> declaraciones imperativas que cambian el estado del programa."
#: src\functional/paradigms.md:1
#, fuzzy
msgid "# Programming paradigms"
msgstr "# Paradigmas de programación"
#: src\functional/paradigms.md:3
#, fuzzy
msgid ""
"One of the biggest hurdles to understanding functional programs when coming\n"
"from an imperative background is the shift in thinking. Imperative programs\n"
"describe **how** to do something, whereas declarative programs describe\n"
"**what** to do. Let's sum the numbers from 1 to 10 to show this."
msgstr ""
"Uno de los mayores obstáculos para comprender los programas funcionales "
"cuando se trata de\n"
"desde un trasfondo imperativo es el cambio de pensamiento. programas "
"imperativos\n"
"describen **cómo** hacer algo, mientras que los programas declarativos "
"describen\n"
"**qué hacer. Sumemos los números del 1 al 10 para mostrar esto."
#: src\functional/paradigms.md:8
#, fuzzy
msgid "## Imperative"
msgstr "## Imperativo"
#: src\functional/paradigms.md:10
msgid ""
"```rust\n"
"let mut sum = 0;\n"
"for i in 1..11 {\n"
" sum += i;\n"
"}\n"
"println!(\"{}\", sum);\n"
"```"
msgstr ""
#: src\functional/paradigms.md:18
#, fuzzy
msgid ""
"With imperative programs, we have to play compiler to see what is "
"happening.\n"
"Here, we start with a `sum` of `0`.\n"
"Next, we iterate through the range from 1 to 10.\n"
"Each time through the loop, we add the corresponding value in the range.\n"
"Then we print it out."
msgstr ""
"Con los programas imperativos, tenemos que jugar al compilador para ver qué "
"está pasando.\n"
"Aquí, comenzamos con una `suma` de `0`.\n"
"A continuación, iteramos a través del rango de 1 a 10.\n"
"Cada vez que recorremos el bucle, sumamos el valor correspondiente en el "
"rango.\n"
"Luego lo imprimimos."
#: src\functional/paradigms.md:24
#, fuzzy
msgid ""
"| `i` | `sum` |\n"
"| :-: | :---: |\n"
"| 1 | 1 |\n"
"| 2 | 3 |\n"
"| 3 | 6 |\n"
"| 4 | 10 |\n"
"| 5 | 15 |\n"
"| 6 | 21 |\n"
"| 7 | 28 |\n"
"| 8 | 36 |\n"
"| 9 | 45 |\n"
"| 10 | 55 |"
msgstr ""
"| `yo` | `suma` |\n"
"| :-: | :---: |\n"
"| 1 | 1 |\n"
"| 2 | 3 |\n"
"| 3 | 6 |\n"
"| 4 | 10 |\n"
"| 5 | 15 |\n"
"| 6 | 21 |\n"
"| 7 | 28 |\n"
"| 8 | 36 |\n"
"| 9 | 45 |\n"
"| 10 | 55 |"
#: src\functional/paradigms.md:37
#, fuzzy
msgid ""
"This is how most of us start out programming. We learn that a program is a "
"set\n"
"of steps."
msgstr ""
"Así es como la mayoría de nosotros empezamos a programar. Aprendemos que un "
"programa es un conjunto\n"
"de pasos"
#: src\functional/paradigms.md:40
#, fuzzy
msgid "## Declarative"
msgstr "## Declarativo"
#: src\functional/paradigms.md:42
msgid ""
"```rust\n"
"println!(\"{}\", (1..11).fold(0, |a, b| a + b));\n"
"```"
msgstr ""
#: src\functional/paradigms.md:46
#, fuzzy
msgid ""
"Whoa! This is really different! What's going on here?\n"
"Remember that with declarative programs we are describing **what** to do,\n"
"rather than **how** to do it. `fold` is a function that "
"[composes](https://en.wikipedia.org/wiki/Function_composition)\n"
"functions. The name is a convention from Haskell."
msgstr ""
"¡Guau! ¡Esto es realmente diferente! ¿Que está pasando aqui?\n"
"Recuerde que con los programas declarativos estamos describiendo **qué** "
"hacer,\n"
"en lugar de **cómo** hacerlo. `fold` es una función que [compone] "
"(https://en.wikipedia.org/wiki/Function_composition)\n"
"funciones El nombre es una convención de Haskell."
#: src\functional/paradigms.md:51
#, fuzzy
msgid ""
"Here, we are composing functions of addition (this closure: `|a, b| a + b`)\n"
"with a range from 1 to 10. The `0` is the starting point, so `a` is `0` at\n"
"first. `b` is the first element of the range, `1`. `0 + 1 = 1` is the "
"result.\n"
"So now we `fold` again, with `a = 1`, `b = 2` and so `1 + 2 = 3` is the "
"next\n"
"result. This process continues until we get to the last element in the "
"range,\n"
"`10`."
msgstr ""
"Aquí, estamos componiendo funciones de suma (este cierre: `|a, b| a + b`)\n"
"con un rango de 1 a 10. El `0` es el punto de partida, por lo que `a` es `0` "
"en\n"
"primero. `b` es el primer elemento del rango, `1`. `0 + 1 = 1` es el "
"resultado.\n"
"Así que ahora 'doblamos' de nuevo, con 'a = 1', 'b = 2' y así '1 + 2 = 3' es "
"el siguiente\n"
"resultado. Este proceso continúa hasta que llegamos al último elemento del "
"rango,\n"
"`10`."
#: src\functional/paradigms.md:58
#, fuzzy
msgid ""
"| `a` | `b` | result |\n"
"| :-: | :-: | :----: |\n"
"| 0 | 1 | 1 |\n"
"| 1 | 2 | 3 |\n"
"| 3 | 3 | 6 |\n"
"| 6 | 4 | 10 |\n"
"| 10 | 5 | 15 |\n"
"| 15 | 6 | 21 |\n"
"| 21 | 7 | 28 |\n"
"| 28 | 8 | 36 |\n"
"| 36 | 9 | 45 |\n"
"| 45 | 10 | 55 |"
msgstr ""
"| `a` | `b` | resultado |\n"
"| :-: | :-: | :----: |\n"
"| 0 | 1 | 1 |\n"
"| 1 | 2 | 3 |\n"
"| 3 | 3 | 6 |\n"
"| 6 | 4 | 10 |\n"
"| 10 | 5 | 15 |\n"
"| 15 | 6 | 21 |\n"
"| 21 | 7 | 28 |\n"
"| 28 | 8 | 36 |\n"
"| 36 | 9 | 45 |\n"
"| 45 | 10 | 55 |"
#: src\functional/generics-type-classes.md:1
#, fuzzy
msgid "# Generics as Type Classes"
msgstr "# Genéricos como clases de tipos"
#: src\functional/generics-type-classes.md:5
#, fuzzy
msgid ""
"Rust's type system is designed more like functional languages (like "
"Haskell)\n"
"rather than imperative languages (like Java and C++). As a result, Rust can "
"turn\n"
"many kinds of programming problems into \"static typing\" problems. This is "
"one\n"
"of the biggest wins of choosing a functional language, and is critical to "
"many\n"
"of Rust's compile time guarantees."
msgstr ""
"El sistema de tipos de Rust está diseñado más como lenguajes funcionales "
"(como Haskell)\n"
"en lugar de lenguajes imperativos (como Java y C++). Como resultado, Rust "
"puede convertir\n"
"muchos tipos de problemas de programación en problemas de \"tipado "
"estático\". Este es uno\n"
"de las mayores ganancias de elegir un lenguaje funcional, y es fundamental "
"para muchos\n"
"de las garantías de tiempo de compilación de Rust."
#: src\functional/generics-type-classes.md:11
#, fuzzy
msgid ""
"A key part of this idea is the way generic types work. In C++ and Java, for\n"
"example, generic types are a meta-programming construct for the compiler.\n"
"`vector<int>` and `vector<char>` in C++ are just two different copies of "
"the\n"
"same boilerplate code for a `vector` type (known as a `template`) with two\n"
"different types filled in."
msgstr ""
"Una parte clave de esta idea es la forma en que funcionan los tipos "
"genéricos. En C++ y Java, por\n"
"Por ejemplo, los tipos genéricos son una construcción de metaprogramación "
"para el compilador.\n"
"`vector<int>` y `vector<char>` en C++ son solo dos copias diferentes del\n"
"mismo código repetitivo para un tipo `vector` (conocido como `plantilla`) "
"con dos\n"
"diferentes tipos rellenados."
#: src\functional/generics-type-classes.md:17
#, fuzzy
msgid ""
"In Rust, a generic type parameter creates what is known in functional "
"languages\n"
"as a \"type class constraint\", and each different parameter filled in by an "
"end\n"
"user _actually changes the type_. In other words, `Vec<isize>` and "
"`Vec<char>`\n"
"_are two different types_, which are recognized as distinct by all parts of "
"the\n"
"type system."
msgstr ""
"En Rust, un parámetro de tipo genérico crea lo que se conoce en lenguajes "
"funcionales\n"
"como una \"restricción de clase de tipo\", y cada parámetro diferente "
"completado por un extremo\n"
"el usuario _realmente cambia el tipo_. En otras palabras, `Vec<isize>` y "
"`Vec<char>`\n"
"_son dos tipos diferentes_, que son reconocidos como distintos por todas las "
"partes del\n"
"sistema de tipos."
#: src\functional/generics-type-classes.md:23
#, fuzzy
msgid ""
"This is called **monomorphization**, where different types are created from\n"
"**polymorphic** code. This special behavior requires `impl` blocks to "
"specify\n"
"generic parameters. Different values for the generic type cause different "
"types,\n"
"and different types can have different `impl` blocks."
msgstr ""
"Esto se llama **monomorfización**, donde se crean diferentes tipos a partir "
"de\n"
"Código **polimórfico**. Este comportamiento especial requiere bloques `impl` "
"para especificar\n"
"parámetros genéricos. Diferentes valores para el tipo genérico causan "
"diferentes tipos,\n"
"y diferentes tipos pueden tener diferentes bloques `impl`."
#: src\functional/generics-type-classes.md:28
#, fuzzy
msgid ""
"In object-oriented languages, classes can inherit behavior from their "
"parents.\n"
"However, this allows the attachment of not only additional behavior to\n"
"particular members of a type class, but extra behavior as well."
msgstr ""
"En los lenguajes orientados a objetos, las clases pueden heredar el "
"comportamiento de sus padres.\n"
"Sin embargo, esto permite adjuntar no sólo un comportamiento adicional a\n"
"miembros particulares de una clase de tipo, pero también comportamiento "
"adicional."
#: src\functional/generics-type-classes.md:32
#, fuzzy
msgid ""
"The nearest equivalent is the runtime polymorphism in Javascript and "
"Python,\n"
"where new members can be added to objects willy-nilly by any constructor.\n"
"However, unlike those languages, all of Rust's additional methods can be "
"type\n"
"checked when they are used, because their generics are statically defined. "
"That\n"
"makes them more usable while remaining safe."
msgstr ""
"El equivalente más cercano es el polimorfismo en tiempo de ejecución en "
"Javascript y Python,\n"
"donde cualquier constructor puede agregar nuevos miembros a los objetos de "
"cualquier manera.\n"
"Sin embargo, a diferencia de esos lenguajes, todos los métodos adicionales "
"de Rust se pueden escribir\n"
"verificados cuando se usan, porque sus genéricos están definidos "
"estáticamente. Eso\n"
"los hace más utilizables sin dejar de ser seguros."
#: src\functional/generics-type-classes.md:40
#, fuzzy
msgid ""
"Suppose you are designing a storage server for a series of lab machines.\n"
"Because of the software involved, there are two different protocols you "
"need\n"
"to support: BOOTP (for PXE network boot), and NFS (for remote mount storage)."
msgstr ""
"Suponga que está diseñando un servidor de almacenamiento para una serie de "
"máquinas de laboratorio.\n"
"Debido al software involucrado, hay dos protocolos diferentes que necesita\n"
"para admitir: BOOTP (para arranque de red PXE) y NFS (para almacenamiento de "
"montaje remoto)."
#: src\functional/generics-type-classes.md:44
#, fuzzy
msgid ""
"Your goal is to have one program, written in Rust, which can handle both of\n"
"them. It will have protocol handlers and listen for both kinds of requests. "
"The\n"
"main application logic will then allow a lab administrator to configure "
"storage\n"
"and security controls for the actual files."
msgstr ""
"Su objetivo es tener un programa, escrito en Rust, que pueda manejar ambos\n"
"a ellos. Tendrá controladores de protocolo y escuchará ambos tipos de "
"solicitudes. El\n"
"La lógica de la aplicación principal permitirá que un administrador de "
"laboratorio configure el almacenamiento\n"
"y controles de seguridad para los archivos reales."
#: src\functional/generics-type-classes.md:49
#, fuzzy
msgid ""
"The requests from machines in the lab for files contain the same basic\n"
"information, no matter what protocol they came from: an authentication "
"method,\n"
"and a file name to retrieve. A straightforward implementation would look\n"
"something like this:"
msgstr ""
"Las solicitudes de archivos de las máquinas en el laboratorio contienen el "
"mismo\n"
"información, sin importar de qué protocolo provengan: un método de "
"autenticación,\n"
"y un nombre de archivo para recuperar. Una implementación sencilla se vería\n"
"algo como esto:"
#: src\functional/generics-type-classes.md:54
msgid ""
"```rust,ignore\n"
"enum AuthInfo {\n"
" Nfs(crate::nfs::AuthInfo),\n"
" Bootp(crate::bootp::AuthInfo),\n"
"}\n"
"\n"
"struct FileDownloadRequest {\n"
" file_name: PathBuf,\n"
" authentication: AuthInfo,\n"
"}\n"
"```"
msgstr ""
#: src\functional/generics-type-classes.md:66
#, fuzzy
msgid ""
"This design might work well enough. But now suppose you needed to support\n"
"adding metadata that was _protocol specific_. For example, with NFS, you\n"
"wanted to determine what their mount point was in order to enforce "
"additional\n"
"security rules."
msgstr ""
"Este diseño podría funcionar lo suficientemente bien. Pero ahora supongamos "
"que necesita apoyo\n"
"agregando metadatos que eran _específicos del protocolo_. Por ejemplo, con "
"NFS, usted\n"
"quería determinar cuál era su punto de montaje para hacer cumplir\n"
"reglas de seguridad"
#: src\functional/generics-type-classes.md:71
#, fuzzy
msgid ""
"The way the current struct is designed leaves the protocol decision until\n"
"runtime. That means any method that applies to one protocol and not the "
"other\n"
"requires the programmer to do a runtime check."
msgstr ""
"La forma en que está diseñada la estructura actual deja la decisión del "
"protocolo hasta\n"
"tiempo de ejecución Eso significa cualquier método que se aplique a un "
"protocolo y no al otro.\n"
"requiere que el programador haga una verificación de tiempo de ejecución."
#: src\functional/generics-type-classes.md:75
#, fuzzy
msgid "Here is how getting an NFS mount point would look:"
msgstr "Así es como se vería obtener un punto de montaje NFS:"
#: src\functional/generics-type-classes.md:77
msgid ""
"```rust,ignore\n"
"struct FileDownloadRequest {\n"
" file_name: PathBuf,\n"
" authentication: AuthInfo,\n"
" mount_point: Option<PathBuf>,\n"
"}\n"
"\n"
"impl FileDownloadRequest {\n"
" // ... other methods ...\n"
"\n"
" /// Gets an NFS mount point if this is an NFS request. Otherwise,\n"
" /// return None.\n"
" pub fn mount_point(&self) -> Option<&Path> {\n"
" self.mount_point.as_ref()\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\functional/generics-type-classes.md:95
#, fuzzy
msgid ""
"Every caller of `mount_point()` must check for `None` and write code to "
"handle\n"
"it. This is true even if they know only NFS requests are ever used in a "
"given\n"
"code path!"
msgstr ""
"Cada llamador de `mount_point()` debe buscar `Ninguno` y escribir código "
"para manejar\n"
"él. Esto es cierto incluso si saben que solo se usan solicitudes NFS en un "
"determinado\n"
"ruta de código!"
#: src\functional/generics-type-classes.md:99
#, fuzzy
msgid ""
"It would be far more optimal to cause a compile-time error if the different\n"
"request types were confused. After all, the entire path of the user's code,\n"
"including what functions from the library they use, will know whether a "
"request\n"
"is an NFS request or a BOOTP request."
msgstr ""
"Sería mucho más óptimo causar un error en tiempo de compilación si los "
"diferentes\n"
"los tipos de solicitud estaban confundidos. Después de todo, la ruta "
"completa del código del usuario,\n"
"incluidas las funciones de la biblioteca que utilizan, sabrán si una "
"solicitud\n"
"es una solicitud NFS o una solicitud BOOTP."
#: src\functional/generics-type-classes.md:104
#, fuzzy
msgid ""
"In Rust, this is actually possible! The solution is to _add a generic type_ "
"in\n"
"order to split the API."
msgstr ""
"¡En Rust, esto es realmente posible! La solución es _agregar un tipo "
"genérico_ en\n"
"para dividir la API."
#: src\functional/generics-type-classes.md:107
#, fuzzy
msgid "Here is what that looks like:"
msgstr "Esto es lo que parece:"
#: src\functional/generics-type-classes.md:109
msgid ""
"```rust\n"
"use std::path::{Path, PathBuf};\n"
"\n"
"mod nfs {\n"
" #[derive(Clone)]\n"
" pub(crate) struct AuthInfo(String); // NFS session management omitted\n"
"}\n"
"\n"
"mod bootp {\n"
" pub(crate) struct AuthInfo(); // no authentication in bootp\n"
"}\n"
"\n"
"// private module, lest outside users invent their own protocol kinds!\n"
"mod proto_trait {\n"
" use std::path::{Path, PathBuf};\n"
" use super::{bootp, nfs};\n"
"\n"
" pub(crate) trait ProtoKind {\n"
" type AuthInfo;\n"
" fn auth_info(&self) -> Self::AuthInfo;\n"
" }\n"
"\n"
" pub struct Nfs {\n"
" auth: nfs::AuthInfo,\n"
" mount_point: PathBuf,\n"
" }\n"
"\n"
" impl Nfs {\n"
" pub(crate) fn mount_point(&self) -> &Path {\n"
" &self.mount_point\n"
" }\n"
" }\n"
"\n"
" impl ProtoKind for Nfs {\n"
" type AuthInfo = nfs::AuthInfo;\n"
" fn auth_info(&self) -> Self::AuthInfo {\n"
" self.auth.clone()\n"
" }\n"
" }\n"
"\n"
" pub struct Bootp(); // no additional metadata\n"
"\n"
" impl ProtoKind for Bootp {\n"
" type AuthInfo = bootp::AuthInfo;\n"
" fn auth_info(&self) -> Self::AuthInfo {\n"
" bootp::AuthInfo()\n"
" }\n"
" }\n"
"}\n"
"\n"
"use proto_trait::ProtoKind; // keep internal to prevent impls\n"
"pub use proto_trait::{Nfs, Bootp}; // re-export so callers can see them\n"
"\n"
"struct FileDownloadRequest<P: ProtoKind> {\n"
" file_name: PathBuf,\n"
" protocol: P,\n"
"}\n"
"\n"
"// all common API parts go into a generic impl block\n"
"impl<P: ProtoKind> FileDownloadRequest<P> {\n"
" fn file_path(&self) -> &Path {\n"
" &self.file_name\n"
" }\n"
"\n"
" fn auth_info(&self) -> P::AuthInfo {\n"
" self.protocol.auth_info()\n"
" }\n"
"}\n"
"\n"
"// all protocol-specific impls go into their own block\n"
"impl FileDownloadRequest<Nfs> {\n"
" fn mount_point(&self) -> &Path {\n"
" self.protocol.mount_point()\n"
" }\n"
"}\n"
"\n"
"fn main() {\n"
" // your code here\n"
"}\n"
"```"
msgstr ""
#: src\functional/generics-type-classes.md:190
msgid ""
"With this approach, if the user were to make a mistake and use the wrong\n"
"type;"
msgstr ""
#: src\functional/generics-type-classes.md:193
msgid ""
"```rust,ignore\n"
"fn main() {\n"
" let mut socket = crate::bootp::listen()?;\n"
" while let Some(request) = socket.next_request()? {\n"
" match request.mount_point().as_ref()\n"
" \"/secure\" => socket.send(\"Access denied\"),\n"
" _ => {} // continue on...\n"
" }\n"
" // Rest of the code here\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src\functional/generics-type-classes.md:206
#, fuzzy
msgid ""
"They would get a syntax error. The type `FileDownloadRequest<Bootp>` does "
"not\n"
"implement `mount_point()`, only the type `FileDownloadRequest<Nfs>` does. "
"And\n"
"that is created by the NFS module, not the BOOTP module of course!"
msgstr ""
"Obtendrían un error de sintaxis. El tipo `FileDownloadRequest<Bootp>` no\n"
"implementa `mount_point()`, solo lo hace el tipo `FileDownloadRequest<Nfs>`. "
"Y\n"
"eso lo crea el módulo NFS, ¡no el módulo BOOTP, por supuesto!"
#: src\functional/generics-type-classes.md:212
#, fuzzy
msgid ""
"First, it allows fields that are common to multiple states to be "
"de-duplicated.\n"
"By making the non-shared fields generic, they are implemented once."
msgstr ""
"En primer lugar, permite eliminar la duplicación de campos que son comunes a "
"varios estados.\n"
"Al hacer que los campos no compartidos sean genéricos, se implementan una "
"vez."
#: src\functional/generics-type-classes.md:215
#, fuzzy
msgid ""
"Second, it makes the `impl` blocks easier to read, because they are broken "
"down\n"
"by state. Methods common to all states are typed once in one block, and "
"methods\n"
"unique to one state are in a separate block."
msgstr ""
"En segundo lugar, hace que los bloques `impl` sean más fáciles de leer, "
"porque están desglosados\n"
"por estado Los métodos comunes a todos los estados se escriben una vez en un "
"bloque y los métodos\n"
"exclusivos de un estado están en un bloque separado."
#: src\functional/generics-type-classes.md:219
#, fuzzy
msgid ""
"Both of these mean there are fewer lines of code, and they are better "
"organized."
msgstr ""
"Ambos significan que hay menos líneas de código y están mejor organizados."
#: src\functional/generics-type-classes.md:223
#, fuzzy
msgid ""
"This currently increases the size of the binary, due to the way "
"monomorphization\n"
"is implemented in the compiler. Hopefully the implementation will be able "
"to\n"
"improve in the future."
msgstr ""
"Esto actualmente aumenta el tamaño del binario, debido a la forma en que se "
"monomorfiza.\n"
"se implementa en el compilador. Esperemos que la implementación pueda\n"
"mejorar en el futuro."
#: src\functional/generics-type-classes.md:229
#, fuzzy
msgid ""
"- If a type seems to need a \"split API\" due to construction or partial\n"
" initialization, consider the\n"
" [Builder Pattern](../patterns/creational/builder.md) instead.\n"
"\n"
"- If the API between types does not change -- only the behavior does -- "
"then\n"
" the [Strategy Pattern](../patterns/behavioural/strategy.md) is better "
"used\n"
" instead."
msgstr ""
"- Si un tipo parece necesitar una \"API dividida\" debido a la construcción "
"o parcial\n"
" inicialización, considere la\n"
" [Patrón de constructor] (../patterns/creational/builder.md) en su lugar.\n"
"\n"
"- Si la API entre tipos no cambia, solo cambia el comportamiento, entonces\n"
" el [Patrón de estrategia] (../patterns/behavioural/strategy.md) se usa "
"mejor\n"
" en cambio."
#: src\functional/generics-type-classes.md:239
#, fuzzy
msgid "This pattern is used throughout the standard library:"
msgstr "Este patrón se utiliza en toda la biblioteca estándar:"
#: src\functional/generics-type-classes.md:241
#, fuzzy
msgid ""
"- `Vec<u8>` can be cast from a String, unlike every other type of "
"`Vec<T>`.[^1]\n"
"- They can also be cast into a binary heap, but only if they contain a type\n"
" that implements the `Ord` trait.[^2]\n"
"- The `to_string` method was specialized for `Cow` only of type `str`.[^3]"
msgstr ""
"- `Vec<u8>` se puede convertir desde una cadena, a diferencia de cualquier "
"otro tipo de `Vec<T>`.[^1]\n"
"- También se pueden convertir en un montón binario, pero solo si contienen "
"un tipo\n"
" que implementa el rasgo `Ord`.[^2]\n"
"- El método `to_string` se especializó para `Vaca` solo del tipo `str`.[^3]"
#: src\functional/generics-type-classes.md:246
#, fuzzy
msgid "It is also used by several popular crates to allow API flexibility:"
msgstr ""
"También lo utilizan varias cajas populares para permitir la flexibilidad de "
"la API:"
#: src\functional/generics-type-classes.md:248
#, fuzzy
msgid ""
"- The `embedded-hal` ecosystem used for embedded devices makes extensive use "
"of\n"
" this pattern. For example, it allows statically verifying the "
"configuration of\n"
" device registers used to control embedded pins. When a pin is put into a "
"mode,\n"
" it returns a `Pin<MODE>` struct, whose generic determines the functions\n"
" usable in that mode, which are not on the `Pin` itself. [^4]\n"
"\n"
"- The `hyper` HTTP client library uses this to expose rich APIs for "
"different\n"
" pluggable requests. Clients with different connectors have different "
"methods\n"
" on them as well as different trait implementations, while a core set of\n"
" methods apply to any connector. [^5]\n"
"\n"
"- The \"type state\" pattern -- where an object gains and loses API based on "
"an\n"
" internal state or invariant -- is implemented in Rust using the same "
"basic\n"
" concept, and a slightly different technique. [^6]"
msgstr ""
"- El ecosistema `embedded-hal` utilizado para dispositivos integrados hace "
"un uso extensivo de\n"
" este patrón Por ejemplo, permite verificar estáticamente la configuración "
"de\n"
" registros de dispositivos utilizados para controlar pines incrustados. "
"Cuando un pin se pone en un modo,\n"
" devuelve una estructura `Pin<MODE>`, cuyo genérico determina las "
"funciones\n"
" utilizables en ese modo, que no están en el propio `Pin`. [^4]\n"
"\n"
"- La biblioteca de cliente HTTP 'hiper' usa esto para exponer API "
"enriquecidas para diferentes\n"
" solicitudes conectables. Los clientes con diferentes conectores tienen "
"diferentes métodos\n"
" en ellos, así como diferentes implementaciones de rasgos, mientras que un "
"conjunto básico de\n"
" Los métodos se aplican a cualquier conector. [^5]\n"
"\n"
"- El patrón de \"estado de tipo\", donde un objeto gana y pierde API en "
"función de un\n"
" estado interno o invariante: se implementa en Rust utilizando el mismo\n"
" concepto, y una técnica ligeramente diferente. [^6]"
#: src\functional/generics-type-classes.md:263
#, fuzzy
msgid ""
"See: [impl From\\<CString\\> for "
"Vec\\<u8\\>](https://doc.rust-lang.org/1.59.0/src/std/ffi/c_str.rs.html#803-811)"
msgstr ""
"Ver: [impl From\\<CString\\> for "
"Vec\\<u8\\>](https://doc.rust-lang.org/1.59.0/src/std/ffi/c_str.rs.html#803-811 "
")"
#: src\functional/generics-type-classes.md:265
#, fuzzy
msgid ""
"See: [impl\\<T\\> From\\<Vec\\<T, Global\\>\\> for "
"BinaryHeap\\<T\\>](https://doc.rust-lang.org/stable/src/alloc/collections/binary_heap.rs.html#1345-1354)"
msgstr ""
"Ver: [impl\\<T\\> From\\<Vec\\<T, Global\\>\\> for "
"BinaryHeap\\<T\\>](https://doc.rust-lang.org/stable/src/alloc/collections "
"/binary_heap.rs.html#1345-1354)"
#: src\functional/generics-type-classes.md:267
#, fuzzy
msgid ""
"See: [impl\\<'\\_\\> ToString for Cow\\<'\\_, "
"str>](https://doc.rust-lang.org/stable/src/alloc/string.rs.html#2235-2240)"
msgstr ""
"Consulte: [impl\\<'\\_\\> ToString for Cow\\<'\\_, "
"str>](https://doc.rust-lang.org/stable/src/alloc/string.rs.html#2235- 2240)"
#: src\functional/generics-type-classes.md:269
#, fuzzy
msgid ""
"Example:\n"
"[https://docs.rs/stm32f30x-hal/0.1.0/stm32f30x_hal/gpio/gpioa/struct.PA0.html](https://docs.rs/stm32f30x-hal/0.1.0/stm32f30x_hal/gpio/gpioa/struct.PA0.html)"
msgstr ""
"Ejemplo:\n"
"[https://docs.rs/stm32f30x-hal/0.1.0/stm32f30x_hal/gpio/gpioa/struct.PA0.html](https://docs.rs/stm32f30x-hal/0.1.0/stm32f30x_hal/gpio/ "
"gpioa/struct.PA0.html)"
#: src\functional/generics-type-classes.md:272
#, fuzzy
msgid ""
"See:\n"
"[https://docs.rs/hyper/0.14.5/hyper/client/struct.Client.html](https://docs.rs/hyper/0.14.5/hyper/client/struct.Client.html)"
msgstr ""
"Ver:\n"
"[https://docs.rs/hyper/0.14.5/hyper/client/struct.Client.html](https://docs.rs/hyper/0.14.5/hyper/client/struct.Client.html)"
#: src\functional/generics-type-classes.md:275
#, fuzzy
msgid ""
"See:\n"
"[The Case for the Type State "
"Pattern](https://web.archive.org/web/20210325065112/https://www.novatec-gmbh.de/en/blog/the-case-for-the-typestate-pattern-the-typestate-pattern-itself/)\n"
"and\n"
"[Rusty Typestate Series (an extensive "
"thesis)](https://web.archive.org/web/20210328164854/https://rustype.github.io/notes/notes/rust-typestate-series/rust-typestate-index)"
msgstr ""
"Ver:\n"
"[El caso del patrón de estado "
"tipo](https://web.archive.org/web/20210325065112/https://www.novatec-gmbh.de/en/blog/the-case-for-the-typestate- "
"patrón-el-tipo-estado-patrón-en-sí/)\n"
"y\n"
"[Serie Rusty Typestate (una tesis "
"extensa)](https://web.archive.org/web/20210328164854/https://rustype.github.io/notes/notes/rust-typestate-series/rust-typestate-index "
")"
#: src\functional/lenses.md:1
#, fuzzy
msgid "# Lenses and Prisms"
msgstr "# Lentes y Prismas"
#: src\functional/lenses.md:3
#, fuzzy
msgid ""
"This is a pure functional concept that is not frequently used in Rust.\n"
"Nevertheless, exploring the concept may be helpful to understand other\n"
"patterns in Rust APIs, such as "
"[visitors](../patterns/behavioural/visitor.md).\n"
"They also have niche use cases."
msgstr ""
"Este es un concepto funcional puro que no se usa con frecuencia en Rust.\n"
"Sin embargo, explorar el concepto puede ser útil para entender otros\n"
"patrones en las API de Rust, como [visitantes] "
"(../patterns/behavioural/visitor.md).\n"
"También tienen casos de uso de nicho."
#: src\functional/lenses.md:8
#, fuzzy
msgid "## Lenses: Uniform Access Across Types"
msgstr "## Lentes: acceso uniforme en todos los tipos"
#: src\functional/lenses.md:10
#, fuzzy
msgid ""
"A lens is a concept from functional programming languages that allows\n"
"accessing parts of a data type in an abstract, unified way.[^1]\n"
"In basic concept, it is similar to the way Rust traits work with type "
"erasure,\n"
"but it has a bit more power and flexibility."
msgstr ""
"Una lente es un concepto de los lenguajes de programación funcional que "
"permite\n"
"acceder a partes de un tipo de datos de forma abstracta y unificada.[^1]\n"
"En concepto básico, es similar a la forma en que los rasgos de Rust "
"funcionan con el borrado de tipos,\n"
"pero tiene un poco más de potencia y flexibilidad."
#: src\functional/lenses.md:15
#, fuzzy
msgid ""
"For example, suppose a bank contains several JSON formats for customer\n"
"data.\n"
"This is because they come from different databases or legacy systems.\n"
"One database contains the data needed to perform credit checks:"
msgstr ""
"Por ejemplo, suponga que un banco contiene varios formatos JSON para "
"clientes\n"
"datos.\n"
"Esto se debe a que provienen de diferentes bases de datos o sistemas "
"heredados.\n"
"Una base de datos contiene los datos necesarios para realizar verificaciones "
"de crédito:"
#: src\functional/lenses.md:20
msgid ""
"```json\n"
"{ \"name\": \"Jane Doe\",\n"
" \"dob\": \"2002-02-24\",\n"
" [...]\n"
" \"customer_id\": 1048576332,\n"
"}\n"
"```"
msgstr ""
#: src\functional/lenses.md:28
#, fuzzy
msgid "Another one contains the account information:"
msgstr "Otro contiene la información de la cuenta:"
#: src\functional/lenses.md:30
msgid ""
"```json\n"
"{ \"customer_id\": 1048576332,\n"
" \"accounts\": [\n"
" { \"account_id\": 2121,\n"
" \"account_type: \"savings\",\n"
" \"joint_customer_ids\": [],\n"
" [...]\n"
" },\n"
" { \"account_id\": 2122,\n"
" \"account_type: \"checking\",\n"
" \"joint_customer_ids\": [1048576333],\n"
" [...]\n"
" },\n"
" ]\n"
"}\n"
"```"
msgstr ""
#: src\functional/lenses.md:47
#, fuzzy
msgid ""
"Notice that both types have a customer ID number which corresponds to a "
"person.\n"
"How would a single function handle both records of different types?"
msgstr ""
"Tenga en cuenta que ambos tipos tienen un número de identificación de "
"cliente que corresponde a una persona.\n"
"¿Cómo manejaría una sola función ambos registros de diferentes tipos?"
#: src\functional/lenses.md:50
#, fuzzy
msgid ""
"In Rust, a `struct` could represent each of these types, and a trait would "
"have\n"
"a `get_customer_id` function they would implement:"
msgstr ""
"En Rust, una `estructura` podría representar cada uno de estos tipos, y un "
"rasgo tendría\n"
"una función `get_customer_id` que implementarían:"
#: src\functional/lenses.md:53
msgid ""
"```rust\n"
"use std::collections::HashSet;\n"
"\n"
"pub struct Account {\n"
" account_id: u32,\n"
" account_type: String,\n"
" // other fields omitted\n"
"}\n"
"\n"
"pub trait CustomerId {\n"
" fn get_customer_id(&self) -> u64;\n"
"}\n"
"\n"
"pub struct CreditRecord {\n"
" customer_id: u64,\n"
" name: String,\n"
" dob: String,\n"
" // other fields omitted\n"
"}\n"
"\n"
"impl CustomerId for CreditRecord {\n"
" fn get_customer_id(&self) -> u64 {\n"
" self.customer_id\n"
" }\n"
"}\n"
"\n"
"pub struct AccountRecord {\n"
" customer_id: u64,\n"
" accounts: Vec<Account>,\n"
"}\n"
"\n"
"impl CustomerId for AccountRecord {\n"
" fn get_customer_id(&self) -> u64 {\n"
" self.customer_id\n"
" }\n"
"}\n"
"\n"
"// static polymorphism: only one type, but each function call can choose it\n"
"fn unique_ids_set<R: CustomerId>(records: &[R]) -> HashSet<u64> {\n"
" records.iter().map(|r| r.get_customer_id()).collect()\n"
"}\n"
"\n"
"// dynamic dispatch: iterates over any type with a customer ID, collecting "
"all\n"
"// values together\n"
"fn unique_ids_iter<I>(iterator: I) -> HashSet<u64>\n"
" where I: Iterator<Item=Box<dyn CustomerId>>\n"
"{\n"
" iterator.map(|r| r.as_ref().get_customer_id()).collect()\n"
"}\n"
"```"
msgstr ""
#: src\functional/lenses.md:104
#, fuzzy
msgid ""
"Lenses, however, allow the code supporting customer ID to be moved from the\n"
"_type_ to the _accessor function_.\n"
"Rather than implementing a trait on each type, all matching structures can\n"
"simply be accessed the same way."
msgstr ""
"Sin embargo, las lentes permiten que el código que respalda la "
"identificación del cliente se mueva de la\n"
"_type_ a la _función de acceso_.\n"
"En lugar de implementar un rasgo en cada tipo, todas las estructuras "
"coincidentes pueden\n"
"simplemente se puede acceder de la misma manera."
#: src\functional/lenses.md:109
#, fuzzy
msgid ""
"While the Rust language itself does not support this (type erasure is the\n"
"preferred solution to this problem), the [lens-rs "
"crate](https://github.com/TOETOE55/lens-rs/blob/master/guide.md) allows "
"code\n"
"that feels like this to be written with macros:"
msgstr ""
"Si bien el lenguaje Rust en sí mismo no admite esto (el borrado de tipo es "
"el\n"
"solución preferida para este problema), [lens-rs "
"crate](https://github.com/TOETOE55/lens-rs/blob/master/guide.md) permite "
"código\n"
"que se siente así para ser escrito con macros:"
#: src\functional/lenses.md:113
msgid ""
"```rust,ignore\n"
"use std::collections::HashSet;\n"
"\n"
"use lens_rs::{optics, Lens, LensRef, Optics};\n"
"\n"
"#[derive(Clone, Debug, Lens /* derive to allow lenses to work */)]\n"
"pub struct CreditRecord {\n"
" #[optic(ref)] // macro attribute to allow viewing this field\n"
" customer_id: u64,\n"
" name: String,\n"
" dob: String,\n"
" // other fields omitted\n"
"}\n"
"\n"
"#[derive(Clone, Debug)]\n"
"pub struct Account {\n"
" account_id: u32,\n"
" account_type: String,\n"
" // other fields omitted\n"
"}\n"
"\n"
"#[derive(Clone, Debug, Lens)]\n"
"pub struct AccountRecord {\n"
" #[optic(ref)]\n"
" customer_id: u64,\n"
" accounts: Vec<Account>,\n"
"}\n"
"\n"
"fn unique_ids_lens<T>(iter: impl Iterator<Item = T>) -> HashSet<u64>\n"
"where\n"
" T: LensRef<Optics![customer_id], u64>, // any type with this field\n"
"{\n"
" iter.map(|r| *r.view_ref(optics!(customer_id))).collect()\n"
"}\n"
"```"
msgstr ""
#: src\functional/lenses.md:149
#, fuzzy
msgid ""
"The version of `unique_ids_lens` shown here allows any type to be in the "
"iterator,\n"
"so long as it has an attribute called `customer_id` which can be accessed "
"by\n"
"the function.\n"
"This is how most functional programming languages operate on lenses."
msgstr ""
"La versión de `unique_ids_lens` que se muestra aquí permite que cualquier "
"tipo esté en el iterador,\n"
"siempre que tenga un atributo llamado `customer_id` al que se pueda acceder "
"mediante\n"
"la función.\n"
"Así es como la mayoría de los lenguajes de programación funcionales operan "
"en lentes."
#: src\functional/lenses.md:154
#, fuzzy
msgid ""
"Rather than macros, they achieve this with a technique known as "
"\"currying\".\n"
"That is, they \"partially construct\" the function, leaving the type of the\n"
"final parameter (the value being operated on) unfilled until the function "
"is\n"
"called.\n"
"Thus it can be called with different types dynamically even from one place "
"in\n"
"the code.\n"
"That is what the `optics!` and `view_ref` in the example above simulates."
msgstr ""
"En lugar de macros, lo logran con una técnica conocida como \"curring\".\n"
"Es decir, \"construyen parcialmente\" la función, dejando el tipo de la\n"
"parámetro final (el valor que se está operando) sin completar hasta que la "
"función es\n"
"llamado.\n"
"Por lo tanto, se puede llamar con diferentes tipos dinámicamente incluso "
"desde un lugar en\n"
"el código.\n"
"Eso es lo que simula `optics!` y `view_ref` en el ejemplo anterior."
#: src\functional/lenses.md:162
#, fuzzy
msgid ""
"The functional approach need not be restricted to accessing members.\n"
"More powerful lenses can be created which both _set_ and _get_ data in a\n"
"structure.\n"
"But the concept really becomes interesting when used as a building block "
"for\n"
"composition.\n"
"That is where the concept appears more clearly in Rust."
msgstr ""
"El enfoque funcional no tiene por qué limitarse a los miembros de acceso.\n"
"Se pueden crear lentes más potentes que _configuran_ y _obtienen_ datos en "
"un\n"
"estructura.\n"
"Pero el concepto realmente se vuelve interesante cuando se usa como un "
"bloque de construcción para\n"
"composición.\n"
"Ahí es donde aparece más claro el concepto en Rust."
#: src\functional/lenses.md:169
#, fuzzy
msgid "## Prisms: A Higher-Order form of \"Optics\""
msgstr "## Prismas: una forma de \"óptica\" de orden superior"
#: src\functional/lenses.md:171
#, fuzzy
msgid ""
"A simple function such as `unique_ids_lens` above operates on a single "
"lens.\n"
"A _prism_ is a function that operates on a _family_ of lenses.\n"
"It is one conceptual level higher, using lenses as a building block, and\n"
"continuing the metaphor, is part of a family of \"optics\".\n"
"It is the main one that is useful in understanding Rust APIs, so will be "
"the\n"
"focus here."
msgstr ""
"Una función simple como `unique_ids_lens` anterior opera en una sola lente.\n"
"Un _prisma_ es una función que opera en una _familia_ de lentes.\n"
"Es un nivel conceptual más alto, usando lentes como bloque de construcción, "
"y\n"
"continuando con la metáfora, forma parte de una familia de \"ópticas\".\n"
"Es el principal que es útil para comprender las API de Rust, por lo que será "
"el\n"
"enfócate aquí."
#: src\functional/lenses.md:178
#, fuzzy
msgid ""
"The same way that traits allow \"lens-like\" design with static polymorphism "
"and\n"
"dynamic dispatch, prism-like designs appear in Rust APIs which split "
"problems\n"
"into multiple associated types to be composed.\n"
"A good example of this is the traits in the parsing crate _Serde_."
msgstr ""
"De la misma manera que los rasgos permiten un diseño \"similar a una lente\" "
"con polimorfismo estático y\n"
"envío dinámico, los diseños de prisma aparecen en las API de Rust que "
"dividen los problemas\n"
"en múltiples tipos asociados para ser compuestos.\n"
"Un buen ejemplo de esto son los rasgos en la caja de análisis _Serde_."
#: src\functional/lenses.md:183
#, fuzzy
msgid ""
"Trying to understand the way _Serde_ works by only reading the API is a\n"
"challenge, especially the first time.\n"
"Consider the `Deserializer` trait, implemented by some type in any library\n"
"which parses a new format:"
msgstr ""
"Tratar de entender la forma en que funciona _Serde_ solo leyendo la API es "
"un\n"
"desafío, especialmente la primera vez.\n"
"Considere el rasgo `Deserializer`, implementado por algún tipo en cualquier "
"biblioteca\n"
"que analiza un nuevo formato:"
#: src\functional/lenses.md:188
msgid ""
"```rust,ignore\n"
"pub trait Deserializer<'de>: Sized {\n"
" type Error: Error;\n"
"\n"
" fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, "
"Self::Error>\n"
" where\n"
" V: Visitor<'de>;\n"
"\n"
" fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, "
"Self::Error>\n"
" where\n"
" V: Visitor<'de>;\n"
"\n"
" // remainder ommitted\n"
"}\n"
"```"
msgstr ""
#: src\functional/lenses.md:204
#, fuzzy
msgid ""
"For a trait that is just supposed to parse data from a format and return a\n"
"value, this looks odd."
msgstr ""
"Para un rasgo que se supone que analiza datos de un formato y devuelve un\n"
"valor, esto parece extraño."
#: src\functional/lenses.md:207
#, fuzzy
msgid "Why are all the return types type erased?"
msgstr "¿Por qué se borran todos los tipos de devolución?"
#: src\functional/lenses.md:209
#, fuzzy
msgid ""
"To understand that, we need to keep the lens concept in mind and look at\n"
"the definition of the `Visitor` type that is passed in generically:"
msgstr ""
"Para entender eso, necesitamos tener en mente el concepto de lente y "
"observar\n"
"la definición del tipo `Visitor` que se pasa genéricamente:"
#: src\functional/lenses.md:212
msgid ""
"```rust,ignore\n"
"pub trait Visitor<'de>: Sized {\n"
" type Value;\n"
"\n"
" fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>\n"
" where\n"
" E: Error;\n"
"\n"
" fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>\n"
" where\n"
" E: Error;\n"
"\n"
" fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>\n"
" where\n"
" E: Error;\n"
"\n"
" // remainder omitted\n"
"}\n"
"```"
msgstr ""
#: src\functional/lenses.md:232
#, fuzzy
msgid ""
"The job of the `Visitor` type is to construct values in the _Serde_ data "
"model,\n"
"which are represented by its associated `Value` type."
msgstr ""
"El trabajo del tipo `Visitor` es construir valores en el modelo de datos "
"_Serde_,\n"
"que están representados por su tipo `Valor` asociado."
#: src\functional/lenses.md:235
#, fuzzy
msgid ""
"These values represent parts of the Rust value being deserialized.\n"
"If this fails, it returns an `Error` type - an error type determined by the\n"
"`Deserializer` when its methods were called."
msgstr ""
"Estos valores representan partes del valor de Rust que se está "
"deserializando.\n"
"Si esto falla, devuelve un tipo `Error` - un tipo de error determinado por "
"el\n"
"`Deserializer` cuando se llamaron sus métodos."
#: src\functional/lenses.md:239
#, fuzzy
msgid ""
"This highlights that `Deserializer` is similar to `CustomerId` from "
"earlier,\n"
"allowing any format parser which implements it to create `Value`s based on "
"what\n"
"it parsed.\n"
"The `Value` trait is acting like a lens in functional programming languages."
msgstr ""
"Esto resalta que `Deserializer` es similar a `CustomerId` anterior,\n"
"permitiendo que cualquier analizador de formato que lo implemente cree "
"'Valores' basados en lo que\n"
"analizó.\n"
"El rasgo `Valor` está actuando como una lente en los lenguajes de "
"programación funcionales."
#: src\functional/lenses.md:244
#, fuzzy
msgid ""
"But unlike the `CustomerId` trait, the return types of `Visitor` methods "
"are\n"
"_generic_, and the concrete `Value` type is _determined by the Visitor "
"itself_."
msgstr ""
"Pero a diferencia del rasgo `CustomerId`, los tipos de retorno de los "
"métodos `Visitor` son\n"
"_genérico_, y el tipo de `Valor` concreto es _determinado por el propio "
"Visitante_."
#: src\functional/lenses.md:247
#, fuzzy
msgid ""
"Instead of acting as one lens, it effectively acts as a family of\n"
"lenses, one for each concrete type of `Visitor`."
msgstr ""
"En lugar de actuar como una sola lente, actúa efectivamente como una familia "
"de\n"
"lentes, uno para cada tipo concreto de 'Visitante'."
#: src\functional/lenses.md:250
#, fuzzy
msgid ""
"The `Deserializer` API is based on having a generic set of \"lenses\" work "
"across\n"
"a set of other generic types for \"observation\".\n"
"It is a _prism_."
msgstr ""
"La API `Deserializer` se basa en tener un conjunto genérico de \"lentes\" "
"que funcionan en\n"
"un conjunto de otros tipos genéricos para \"observación\".\n"
"Es un _prisma_."
#: src\functional/lenses.md:254
#, fuzzy
msgid "For example, consider the identity record from earlier but simplified:"
msgstr ""
"Por ejemplo, considere el registro de identidad anterior pero simplificado:"
#: src\functional/lenses.md:256
msgid ""
"```json\n"
"{ \"name\": \"Jane Doe\",\n"
" \"customer_id\": 1048576332,\n"
"}\n"
"```"
msgstr ""
#: src\functional/lenses.md:262
#, fuzzy
msgid ""
"How would the _Serde_ library deserialize this JSON into `struct "
"CreditRecord`?"
msgstr ""
"¿Cómo deserializaría la biblioteca _Serde_ este JSON en `struct "
"CreditRecord`?"
#: src\functional/lenses.md:264
#, fuzzy
msgid ""
"1. The user would call a library function to deserialize the data. This "
"would\n"
" create a `Deserializer` based on the JSON format.\n"
"1. Based on the fields in the struct, a `Visitor` would be created (more on\n"
" that in a moment) which knows how to create each type in a generic data\n"
" model that was needed to represent it: `u64` and `String`.\n"
"1. The deserializer would make calls to the `Visitor` as it parsed items.\n"
"1. The `Visitor` would indicate if the items found were expected, and if "
"not,\n"
" raise an error to indicate deserialization has failed."
msgstr ""
"1. El usuario llamaría a una función de biblioteca para deserializar los "
"datos. Esto sería\n"
" cree un `Deserializador` basado en el formato JSON.\n"
"1. Según los campos de la estructura, se crearía un 'Visitante' (más sobre\n"
" eso en un momento) que sabe cómo crear cada tipo en un data genérico\n"
" modelo que se necesitaba para representarlo: `u64` y `String`.\n"
"1. El deserializador haría llamadas al `Visitor` mientras analizaba los "
"elementos.\n"
"1. El `Visitante` indicaría si los artículos encontrados eran los esperados, "
"y si no,\n"
" genera un error para indicar que la deserialización ha fallado."
#: src\functional/lenses.md:273
#, fuzzy
msgid "For our very simple structure above, the expected pattern would be:"
msgstr "Para nuestra estructura muy simple anterior, el patrón esperado sería:"
#: src\functional/lenses.md:275
#, fuzzy
msgid ""
"1. Visit a map (_Serde_'s equvialent to `HashMap` or JSON's dictionary).\n"
"1. Visit a string key called \"name\".\n"
"1. Visit a string value, which will go into the `name` field.\n"
"1. Visit a string key called \"customer_id\".\n"
"1. Visit a string value, which will go into the `customer_id` field.\n"
"1. Visit the end of the map."
msgstr ""
"1. Visitar un mapa (equivalente de _Serde_ a `HashMap` o diccionario de "
"JSON).\n"
"1. Visite una clave de cadena llamada \"nombre\".\n"
"1. Visite un valor de cadena, que irá al campo `nombre`.\n"
"1. Visite una clave de cadena llamada \"customer_id\".\n"
"1. Visite un valor de cadena, que irá al campo `customer_id`.\n"
"1. Visita el final del mapa."
#: src\functional/lenses.md:282
#, fuzzy
msgid "But what determines which \"observation\" pattern is expected?"
msgstr "Pero, ¿qué determina qué patrón de \"observación\" se espera?"
#: src\functional/lenses.md:284
#, fuzzy
msgid ""
"A functional programming language would be able to use currying to create\n"
"reflection of each type based on the type itself.\n"
"Rust does not support that, so every single type would need to have its own\n"
"code written based on its fields and their properties."
msgstr ""
"Un lenguaje de programación funcional sería capaz de usar curry para crear\n"
"reflejo de cada tipo basado en el tipo mismo.\n"
"Rust no admite eso, por lo que cada tipo debería tener su propio\n"
"código escrito en base a sus campos y sus propiedades."
#: src\functional/lenses.md:289
#, fuzzy
msgid "_Serde_ solves this usability challenge with a derive macro:"
msgstr "_Serde_ resuelve este desafío de usabilidad con una macro derivada:"
#: src\functional/lenses.md:291
msgid ""
"```rust,ignore\n"
"use serde::Deserialize;\n"
"\n"
"#[derive(Deserialize)]\n"
"struct IdRecord {\n"
" name: String,\n"
" customer_id: String,\n"
"}\n"
"```"
msgstr ""
#: src\functional/lenses.md:301
#, fuzzy
msgid ""
"That macro simply generates an impl block causing the struct to implement a\n"
"trait called `Deserialize`."
msgstr ""
"Esa macro simplemente genera un bloque impl que hace que la estructura "
"implemente un\n"
"rasgo llamado `Deserializar`."
#: src\functional/lenses.md:304
#, fuzzy
msgid "It is defined this way:"
msgstr "Se define de esta manera:"
#: src\functional/lenses.md:306
msgid ""
"```rust,ignore\n"
"pub trait Deserialize<'de>: Sized {\n"
" fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n"
" where\n"
" D: Deserializer<'de>;\n"
"}\n"
"```"
msgstr ""
#: src\functional/lenses.md:314
#, fuzzy
msgid ""
"This is the function that determines how to create the struct itself.\n"
"Code is generated based on the struct's fields.\n"
"When the parsing library is called - in our example, a JSON parsing library "
"-\n"
"it creates a `Deserializer` and calls `Type::deserialize` with it as a\n"
"parameter."
msgstr ""
"Esta es la función que determina cómo crear la estructura en sí.\n"
"El código se genera en función de los campos de la estructura.\n"
"Cuando se llama a la biblioteca de análisis, en nuestro ejemplo, una "
"biblioteca de análisis JSON,\n"
"crea un 'Deserializer' y llama a 'Type::deserialize' con él como un\n"
"parámetro."
#: src\functional/lenses.md:320
#, fuzzy
msgid ""
"The `deserialize` code will then create a `Visitor` which will have its "
"calls\n"
"\"refracted\" by the `Deserializer`.\n"
"If everything goes well, eventually that `Visitor` will construct a value\n"
"corresponding to the type being parsed and return it."
msgstr ""
"El código `deserialize` creará un `Visitor` que tendrá sus llamadas\n"
"\"refractado\" por el `Deserializador`.\n"
"Si todo va bien, eventualmente ese 'Visitante' construirá un valor\n"
"correspondiente al tipo que se está analizando y devolverlo."
#: src\functional/lenses.md:325
#, fuzzy
msgid ""
"For a complete example, see the [_Serde_ "
"documentation](https://serde.rs/deserialize-struct.html)."
msgstr ""
"Para ver un ejemplo completo, consulte la "
"[documentación_Serde_](https://serde.rs/deserialize-struct.html)."
#: src\functional/lenses.md:327
#, fuzzy
msgid "To wrap up, this is the power of _Serde_:"
msgstr "Para terminar, este es el poder de _Serde_:"
#: src\functional/lenses.md:329
#, fuzzy
msgid ""
"1. The structure being parsed is represented by an `impl` block for "
"`Deserialize`\n"
"1. The input data format (e.g. JSON) is represented by a `Deserializer` "
"called\n"
" by `Deserialize`\n"
"1. The `Deserializer` acts like a prism which \"refracts\" lens-like "
"`Visitor`\n"
" calls which actually build the data value"
msgstr ""
"1. La estructura que se analiza está representada por un bloque `impl` para "
"`Deserialize`\n"
"1. El formato de datos de entrada (por ejemplo, JSON) está representado por "
"un `Deserializador` llamado\n"
" por `Deserializar`\n"
"1. El 'Deserializador' actúa como un prisma que \"refracta\" al 'Visitor' "
"similar a una lente\n"
" llamadas que realmente construyen el valor de los datos"
#: src\functional/lenses.md:335
#, fuzzy
msgid ""
"The result is that types to be deserialized only implement the \"top layer\" "
"of\n"
"the API, and file formats only need to implement the \"bottom layer\".\n"
"Each piece can then \"just work\" with the rest of the ecosystem, since "
"generic\n"
"types will bridge them."
msgstr ""
"El resultado es que los tipos que se van a deserializar solo implementan la "
"\"capa superior\" de\n"
"la API y los formatos de archivo solo necesitan implementar la \"capa "
"inferior\".\n"
"Luego, cada pieza puede \"simplemente funcionar\" con el resto del "
"ecosistema, ya que los genéricos\n"
"los tipos los unirán."
#: src\functional/lenses.md:340
#, fuzzy
msgid ""
"To emphasize, the only reason this model works on any format and any type "
"is\n"
"because the `Deserializer` trait's output type **is specified by the\n"
"implementor of `Visitor` it is passed**, rather than being tied to one "
"specific\n"
"type.\n"
"This was not true in the account example earlier."
msgstr ""
"Para enfatizar, la única razón por la que este modelo funciona en cualquier "
"formato y cualquier tipo es\n"
"porque el tipo de salida del rasgo `Deserializer` ** está especificado por "
"el\n"
"implementador de `Visitor` se pasa **, en lugar de estar vinculado a un "
"específico\n"
"tipo.\n"
"Esto no era cierto en el ejemplo de la cuenta anterior."
#: src\functional/lenses.md:346
#, fuzzy
msgid ""
"Rust's generic-inspired type system can bring it close to these concepts "
"and\n"
"use their power, as shown in this API design.\n"
"But it may also need procedural macros to create bridges for its generics."
msgstr ""
"El sistema de tipos de inspiración genérica de Rust puede acercarlo a estos "
"conceptos y\n"
"usa su poder, como se muestra en este diseño de API.\n"
"Pero también puede necesitar macros de procedimiento para crear puentes para "
"sus genéricos."
#: src\functional/lenses.md:350
#, fuzzy
msgid "## See Also"
msgstr "## Ver también"
#: src\functional/lenses.md:352
#, fuzzy
msgid ""
"- [lens-rs crate](https://crates.io/crates/lens-rs) for a pre-built lenses\n"
" implementation, with a cleaner interface than these examples\n"
"- [serde](https://serde.rs) itself, which makes these concepts intuitive "
"for\n"
" end users (i.e. defining the structs) without needing to undestand the\n"
" details\n"
"- [luminance](https://github.com/phaazon/luminance-rs) is a crate for "
"drawing\n"
" computer graphics that uses lens API design, including proceducal macros "
"to\n"
" create full prisms for buffers of different pixel types that remain "
"generic\n"
"- [An Article about Lenses in "
"Scala](https://web.archive.org/web/20221128185849/https://medium.com/zyseme-technology/functional-references-lens-and-other-optics-in-scala-e5f7e2fdafe)\n"
" that is very readable even without Scala expertise.\n"
"- [Paper: Profunctor Optics: Modular Data\n"
" "
"Accessors](https://web.archive.org/web/20220701102832/https://arxiv.org/ftp/arxiv/papers/1703/1703.10857.pdf)"
msgstr ""
"- [caja de lentes-rs] (https://crates.io/crates/lens-rs) para lentes "
"preconstruidos\n"
" implementación, con una interfaz más limpia que estos ejemplos\n"
"- [serde](https://serde.rs) en sí mismo, lo que hace que estos conceptos "
"sean intuitivos para\n"
" usuarios finales (es decir, definir las estructuras) sin necesidad de "
"entender el\n"
" detalles\n"
"- [luminance](https://github.com/phaazon/luminance-rs) es una caja para "
"dibujar\n"
" gráficos por computadora que utilizan el diseño de la API de la lente, "
"incluidas las macros procesales para\n"
" crear prismas completos para búferes de diferentes tipos de píxeles que "
"siguen siendo genéricos\n"
"- [Un artículo sobre lentes en Scala] "
"(https://web.archive.org/web/20221128185849/https://medium.com/zyseme-technology/function-references-lens-and-other-optics-in- "
"scala-e5f7e2fdafe)\n"
" eso es muy legible incluso sin experiencia en Scala.\n"
"- [Papel: Óptica Profunctor: Datos Modulares\n"
" "
"Accesores](https://web.archive.org/web/20220701102832/https://arxiv.org/ftp/arxiv/papers/1703/1703.10857.pdf)"
#: src\functional/lenses.md:365
#, fuzzy
msgid ""
"[School of Haskell: A Little Lens Starter "
"Tutorial](https://web.archive.org/web/20221128190041/https://www.schoolofhaskell.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial)"
msgstr ""
"[Escuela de Haskell: un pequeño tutorial para principiantes de lentes] "
"la-semana/un-pequeño-lentes-inicio-tutorial)"
#: src\additional_resources/index.md:1
#, fuzzy
msgid "# Additional resources"
msgstr "# Recursos adicionales"
#: src\additional_resources/index.md:3
#, fuzzy
msgid "A collection of complementary helpful content"
msgstr "Una colección de contenido útil complementario"
#: src\additional_resources/index.md:5
#, fuzzy
msgid "## Talks"
msgstr "## Negociaciones"
#: src\additional_resources/index.md:7
#, fuzzy
msgid ""
"- [Design Patterns in Rust](https://www.youtube.com/watch?v=Pm_oO0N5B9k) by\n"
" Nicholas Cameron at the PDRust (2016)\n"
"- [Writing Idiomatic Libraries in "
"Rust](https://www.youtube.com/watch?v=0zOg8_B71gE)\n"
" by Pascal Hertleif at RustFest (2017)\n"
"- [Rust Programming Techniques](https://www.youtube.com/watch?v=vqavdUGKeb4) "
"by\n"
" Nicholas Cameron at LinuxConfAu (2018)"
msgstr ""
"- [Patrones de diseño en Rust](https://www.youtube.com/watch?v=Pm_oO0N5B9k) "
"por\n"
" Nicholas Cameron en el PDRust (2016)\n"
"- [Escribir bibliotecas idiomáticas en "
"Rust](https://www.youtube.com/watch?v=0zOg8_B71gE)\n"
" por Pascal Hertleif en RustFest (2017)\n"
"- [Técnicas de programación de óxido] "
"(https://www.youtube.com/watch?v=vqavdUGKeb4) por\n"
" Nicholas Cameron en LinuxConfAu (2018)"
#: src\additional_resources/index.md:14
#, fuzzy
msgid "## Books (Online)"
msgstr "## Libros (en línea)"
#: src\additional_resources/index.md:16
#, fuzzy
msgid "- [The Rust API Guidelines](https://rust-lang.github.io/api-guidelines)"
msgstr ""
"- [Las pautas de la API de Rust] (https://rust-lang.github.io/api-guidelines)"
#: src\additional_resources/design-principles.md:1
#, fuzzy
msgid "# Design principles"
msgstr "# Criterios de diseño"
#: src\additional_resources/design-principles.md:3
#, fuzzy
msgid "## A brief overview over common design principles"
msgstr "## Una breve descripción de los principios de diseño comunes"
#: src\additional_resources/design-principles.md:7
#, fuzzy
msgid "## [SOLID](https://en.wikipedia.org/wiki/SOLID)"
msgstr "## [SÓLIDO](https://en.wikipedia.org/wiki/SÓLIDO)"
#: src\additional_resources/design-principles.md:9
#, fuzzy
msgid ""
"- [Single Responsibility Principle "
"(SRP)](https://en.wikipedia.org/wiki/Single-responsibility_principle):\n"
" A class should only have a single responsibility, that is, only changes "
"to\n"
" one part of the software's specification should be able to affect the\n"
" specification of the class.\n"
"- [Open/Closed Principle "
"(OCP)](https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle):\n"
" \"Software entities ... should be open for extension, but closed for\n"
" modification.\"\n"
"- [Liskov Substitution Principle "
"(LSP)](https://en.wikipedia.org/wiki/Liskov_substitution_principle):\n"
" \"Objects in a program should be replaceable with instances of their "
"subtypes\n"
" without altering the correctness of that program.\"\n"
"- [Interface Segregation Principle "
"(ISP)](https://en.wikipedia.org/wiki/Interface_segregation_principle):\n"
" \"Many client-specific interfaces are better than one general-purpose\n"
" interface.\"\n"
"- [Dependency Inversion Principle "
"(DIP)](https://en.wikipedia.org/wiki/Dependency_inversion_principle):\n"
" One should \"depend upon abstractions, [not] concretions.\""
msgstr ""
"- [Principio de responsabilidad única (SRP)] "
"(https://en.wikipedia.org/wiki/Single-responsibility_principle):\n"
" Una clase solo debe tener una única responsabilidad, es decir, solo "
"cambios a\n"
" una parte de la especificación del software debería poder afectar la\n"
" especificación de la clase.\n"
"- [Principio abierto/cerrado "
"(OCP)](https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle):\n"
" \"Las entidades de software... deberían estar abiertas para la extensión, "
"pero cerradas para\n"
" modificación.\"\n"
"- [Principio de sustitución de Liskov (LSP)] "
"(https://en.wikipedia.org/wiki/Liskov_substitution_principle):\n"
" \"Los objetos en un programa deben ser reemplazables con instancias de sus "
"subtipos\n"
" sin alterar la corrección de ese programa\".\n"
"- [Principio de segregación de interfaz (ISP)] "
"(https://en.wikipedia.org/wiki/Interface_segregation_principle):\n"
" \"Muchas interfaces específicas del cliente son mejores que una de "
"propósito general\n"
" interfaz.\"\n"
"- [Principio de inversión de dependencia (DIP)] "
"(https://en.wikipedia.org/wiki/Dependency_inversion_principle):\n"
" Uno debe \"depender de abstracciones, [no] de concreciones\"."
#: src\additional_resources/design-principles.md:25
#, fuzzy
msgid ""
"## [DRY (Dont Repeat "
"Yourself)](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)"
msgstr ""
"## [SECO (No te "
"repitas)](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)"
#: src\additional_resources/design-principles.md:27
#, fuzzy
msgid ""
"\"Every piece of knowledge must have a single, unambiguous, authoritative\n"
"representation within a system\""
msgstr ""
"“Cada pieza de conocimiento debe tener un único, inequívoco, autorizado\n"
"representación dentro de un sistema\""
#: src\additional_resources/design-principles.md:30
#, fuzzy
msgid "## [KISS principle](https://en.wikipedia.org/wiki/KISS_principle)"
msgstr "## [principio KISS](https://en.wikipedia.org/wiki/KISS_principle)"
#: src\additional_resources/design-principles.md:32
msgid ""
"most systems work best if they are kept simple rather than made "
"complicated;\n"
"therefore, simplicity should be a key goal in design, and unnecessary\n"
"complexity should be avoided"
msgstr ""
#: src\additional_resources/design-principles.md:36
#, fuzzy
msgid "## [Law of Demeter (LoD)](https://en.wikipedia.org/wiki/Law_of_Demeter)"
msgstr "## [Ley de Deméter (LoD)](https://en.wikipedia.org/wiki/Law_of_Demeter)"
#: src\additional_resources/design-principles.md:38
#, fuzzy
msgid ""
"a given object should assume as little as possible about the structure or\n"
"properties of anything else (including its subcomponents), in accordance "
"with\n"
"the principle of \"information hiding\""
msgstr ""
"un objeto dado debe suponer lo menos posible acerca de la estructura o\n"
"propiedades de cualquier otra cosa (incluidos sus subcomponentes), de "
"acuerdo con\n"
"el principio de \"ocultamiento de información\""
#: src\additional_resources/design-principles.md:42
#, fuzzy
msgid ""
"## [Design by contract "
"(DbC)](https://en.wikipedia.org/wiki/Design_by_contract)"
msgstr ""
"## [Diseño por contrato "
"(DbC)](https://en.wikipedia.org/wiki/Design_by_contract)"
#: src\additional_resources/design-principles.md:44
#, fuzzy
msgid ""
"software designers should define formal, precise and verifiable interface\n"
"specifications for software components, which extend the ordinary definition "
"of\n"
"abstract data types with preconditions, postconditions and invariants"
msgstr ""
"los diseñadores de software deben definir una interfaz formal, precisa y "
"verificable\n"
"especificaciones para componentes de software, que amplían la definición "
"ordinaria de\n"
"tipos de datos abstractos con condiciones previas, condiciones posteriores e "
"invariantes"
#: src\additional_resources/design-principles.md:48
#, fuzzy
msgid ""
"## "
"[Encapsulation](https://en.wikipedia.org/wiki/Encapsulation_(computer_programming))"
msgstr ""
"## "
"[Encapsulación](https://en.wikipedia.org/wiki/Encapsulation_(computer_programming))"
#: src\additional_resources/design-principles.md:50
#, fuzzy
msgid ""
"bundling of data with the methods that operate on that data, or the "
"restricting\n"
"of direct access to some of an object's components. Encapsulation is used "
"to\n"
"hide the values or state of a structured data object inside a class, "
"preventing\n"
"unauthorized parties' direct access to them."
msgstr ""
"agrupación de datos con los métodos que operan en esos datos, o la "
"restricción\n"
"de acceso directo a algunos de los componentes de un objeto. La "
"encapsulación se utiliza para\n"
"ocultar los valores o el estado de un objeto de datos estructurados dentro "
"de una clase, evitando\n"
"el acceso directo de terceros no autorizados a ellos."
#: src\additional_resources/design-principles.md:55
#, fuzzy
msgid ""
"## "
"[Command-Query-Separation(CQS)](https://en.wikipedia.org/wiki/Command%E2%80%93query_separation)"
msgstr ""
"## [Comando-Consulta-Separación "
"(CQS)](https://en.wikipedia.org/wiki/Command%E2%80%93query_separation)"
#: src\additional_resources/design-principles.md:57
#, fuzzy
msgid ""
"“Functions should not produce abstract side effects...only commands\n"
"(procedures) will be permitted to produce side effects.” - Bertrand Meyer:\n"
"Object-Oriented Software Construction"
msgstr ""
"“Las funciones no deben producir efectos secundarios abstractos... solo "
"comandos\n"
"(procedimientos) podrán producir efectos secundarios”. -Bertrand Meyer:\n"
"Construcción de software orientada a objetos"
#: src\additional_resources/design-principles.md:61
#, fuzzy
msgid ""
"## [Principle of least astonishment "
"(POLA)](https://en.wikipedia.org/wiki/Principle_of_least_astonishment)"
msgstr ""
"## [Principio del menor asombro "
"(POLA)](https://en.wikipedia.org/wiki/Principle_of_least_astonishment)"
#: src\additional_resources/design-principles.md:63
#, fuzzy
msgid ""
"a component of a system should behave in a way that most users will expect "
"it\n"
"to behave. The behavior should not astonish or surprise users"
msgstr ""
"un componente de un sistema debe comportarse de una manera que la mayoría de "
"los usuarios esperarán\n"
"a comportarse. El comportamiento no debe asombrar o sorprender a los "
"usuarios."
#: src\additional_resources/design-principles.md:66
#, fuzzy
msgid "## Linguistic-Modular-Units"
msgstr "## Unidades modulares lingüísticas"
#: src\additional_resources/design-principles.md:68
#, fuzzy
msgid ""
"“Modules must correspond to syntactic units in the language used.” - "
"Bertrand\n"
"Meyer: Object-Oriented Software Construction"
msgstr ""
"“Los módulos deben corresponder a unidades sintácticas en el idioma "
"utilizado.” - Bertrand\n"
"Meyer: Construcción de Software Orientado a Objetos"
#: src\additional_resources/design-principles.md:71
#, fuzzy
msgid "## Self-Documentation"
msgstr "## Autodocumentación"
#: src\additional_resources/design-principles.md:73
#, fuzzy
msgid ""
"“The designer of a module should strive to make all information about the\n"
"module part of the module itself.” - Bertrand Meyer: Object-Oriented "
"Software\n"
"Construction"
msgstr ""
"“El diseñador de un módulo debe esforzarse por hacer que toda la información "
"sobre el\n"
"módulo parte del propio módulo.” - Bertrand Meyer: software orientado a "
"objetos\n"
"Construcción"
#: src\additional_resources/design-principles.md:77
#, fuzzy
msgid "## Uniform-Access"
msgstr "## Acceso uniforme"
#: src\additional_resources/design-principles.md:79
#, fuzzy
msgid ""
"“All services offered by a module should be available through a uniform\n"
"notation, which does not betray whether they are implemented through storage "
"or\n"
"through computation.” - Bertrand Meyer: Object-Oriented Software Construction"
msgstr ""
"“Todos los servicios ofrecidos por un módulo deben estar disponibles a "
"través de un\n"
"notación, que no traiciona si se implementan a través del almacenamiento o\n"
"a través de la computación.” - Bertrand Meyer: Construcción de Software "
"Orientado a Objetos"
#: src\additional_resources/design-principles.md:83
#, fuzzy
msgid "## Single-Choice"
msgstr "## Opción única"
#: src\additional_resources/design-principles.md:85
#, fuzzy
msgid ""
"“Whenever a software system must support a set of alternatives, one and "
"only\n"
"one module in the system should know their exhaustive list.” - Bertrand "
"Meyer:\n"
"Object-Oriented Software Construction"
msgstr ""
"“Siempre que un sistema de software deba soportar un conjunto de "
"alternativas, una y sólo\n"
"un módulo en el sistema debe conocer su lista exhaustiva”. -Bertrand Meyer:\n"
"Construcción de software orientada a objetos"
#: src\additional_resources/design-principles.md:89
#, fuzzy
msgid "## Persistence-Closure"
msgstr "## Persistencia-Cierre"
#: src\additional_resources/design-principles.md:91
#, fuzzy
msgid ""
"“Whenever a storage mechanism stores an object, it must store with it the\n"
"dependents of that object. Whenever a retrieval mechanism retrieves a\n"
"previously stored object, it must also retrieve any dependent of that "
"object\n"
"that has not yet been retrieved.” - Bertrand Meyer: Object-Oriented "
"Software\n"
"Construction"
msgstr ""
"“Siempre que un mecanismo de almacenamiento almacena un objeto, debe "
"almacenar con él el\n"
"dependientes de ese objeto. Cada vez que un mecanismo de recuperación "
"recupera un\n"
"objeto previamente almacenado, también debe recuperar cualquier dependiente "
"de ese objeto\n"
"que aún no ha sido recuperado.” - Bertrand Meyer: software orientado a "
"objetos\n"
"Construcción"
msgid ""
msgstr ""
msgid ""
msgstr ""
msgid ""
msgstr ""
msgid ""
msgstr ""
msgid ""
msgstr ""
msgid ""
msgstr ""
msgid ""
msgstr ""
msgid ""
msgstr ""
msgid ""
msgstr ""
msgid ""
msgstr ""