Showing preview only (1,499K chars total). Download the full file or copy to clipboard to get everything.
Repository: rust-unofficial/patterns
Branch: main
Commit: f279f3541c37
Files: 80
Total size: 1.4 MB
Directory structure:
gitextract_1gr8fib9/
├── .dprint.json
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── build.yml
│ ├── install-mdbook/
│ │ └── action.yml
│ ├── lint.yml
│ ├── publish.yml
│ ├── setup-rust-cache/
│ │ └── action.yml
│ ├── url-check-on-change.yml
│ └── url-check-periodic.yml
├── .gitignore
├── .lycheeignore
├── .markdownlint.yaml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── book.toml
├── po/
│ ├── es.po
│ ├── it.po
│ ├── messages.pot
│ └── pt-BR.po
├── src/
│ ├── SUMMARY.md
│ ├── additional_resources/
│ │ ├── design-principles.md
│ │ └── index.md
│ ├── anti_patterns/
│ │ ├── borrow_clone.md
│ │ ├── deny-warnings.md
│ │ ├── deref.md
│ │ └── index.md
│ ├── functional/
│ │ ├── generics-type-classes.md
│ │ ├── index.md
│ │ ├── optics.md
│ │ └── paradigms.md
│ ├── idioms/
│ │ ├── coercion-arguments.md
│ │ ├── concat-format.md
│ │ ├── ctor.md
│ │ ├── default.md
│ │ ├── deref.md
│ │ ├── dtor-finally.md
│ │ ├── ffi/
│ │ │ ├── accepting-strings.md
│ │ │ ├── errors.md
│ │ │ ├── intro.md
│ │ │ └── passing-strings.md
│ │ ├── index.md
│ │ ├── mem-replace.md
│ │ ├── on-stack-dyn-dispatch.md
│ │ ├── option-iter.md
│ │ ├── pass-var-to-closure.md
│ │ ├── priv-extend.md
│ │ ├── return-consumed-arg-on-error.md
│ │ ├── rustdoc-init.md
│ │ └── temporary-mutability.md
│ ├── intro.md
│ ├── patterns/
│ │ ├── behavioural/
│ │ │ ├── RAII.md
│ │ │ ├── command.md
│ │ │ ├── interpreter.md
│ │ │ ├── intro.md
│ │ │ ├── newtype.md
│ │ │ ├── strategy.md
│ │ │ └── visitor.md
│ │ ├── creational/
│ │ │ ├── builder.md
│ │ │ ├── fold.md
│ │ │ └── intro.md
│ │ ├── ffi/
│ │ │ ├── export.md
│ │ │ ├── intro.md
│ │ │ └── wrappers.md
│ │ ├── index.md
│ │ └── structural/
│ │ ├── compose-structs.md
│ │ ├── intro.md
│ │ ├── small-crates.md
│ │ ├── trait-for-bounds.md
│ │ └── unsafe-mods.md
│ ├── refactoring/
│ │ └── index.md
│ └── translations.md
├── styles/
│ └── last-changed.css
├── template.md
├── theme/
│ ├── css/
│ │ └── language-picker.css
│ ├── head.hbs
│ └── index.hbs
└── third_party/
└── mdbook/
├── LICENSE
├── README.md
└── book.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .dprint.json
================================================
{
"lineWidth": 80,
"markdown": {
"lineWidth": 80,
"emphasisKind": "asterisks",
"strongKind": "asterisks",
"textWrap": "always"
},
"toml": {
"lineWidth": 80
},
"json": {
"lineWidth": 80,
"indentWidth": 4
},
"includes": [
"**/*.{md}",
"**/*.{toml}",
"**/*.{json}",
"**/*.{js,ts,tsx,jsx}"
],
"excludes": [
"book/**/book.js",
"theme/book.js",
"target/**/*"
],
"exec": {
"commands": [{
"command": "rustfmt --edition 2021",
"exts": ["rs"]
}]
},
"plugins": [
"https://plugins.dprint.dev/markdown-0.20.0.wasm",
"https://plugins.dprint.dev/toml-0.7.0.wasm",
"https://plugins.dprint.dev/json-0.21.0.wasm",
"https://plugins.dprint.dev/typescript-0.95.13.wasm",
"https://plugins.dprint.dev/exec-0.6.0.json@a054130d458f124f9b5c91484833828950723a5af3f8ff2bd1523bd47b83b364"
]
}
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
# Check for updates every Monday
schedule:
interval: "weekly"
open-pull-requests-limit: 10
================================================
FILE: .github/workflows/build.yml
================================================
name: Test mdbook chapters
on:
pull_request:
push:
branches:
- main
env:
CARGO_TERM_COLOR: always
jobs:
mdbook-test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Rust cache
uses: ./.github/workflows/setup-rust-cache
- name: Install mdbook
uses: ./.github/workflows/install-mdbook
- name: Test code snippets
run: mdbook test
# TODO: Activate when first translation is available
# i18n-helpers:
# runs-on: ubuntu-latest
# steps:
# - name: Checkout
# uses: actions/checkout@v4
# - name: Install Gettext
# run: sudo apt install gettext
# - name: Setup Rust cache
# uses: ./.github/workflows/setup-rust-cache
# - name: Install mdbook
# uses: ./.github/workflows/install-mdbook
# - name: Generate po/messages.pot
# run: mdbook build -d po
# env:
# MDBOOK_OUTPUT: '{"xgettext": {"pot-file": "messages.pot"}}'
# - name: Test messages.pot
# run: msgfmt --statistics -o /dev/null po/messages.pot
# - name: Expand includes without translation
# run: mdbook build -d expanded
# env:
# MDBOOK_OUTPUT: '{"markdown": {}}'
# - name: Expand includes with no-op translation
# run: mdbook build -d no-op
# env:
# MDBOOK_OUTPUT: '{"markdown": {}}'
# MDBOOK_PREPROCESSOR__GETTEXT__PO_FILE: po/messages.pot
# - name: Compare no translation to no-op translation
# run: diff --color=always --unified --recursive expanded no-op
# find-translations:
# runs-on: ubuntu-latest
# outputs:
# languages: ${{ steps.find-translations.outputs.languages }}
# steps:
# - name: Checkout
# uses: actions/checkout@v4
# - name: Find translations
# id: find-translations
# shell: python
# run: |
# import os, json, pathlib
# languages = [p.stem for p in pathlib.Path("po").iterdir() if p.suffix == ".po"]
# github_output = open(os.environ["GITHUB_OUTPUT"], "a")
# github_output.write("languages=")
# json.dump(sorted(languages), github_output)
# translations:
# runs-on: ubuntu-latest
# needs:
# - find-translations
# strategy:
# matrix:
# language: ${{ fromJSON(needs.find-translations.outputs.languages) }}
# env:
# MDBOOK_BOOK__LANGUAGE: ${{ matrix.language }}
# steps:
# - name: Checkout
# uses: actions/checkout@v4
# - name: Install Gettext
# run: sudo apt install gettext
# - name: Setup Rust cache
# uses: ./.github/workflows/setup-rust-cache
# - name: Install mdbook
# uses: ./.github/workflows/install-mdbook
# - name: Test ${{ matrix.language }} translation
# run: msgfmt --statistics -o /dev/null po/${{ matrix.language }}.po
# - name: Build book with ${{ matrix.language }} translation
# run: mdbook build
# - name: Upload ${{ matrix.language }} translation
# uses: actions/upload-artifact@v3
# with:
# name: rust-design-patterns-${{ matrix.language }}
# path: book/
# - name: Test code snippets with ${{ matrix.language }} translation
# run: mdbook test
================================================
FILE: .github/workflows/install-mdbook/action.yml
================================================
name: Install mdbook and dependencies
description: Install the mdbook with the dependencies we need.
runs:
using: composite
steps:
- name: Read mdbook version from .env
id: mdbook-version
run: |
. ./.env
echo "version=$MDBOOK_VERSION" >> $GITHUB_OUTPUT
shell: bash
- name: Read mdbook-i18n-helpers version from .env
id: mdbook-i18n-helpers-version
run: |
. ./.env
echo "version=$MDBOOK_I18N_HELPERS_VERSION" >> $GITHUB_OUTPUT
shell: bash
- name: Read mdbook-pandoc version from .env
id: mdbook-pandoc-version
run: |
. ./.env
echo "version=$MDBOOK_PANDOC_VERSION" >> $GITHUB_OUTPUT
shell: bash
- name: Read mdbook-last-changed version from .env
id: mdbook-last-changed-version
run: |
. ./.env
echo "version=$MDBOOK_LAST_CHANGED_VERSION" >> $GITHUB_OUTPUT
shell: bash
- name: Install dependencies
uses: taiki-e/install-action@v2
with:
tool: mdbook@${{ steps.mdbook-version.outputs.version }},mdbook-pandoc@${{ steps.mdbook-pandoc-version.outputs.version }},mdbook-i18n-helpers@${{ steps.mdbook-i18n-helpers-version.outputs.version }},mdbook-last-changed@${{ steps.mdbook-last-changed-version.outputs.version }}
- name: Install mdbook-pandoc and related dependencies
run: |
. ./.env
sudo apt-get update
sudo apt-get install -y texlive texlive-latex-extra texlive-luatex texlive-lang-cjk librsvg2-bin fonts-noto
curl -LsSf https://github.com/jgm/pandoc/releases/download/$PANDOC_VERSION/pandoc-$PANDOC_VERSION-linux-amd64.tar.gz | tar zxf -
echo "$PWD/pandoc-$PANDOC_VERSION/bin" >> $GITHUB_PATH
shell: bash
================================================
FILE: .github/workflows/lint.yml
================================================
name: Lint with dprint
on:
push:
branches: [main]
pull_request:
jobs:
style:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@f7ccc83f9ed1e5b9c81d8a67d7ad1a747e22a561 # v1
with:
toolchain: stable
components: rustfmt
- uses: Swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2
- uses: dprint/check@v2.3
================================================
FILE: .github/workflows/publish.yml
================================================
name: Deploy mdBook sites to GH Pages
on:
push:
branches: ["main"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
# TODO: Update the language picker in index.hbs to link new languages.
# TODO: As long as https://github.com/google/mdbook-i18n-helpers/issues/12 is not implemented, yet.
# TODO: Activate when first translation is available
# These are the languages in addition to 'en', which is the main language
# LANGUAGES: xx
jobs:
publish:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Rust cache
uses: ./.github/workflows/setup-rust-cache
- name: Install mdbook
uses: ./.github/workflows/install-mdbook
- name: Build course in English
run: |
mdbook build -d book
mv book/html/* book/pandoc/pdf/rust-design-patterns.pdf book/
rm -r book/html book/pandoc
# TODO: Activate when first translation is available
# - name: Build all translations
# run: |
# for po_lang in ${{ env.LANGUAGES }}; do
# echo "::group::Building $po_lang translation"
# MDBOOK_BOOK__LANGUAGE=$po_lang \
# MDBOOK_OUTPUT__HTML__SITE_URL=/patterns/$po_lang/ \
# mdbook build -d book/$po_lang
# echo "::endgroup::"
# done
- name: Setup Pages
id: pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./book
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
================================================
FILE: .github/workflows/setup-rust-cache/action.yml
================================================
name: Setup Rust cache
description: Configure the rust-cache workflow.
runs:
using: composite
steps:
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
prefix-key: v1
================================================
FILE: .github/workflows/url-check-on-change.yml
================================================
name: Check Markdown links
on:
push:
branches: [main]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: {}
jobs:
markdown-link-check:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: Restore lychee cache
uses: actions/cache@v5
with:
path: .lycheecache
key: cache-lychee-${{ github.sha }}
restore-keys: cache-lychee-
- name: Link Checker
uses: lycheeverse/lychee-action@a8c4c7cb88f0c7386610c35eb25108e448569cb0 # v2.7.0
env:
# set the GitHub token to avoid rate limits
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
fail: true
args: |
--no-progress
--accept '100..=103, 200..=299, 429'
.
================================================
FILE: .github/workflows/url-check-periodic.yml
================================================
name: Check Markdown links Periodically
on:
schedule:
# Run everyday at 0:00 AM
- cron: "0 0 * * *"
permissions: {}
jobs:
markdown-link-check-periodic:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: Restore lychee cache
uses: actions/cache@v5
with:
path: .lycheecache
key: cache-lychee-${{ github.sha }}
restore-keys: cache-lychee-
- name: Link Checker
uses: lycheeverse/lychee-action@a8c4c7cb88f0c7386610c35eb25108e448569cb0 # v2.7.0
env:
# set the GitHub token to avoid rate limits
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
fail: true
args: |
--no-progress
--accept '100..=103, 200..=299, 429'
.
================================================
FILE: .gitignore
================================================
# Generated output of mdbook
/book
.DS_Store
.vscode/settings.json
================================================
FILE: .lycheeignore
================================================
^(http|https)://crates.io/
================================================
FILE: .markdownlint.yaml
================================================
---
# Use `#` for headers
MD003:
style: atx
# Set maximum line length
MD013:
line_length: 80
# Use `---` for horizontal rule
MD035:
style: ---
# Use ``` for code blocks
MD046:
style: fenced
MD048:
style: backtick
# See https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md for
# additional info
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
## Introduction
This book is a catalogue of Rust programming techniques, (anti-)patterns, idioms
and other explanations. It is a compilation of collective (sometimes implicit)
knowledge as well as experiences that have emerged through collaborative work.
The patterns described here are **not rules**, but should be taken as guidelines
for writing idiomatic code in Rust. We are collecting Rust patterns in this book
so people can learn the tradeoffs between Rust idioms and use them properly in
their own code.
If you want to be part of this effort here are some ways you can participate:
## Discussion board
If you have a question or an idea regarding certain content, but you want to
have feedback of fellow community members, and you think it may not be
appropriate to file an issue open a discussion in our
[discussion board](https://github.com/rust-unofficial/patterns/discussions).
## Writing a new article
Before writing a new article please check in one of the following resources if
there is an existing discussion or if someone is already working on that topic:
- [Umbrella issue](https://github.com/rust-unofficial/patterns/issues/116),
- [All issues](https://github.com/rust-unofficial/patterns/issues),
- [Pull Requests](https://github.com/rust-unofficial/patterns/pulls)
If you don't find an issue regarding your topic, and you are sure it is not more
feasible to open a thread in the
[discussion board](https://github.com/rust-unofficial/patterns/discussions)
please open a new issue, so we can discuss the ideas and future content of the
article together and maybe give some feedback/input on it.
When writing a new article it's recommended to copy the
[pattern template](https://github.com/rust-unofficial/patterns/blob/master/template.md)
into the appropriate directory and start editing it. You may not want to fill
out every section and remove it, or you might want to add extra sections.
Consider writing your article in a way that has a low barrier of entry so also
[Rustlings](https://github.com/rust-lang/rustlings) can follow and understand
the thought process behind it. So we can encourage people to use these patterns
early on.
We encourage you to write idiomatic Rust code that builds in the
[playground](https://play.rust-lang.org/).
If you use links to blogposts or in general content that is not to be sure
existing in a few years (e.g. pdfs) please take a snapshot with the
[Wayback Machine](https://web.archive.org/) and use the link to that snapshot in
your article.
Don't forget to add your new article to the `SUMMARY.md` to let it be rendered
to the book.
Please make `Draft Pull requests` early, so we can follow your progress and can
give early feedback (see the following section).
## Style guide
In order to have a consistent style across the book, we suggest to:
- Follow the official Rust book's
[style guide](https://github.com/rust-lang/book/blob/master/style-guide.md).
- Follow
[RFC 1574](https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text).
Tl;dr:
- Prefer full types name. For example `Option<T>` instead of `Option`.
- Prefer line comments (`//`) over block comments (`/* */`) where applicable.
## Check the article locally
Before submitting the PR launch the commands `mdbook build` to make sure that
the book builds and `mdbook test` to make sure that code examples are correct.
### Markdown lint
To make sure the files comply with our Markdown style we use
[markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli). To spare
you some manual work to get through the CI test you can use the following
commands to automatically fix most of the emerging problems when writing
Markdown files.
- Install:
```sh
npm install -g markdownlint-cli
```
- Check all markdown files:
- unix: `markdownlint '**/*.md'`
- windows: `markdownlint **/*.md`
- Automatically fix basic errors:
- unix: `markdownlint -f '**/*.md'`
- windows: `markdownlint -f **/*.md`
## Creating a Pull Request
"Release early and often!" also applies to pull requests!
Once your article has some visible work, create a `[WIP]` draft pull request and
give it a description of what you did or want to do. Early reviews of the
community are not meant as an offense but to give feedback.
A good principle: "Work together, share ideas, teach others."
### Important Note
Please **don't force push** commits in your branch, in order to keep commit
history and make it easier for us to see changes between reviews.
Make sure to `Allow edits of maintainers` (under the text box) in the PR so
people can actually collaborate on things or fix smaller issues themselves.
## Maintainers
This repository is maintained by the following people:
- [simonsan](https://github.com/simonsan).
- [marcoieni](https://github.com/marcoieni). Marco only works on the book CI. He
doesn't review the book content and he doesn't receive notifications on new
issues and pull requests. If you want him to have a look at a CI issue, ping
him directly.
================================================
FILE: LICENSE
================================================
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.
================================================
FILE: README.md
================================================
# Rust Design Patterns
An open source book about design patterns and idioms in the Rust programming
language that you can read [here](https://rust-unofficial.github.io/patterns/).
You can also download the book in PDF format from
[this link](https://rust-unofficial.github.io/patterns/rust-design-patterns.pdf).
## Contributing
You are missing content in this repository that can be helpful for others, and
you are eager to explain it? Awesome! We are always happy about new
contributions (e.g. elaboration or corrections on certain topics) to this
project.
You can check the
[Umbrella issue](https://github.com/rust-unofficial/patterns/issues/116) for all
the patterns, anti-patterns, and idioms that could be added.
We suggest reading our [Contribution guide](./CONTRIBUTING.md) to get more
information on how contributing to this repository works.
## Building with mdbook
This book is built with [mdbook](https://rust-lang.github.io/mdBook/). You can
install it by running `cargo install mdbook`.
### Additional dependencies
- `cargo install mdbook-last-changed` for date changes in the footer
- `cargo install mdbook-pandoc` for rendering the book to PDF
- `cargo install mdbook-i18n-helpers` for translation and i8n support
#### Texlive
```sh
# Source the .env file to get the PANDOC_VERSION
. ./.env
sudo apt-get update
sudo apt-get install -y texlive texlive-latex-extra texlive-luatex texlive-lang-cjk librsvg2-bin fonts-noto
curl -LsSf https://github.com/jgm/pandoc/releases/download/$PANDOC_VERSION/pandoc-$PANDOC_VERSION-linux-amd64.tar.gz | tar zxf -
```
### Building the book
If you want to build it locally you can run one of these two commands in the
root directory of the repository:
- `mdbook build`
Builds static html pages as output and place them in the `/book` directory by
default.
- `mdbook serve`
Serves the book at `http://localhost:3000` (port is changeable, take a look at
the terminal output to be sure) and reloads the browser when a change occurs.
## License
The content of this repository is licensed under **MPL-2.0**; see
[LICENSE](./LICENSE).
================================================
FILE: book.toml
================================================
[book]
title = "Rust Design Patterns"
authors = ["the rust-unofficial authors"]
description = "A catalogue of Rust design patterns, anti-patterns and idioms"
language = "en"
src = "src"
[build]
create-missing = false
extra-watch-dirs = ["po", "third_party"]
[preprocessor.gettext]
after = ["links"]
[rust]
edition = "2024"
[output.html]
smart-punctuation = true
default-theme = "rust"
site-url = "/patterns/"
git-repository-url = "https://github.com/rust-unofficial/patterns"
edit-url-template = "https://github.com/rust-unofficial/patterns/edit/main/{path}"
additional-css = [
"./theme/css/language-picker.css",
"./styles/last-changed.css",
]
[preprocessor.last-changed]
optional = true
command = "mdbook-last-changed"
renderer = ["html"]
[output.html.fold]
enable = true
level = 1
[output.html.playground]
editable = false
# [output.linkcheck] # enable the "mdbook-linkcheck" renderer, disabled due to gh-actions
[output.html.redirect]
# Redirects in the form of "old-path" = "new-path", where the new path
# is relative to the old path.
"functional/lenses.html" = "optics.html"
[output.pandoc]
optional = true
hosted-html = "https://rust-unofficial.github.io/patterns/"
[output.pandoc.profile.pdf]
output-file = "rust-design-patterns.pdf"
pdf-engine = "lualatex"
[output.pandoc.profile.pdf.variables]
mainfont = "Noto Serif"
sansfont = "Noto Sans"
monofont = "Noto Sans Mono"
mainfontfallback = ["NotoSerifCJKSC:"]
geometry = ["margin=1in"]
linkcolor = "blue"
urlcolor = "red"
================================================
FILE: po/es.po
================================================
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 algorithm’s 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
gitextract_1gr8fib9/
├── .dprint.json
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── build.yml
│ ├── install-mdbook/
│ │ └── action.yml
│ ├── lint.yml
│ ├── publish.yml
│ ├── setup-rust-cache/
│ │ └── action.yml
│ ├── url-check-on-change.yml
│ └── url-check-periodic.yml
├── .gitignore
├── .lycheeignore
├── .markdownlint.yaml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── book.toml
├── po/
│ ├── es.po
│ ├── it.po
│ ├── messages.pot
│ └── pt-BR.po
├── src/
│ ├── SUMMARY.md
│ ├── additional_resources/
│ │ ├── design-principles.md
│ │ └── index.md
│ ├── anti_patterns/
│ │ ├── borrow_clone.md
│ │ ├── deny-warnings.md
│ │ ├── deref.md
│ │ └── index.md
│ ├── functional/
│ │ ├── generics-type-classes.md
│ │ ├── index.md
│ │ ├── optics.md
│ │ └── paradigms.md
│ ├── idioms/
│ │ ├── coercion-arguments.md
│ │ ├── concat-format.md
│ │ ├── ctor.md
│ │ ├── default.md
│ │ ├── deref.md
│ │ ├── dtor-finally.md
│ │ ├── ffi/
│ │ │ ├── accepting-strings.md
│ │ │ ├── errors.md
│ │ │ ├── intro.md
│ │ │ └── passing-strings.md
│ │ ├── index.md
│ │ ├── mem-replace.md
│ │ ├── on-stack-dyn-dispatch.md
│ │ ├── option-iter.md
│ │ ├── pass-var-to-closure.md
│ │ ├── priv-extend.md
│ │ ├── return-consumed-arg-on-error.md
│ │ ├── rustdoc-init.md
│ │ └── temporary-mutability.md
│ ├── intro.md
│ ├── patterns/
│ │ ├── behavioural/
│ │ │ ├── RAII.md
│ │ │ ├── command.md
│ │ │ ├── interpreter.md
│ │ │ ├── intro.md
│ │ │ ├── newtype.md
│ │ │ ├── strategy.md
│ │ │ └── visitor.md
│ │ ├── creational/
│ │ │ ├── builder.md
│ │ │ ├── fold.md
│ │ │ └── intro.md
│ │ ├── ffi/
│ │ │ ├── export.md
│ │ │ ├── intro.md
│ │ │ └── wrappers.md
│ │ ├── index.md
│ │ └── structural/
│ │ ├── compose-structs.md
│ │ ├── intro.md
│ │ ├── small-crates.md
│ │ ├── trait-for-bounds.md
│ │ └── unsafe-mods.md
│ ├── refactoring/
│ │ └── index.md
│ └── translations.md
├── styles/
│ └── last-changed.css
├── template.md
├── theme/
│ ├── css/
│ │ └── language-picker.css
│ ├── head.hbs
│ └── index.hbs
└── third_party/
└── mdbook/
├── LICENSE
├── README.md
└── book.js
SYMBOL INDEX (24 symbols across 1 files)
FILE: third_party/mdbook/book.js
function playground_text (line 9) | function playground_text(playground, hidden = true) {
function fetch_with_timeout (line 23) | function fetch_with_timeout(url, options, timeout = 6000) {
function handle_crate_list_update (line 51) | function handle_crate_list_update(playground_block, playground_crates) {
function update_play_button (line 78) | function update_play_button(pre_block, playground_crates) {
function run_rust_code (line 109) | function run_rust_code(code_block) {
function showThemes (line 336) | function showThemes() {
function updateThemeSelected (line 342) | function updateThemeSelected() {
function hideThemes (line 355) | function hideThemes() {
function get_saved_theme (line 361) | function get_saved_theme() {
function delete_saved_theme (line 371) | function delete_saved_theme() {
function get_theme (line 375) | function get_theme() {
function set_theme (line 395) | function set_theme(theme, store = true) {
function showSidebar (line 574) | function showSidebar() {
function hideSidebar (line 588) | function hideSidebar() {
function initResize (line 625) | function initResize() {
function resize (line 630) | function resize(e) {
function stopResize (line 646) | function stopResize() {
function next (line 693) | function next() {
function prev (line 699) | function prev() {
function showHelp (line 705) | function showHelp() {
function hideHelp (line 737) | function hideHelp() {
function hideTooltip (line 778) | function hideTooltip(elem) {
function showTooltip (line 783) | function showTooltip(elem, msg) {
function updateBorder (line 867) | function updateBorder() {
Condensed preview — 80 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,612K chars).
[
{
"path": ".dprint.json",
"chars": 1016,
"preview": "{\n \"lineWidth\": 80,\n \"markdown\": {\n \"lineWidth\": 80,\n \"emphasisKind\": \"asterisks\",\n \"strongKi"
},
{
"path": ".github/dependabot.yml",
"chars": 188,
"preview": "version: 2\nupdates:\n - package-ecosystem: \"github-actions\"\n directory: \"/\"\n # Check for updates every Monday\n "
},
{
"path": ".github/workflows/build.yml",
"chars": 3379,
"preview": "name: Test mdbook chapters\n\non:\n pull_request:\n push:\n branches:\n - main\n\nenv:\n CARGO_TERM_COLOR: always\n\njob"
},
{
"path": ".github/workflows/install-mdbook/action.yml",
"chars": 1747,
"preview": "name: Install mdbook and dependencies\n\ndescription: Install the mdbook with the dependencies we need.\n\nruns:\n using: co"
},
{
"path": ".github/workflows/lint.yml",
"chars": 467,
"preview": "name: Lint with dprint\n\non:\n push:\n branches: [main]\n pull_request:\n\njobs:\n style:\n runs-on: ubuntu-latest\n "
},
{
"path": ".github/workflows/publish.yml",
"chars": 1918,
"preview": "name: Deploy mdBook sites to GH Pages\n\non:\n push:\n branches: [\"main\"]\n workflow_dispatch:\n\npermissions:\n contents:"
},
{
"path": ".github/workflows/setup-rust-cache/action.yml",
"chars": 206,
"preview": "name: Setup Rust cache\n\ndescription: Configure the rust-cache workflow.\n\nruns:\n using: composite\n steps:\n - name: S"
},
{
"path": ".github/workflows/url-check-on-change.yml",
"chars": 992,
"preview": "name: Check Markdown links\n\non:\n push:\n branches: [main]\n pull_request:\n\nconcurrency:\n group: ${{ github.workflow "
},
{
"path": ".github/workflows/url-check-periodic.yml",
"chars": 944,
"preview": "name: Check Markdown links Periodically\n\non:\n schedule:\n # Run everyday at 0:00 AM\n - cron: \"0 0 * * *\"\n\npermissi"
},
{
"path": ".gitignore",
"chars": 67,
"preview": "# Generated output of mdbook\n/book\n.DS_Store\n.vscode/settings.json\n"
},
{
"path": ".lycheeignore",
"chars": 27,
"preview": "^(http|https)://crates.io/\n"
},
{
"path": ".markdownlint.yaml",
"chars": 321,
"preview": "---\n# Use `#` for headers\nMD003:\n style: atx\n\n# Set maximum line length\nMD013:\n line_length: 80\n\n# Use `---` for horiz"
},
{
"path": "CONTRIBUTING.md",
"chars": 5104,
"preview": "# Contributing\n\n## Introduction\n\nThis book is a catalogue of Rust programming techniques, (anti-)patterns, idioms\nand ot"
},
{
"path": "LICENSE",
"chars": 15648,
"preview": " Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor"
},
{
"path": "README.md",
"chars": 2110,
"preview": "# Rust Design Patterns\n\nAn open source book about design patterns and idioms in the Rust programming\nlanguage that you c"
},
{
"path": "book.toml",
"chars": 1497,
"preview": "[book]\ntitle = \"Rust Design Patterns\"\nauthors = [\"the rust-unofficial authors\"]\ndescription = \"A catalogue of Rust desig"
},
{
"path": "po/es.po",
"chars": 343889,
"preview": "\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Rust Design Patterns\\n\"\n\"POT-Creation-Date: \\n\"\n\"PO-Revision-Date: 2023-04-08 2"
},
{
"path": "po/it.po",
"chars": 344796,
"preview": "\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Rust Design Patterns\\n\"\n\"POT-Creation-Date: \\n\"\n\"PO-Revision-Date: 2023-04-08 2"
},
{
"path": "po/messages.pot",
"chars": 193320,
"preview": "\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Rust Design Patterns\\n\"\n\"POT-Creation-Date: 2025-05-17T14:07:35+09:00\\n\"\n\"PO-Re"
},
{
"path": "po/pt-BR.po",
"chars": 339336,
"preview": "\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Rust Design Patterns\\n\"\n\"POT-Creation-Date: \\n\"\n\"PO-Revision-Date: 2023-04-08 2"
},
{
"path": "src/SUMMARY.md",
"chars": 2851,
"preview": "# Summary\n\n- [Introduction](./intro.md)\n - [Translations](./translations.md)\n- [Idioms](./idioms/index.md)\n - [Use bor"
},
{
"path": "src/additional_resources/design-principles.md",
"chars": 4664,
"preview": "# Design principles\n\n## A brief overview over common design principles\n\n---\n\n## [SOLID](https://en.wikipedia.org/wiki/SO"
},
{
"path": "src/additional_resources/index.md",
"chars": 535,
"preview": "# Additional resources\n\nA collection of complementary helpful content\n\n## Talks\n\n- [Design Patterns in Rust](https://www"
},
{
"path": "src/anti_patterns/borrow_clone.md",
"chars": 2881,
"preview": "# Clone to satisfy the borrow checker\n\n## Description\n\nThe borrow checker prevents Rust users from developing otherwise "
},
{
"path": "src/anti_patterns/deny-warnings.md",
"chars": 3440,
"preview": "# `#![deny(warnings)]`\n\n## Description\n\nA well-intentioned crate author wants to ensure their code builds without\nwarnin"
},
{
"path": "src/anti_patterns/deref.md",
"chars": 4239,
"preview": "# `Deref` polymorphism\n\n## Description\n\nMisuse the `Deref` trait to emulate inheritance between structs, and thus reuse\n"
},
{
"path": "src/anti_patterns/index.md",
"chars": 452,
"preview": "# Anti-patterns\n\nAn [anti-pattern](https://en.wikipedia.org/wiki/Anti-pattern) is a solution to a\n\"recurring problem tha"
},
{
"path": "src/functional/generics-type-classes.md",
"chars": 10140,
"preview": "# Generics as Type Classes\n\n## Description\n\nRust's type system is designed more like functional languages (like Haskell)"
},
{
"path": "src/functional/index.md",
"chars": 530,
"preview": "# Functional Usage of Rust\n\nRust is an imperative language, but it follows many\n[functional programming](https://en.wiki"
},
{
"path": "src/functional/optics.md",
"chars": 16181,
"preview": "# Functional Language Optics\n\nOptics is a type of API design that is common to functional languages. This is a\npure func"
},
{
"path": "src/functional/paradigms.md",
"chars": 1994,
"preview": "# Programming paradigms\n\nOne of the biggest hurdles to understanding functional programs when coming from\nan imperative "
},
{
"path": "src/idioms/coercion-arguments.md",
"chars": 4768,
"preview": "# Use borrowed types for arguments\n\n## Description\n\nUsing a target of a deref coercion can increase the flexibility of y"
},
{
"path": "src/idioms/concat-format.md",
"chars": 933,
"preview": "# Concatenating strings with `format!`\n\n## Description\n\nIt is possible to build up strings using the `push` and `push_st"
},
{
"path": "src/idioms/ctor.md",
"chars": 2859,
"preview": "# Constructors\n\n## Description\n\nRust does not have constructors as a language construct. Instead, the convention\nis to u"
},
{
"path": "src/idioms/default.md",
"chars": 2283,
"preview": "# The `Default` Trait\n\n## Description\n\nMany types in Rust have a [constructor]. However, this is *specific* to the\ntype;"
},
{
"path": "src/idioms/deref.md",
"chars": 2820,
"preview": "# Collections are smart pointers\n\n## Description\n\nUse the [`Deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html) "
},
{
"path": "src/idioms/dtor-finally.md",
"chars": 3602,
"preview": "# Finalisation in destructors\n\n## Description\n\nRust does not provide the equivalent to `finally` blocks - code that will"
},
{
"path": "src/idioms/ffi/accepting-strings.md",
"chars": 4562,
"preview": "# Accepting Strings\n\n## Description\n\nWhen accepting strings via FFI through pointers, there are two principles that\nshou"
},
{
"path": "src/idioms/ffi/errors.md",
"chars": 3567,
"preview": "# Error Handling in FFI\n\n## Description\n\nIn foreign languages like C, errors are represented by return codes. However,\nR"
},
{
"path": "src/idioms/ffi/intro.md",
"chars": 512,
"preview": "# FFI Idioms\n\nWriting FFI code is an entire course in itself. However, there are several\nidioms here that can act as poi"
},
{
"path": "src/idioms/ffi/passing-strings.md",
"chars": 3264,
"preview": "# Passing Strings\n\n## Description\n\nWhen passing strings to FFI functions, there are four principles that should be\nfollo"
},
{
"path": "src/idioms/index.md",
"chars": 829,
"preview": "# Idioms\n\n[Idioms](https://en.wikipedia.org/wiki/Programming_idiom) are commonly used\nstyles, guidelines and patterns la"
},
{
"path": "src/idioms/mem-replace.md",
"chars": 3963,
"preview": "# `mem::{take(_), replace(_)}` to keep owned values in changed enums\n\n## Description\n\nSay we have a `&mut MyEnum` which "
},
{
"path": "src/idioms/on-stack-dyn-dispatch.md",
"chars": 2730,
"preview": "# On-Stack Dynamic Dispatch\n\n## Description\n\nWe can dynamically dispatch over multiple values, however, to do so, we nee"
},
{
"path": "src/idioms/option-iter.md",
"chars": 2079,
"preview": "# Iterating over an `Option`\n\n## Description\n\n`Option` can be viewed as a container that contains either zero or one ele"
},
{
"path": "src/idioms/pass-var-to-closure.md",
"chars": 1297,
"preview": "# Pass variables to closure\n\n## Description\n\nBy default, closures capture their environment by borrowing. Or you can use"
},
{
"path": "src/idioms/priv-extend.md",
"chars": 4539,
"preview": "# `#[non_exhaustive]` and private fields for extensibility\n\n## Description\n\nA small set of scenarios exist where a libra"
},
{
"path": "src/idioms/return-consumed-arg-on-error.md",
"chars": 1599,
"preview": "# Return consumed argument on error\n\n## Description\n\nIf a fallible function consumes (moves) an argument, return that ar"
},
{
"path": "src/idioms/rustdoc-init.md",
"chars": 2657,
"preview": "# Easy doc initialization\n\n## Description\n\nIf a struct takes significant effort to initialize when writing docs, it can "
},
{
"path": "src/idioms/temporary-mutability.md",
"chars": 896,
"preview": "# Temporary mutability\n\n## Description\n\nOften it is necessary to prepare and process some data, but after that data are\n"
},
{
"path": "src/intro.md",
"chars": 2377,
"preview": "# Introduction\n\n## Participation\n\nIf you are interested in contributing to this book, check out the\n[contribution guidel"
},
{
"path": "src/patterns/behavioural/RAII.md",
"chars": 3643,
"preview": "# RAII with guards\n\n## Description\n\n[RAII][wikipedia] stands for \"Resource Acquisition is Initialisation\" which is a\nter"
},
{
"path": "src/patterns/behavioural/command.md",
"chars": 6459,
"preview": "# Command\n\n## Description\n\nThe basic idea of the Command pattern is to separate out actions into its own\nobjects and pas"
},
{
"path": "src/patterns/behavioural/interpreter.md",
"chars": 4488,
"preview": "# Interpreter\n\n## Description\n\nIf a problem occurs very often and requires long and repetitive steps to solve\nit, then t"
},
{
"path": "src/patterns/behavioural/intro.md",
"chars": 252,
"preview": "# Behavioural Patterns\n\nFrom [Wikipedia](https://en.wikipedia.org/wiki/Behavioral_pattern):\n\n> Design patterns that iden"
},
{
"path": "src/patterns/behavioural/newtype.md",
"chars": 3693,
"preview": "# Newtype\n\nWhat if in some cases we want a type to behave similar to another type or\nenforce some behaviour at compile t"
},
{
"path": "src/patterns/behavioural/strategy.md",
"chars": 6088,
"preview": "# Strategy (aka Policy)\n\n## Description\n\nThe [Strategy design pattern](https://en.wikipedia.org/wiki/Strategy_pattern) i"
},
{
"path": "src/patterns/behavioural/visitor.md",
"chars": 3170,
"preview": "# Visitor\n\n## Description\n\nA visitor encapsulates an algorithm that operates over a heterogeneous\ncollection of objects."
},
{
"path": "src/patterns/creational/builder.md",
"chars": 3635,
"preview": "# Builder\n\n## Description\n\nConstruct an object with calls to a builder helper.\n\n## Example\n\n```rust\n#[derive(Debug, Part"
},
{
"path": "src/patterns/creational/fold.md",
"chars": 4436,
"preview": "# Fold\n\n## Description\n\nRun an algorithm over each item in a collection of data to create a new item,\nthus creating a wh"
},
{
"path": "src/patterns/creational/intro.md",
"chars": 420,
"preview": "# Creational Patterns\n\nFrom [Wikipedia](https://en.wikipedia.org/wiki/Creational_pattern):\n\n> Design patterns that deal "
},
{
"path": "src/patterns/ffi/export.md",
"chars": 10180,
"preview": "# Object-Based APIs\n\n## Description\n\nWhen designing APIs in Rust which are exposed to other languages, there are some\nim"
},
{
"path": "src/patterns/ffi/intro.md",
"chars": 524,
"preview": "# FFI Patterns\n\nWriting FFI code is an entire course in itself. However, there are several\nidioms here that can act as p"
},
{
"path": "src/patterns/ffi/wrappers.md",
"chars": 5830,
"preview": "# Type Consolidation into Wrappers\n\n## Description\n\nThis pattern is designed to allow gracefully handling multiple relat"
},
{
"path": "src/patterns/index.md",
"chars": 1349,
"preview": "# Design Patterns\n\n[Design patterns](https://en.wikipedia.org/wiki/Software_design_pattern) are\n\"general reusable soluti"
},
{
"path": "src/patterns/structural/compose-structs.md",
"chars": 4165,
"preview": "# Struct decomposition for independent borrowing\n\n## Description\n\nSometimes a large struct will cause issues with the bo"
},
{
"path": "src/patterns/structural/intro.md",
"chars": 202,
"preview": "# Structural Patterns\n\nFrom [Wikipedia](https://en.wikipedia.org/wiki/Structural_pattern):\n\n> Design patterns that ease "
},
{
"path": "src/patterns/structural/small-crates.md",
"chars": 1941,
"preview": "# Prefer small crates\n\n## Description\n\nPrefer small crates that do one thing well.\n\nCargo and crates.io make it easy to "
},
{
"path": "src/patterns/structural/trait-for-bounds.md",
"chars": 3730,
"preview": "# Use custom traits to avoid complex type bounds\n\n## Description\n\nTrait bounds can become somewhat unwieldy, especially "
},
{
"path": "src/patterns/structural/unsafe-mods.md",
"chars": 1372,
"preview": "# Contain unsafety in small modules\n\n## Description\n\nIf you have `unsafe` code, create the smallest possible module that"
},
{
"path": "src/refactoring/index.md",
"chars": 703,
"preview": "# Refactoring\n\nRefactoring is very important in relation to these topics. Just as important as\nthe other topics covered "
},
{
"path": "src/translations.md",
"chars": 468,
"preview": "# Translations\n\nWe are utilizing\n[mdbook-i18n-helper](https://github.com/google/mdbook-i18n-helpers). Please read\nup on "
},
{
"path": "styles/last-changed.css",
"chars": 126,
"preview": "footer {\n font-size: 0.8em;\n text-align: center;\n border-top: 1px solid grey;\n padding: 1.25em 0;\n margin-top: 1.25"
},
{
"path": "template.md",
"chars": 1016,
"preview": "# A succinct name for the pattern\n\n## Description\n\nA short, prose description of the pattern.\n\n## Example\n\n```rust\n// An"
},
{
"path": "theme/css/language-picker.css",
"chars": 149,
"preview": "#language-list {\n left: auto;\n right: 10px;\n}\n\n[dir=\"rtl\"] #language-list {\n left: 10px;\n right: auto;\n}\n\n#language-"
},
{
"path": "theme/head.hbs",
"chars": 1069,
"preview": "{{! Move to template code after fixing this issue:\n https://github.com/google/mdbook-i18n-helpers/issues/70 }}\n<scrip"
},
{
"path": "theme/index.hbs",
"chars": 16842,
"preview": "<!DOCTYPE HTML>\n<html lang=\"{{ language }}\" class=\"{{ default_theme }} sidebar-visible\" dir=\"{{ text_direction }}\">\n "
},
{
"path": "third_party/mdbook/LICENSE",
"chars": 15921,
"preview": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. \"Contributor\"\n\n means each individual or legal entity that"
},
{
"path": "third_party/mdbook/README.md",
"chars": 224,
"preview": "# mdBook\n\nThis directory contains files copied from mdBook. Please see\n<https://github.com/rust-lang/mdBook/> for the fu"
},
{
"path": "third_party/mdbook/book.js",
"chars": 26922,
"preview": "\"use strict\";\n\n/* global default_theme, default_dark_theme, default_light_theme, hljs, ClipboardJS */\n\n// Fix back butto"
}
]
About this extraction
This page contains the full source code of the rust-unofficial/patterns GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 80 files (1.4 MB), approximately 408.7k tokens, and a symbol index with 24 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.