1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2024-11-29 02:12:05 +02:00

pt-BR: Some updates and fixes (#994)

pt-BR: Some updates and fixes to the
Brazilian Portuguese translation.
This commit is contained in:
Henri Fontana 2023-07-18 03:10:24 -07:00 committed by GitHub
parent 2f86a259b6
commit b0380e1f0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,7 +2,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Comprehensive Rust 🦀\n" "Project-Id-Version: Comprehensive Rust 🦀\n"
"POT-Creation-Date: \n" "POT-Creation-Date: \n"
"PO-Revision-Date: 2023-07-13 16:10-0700\n" "PO-Revision-Date: 2023-07-17 12:30-0700\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"Language: pt_BR\n" "Language: pt_BR\n"
@ -141,7 +141,7 @@ msgstr "Conversões Implícitas"
#: src/SUMMARY.md:39 #: src/SUMMARY.md:39
msgid "Arrays and for Loops" msgid "Arrays and for Loops"
msgstr "Vetores e Laços For" msgstr "Matrizes e Loops for"
#: src/SUMMARY.md:41 #: src/SUMMARY.md:41
msgid "Day 1: Afternoon" msgid "Day 1: Afternoon"
@ -185,11 +185,11 @@ msgstr "Gerenciamento de Memória Baseado em Escopo"
#: src/SUMMARY.md:52 #: src/SUMMARY.md:52
msgid "Garbage Collection" msgid "Garbage Collection"
msgstr "Garbage Collection (Coletor de lixo)" msgstr "Gerenciamento Automático de Memória"
#: src/SUMMARY.md:53 #: src/SUMMARY.md:53
msgid "Rust Memory Management" msgid "Rust Memory Management"
msgstr "Gerenciamento de Memória do Rust" msgstr "Gerenciamento de Memória no Rust"
#: src/SUMMARY.md:54 #: src/SUMMARY.md:54
msgid "Comparison" msgid "Comparison"
@ -201,7 +201,7 @@ msgstr "Ownership"
#: src/SUMMARY.md:56 #: src/SUMMARY.md:56
msgid "Move Semantics" msgid "Move Semantics"
msgstr "Semântica do move (mover)" msgstr "Semântica do Move (mover)"
#: src/SUMMARY.md:57 #: src/SUMMARY.md:57
msgid "Moved Strings in Rust" msgid "Moved Strings in Rust"
@ -257,7 +257,7 @@ msgstr "Structs"
#: src/SUMMARY.md:77 #: src/SUMMARY.md:77
msgid "Tuple Structs" msgid "Tuple Structs"
msgstr "Structs como Tuplas" msgstr "Estruturas de Tuplas (Tuple Structs)"
#: src/SUMMARY.md:78 #: src/SUMMARY.md:78
msgid "Field Shorthand Syntax" msgid "Field Shorthand Syntax"
@ -301,7 +301,7 @@ msgstr "Desestruturando Matrizes"
#: src/SUMMARY.md:89 #: src/SUMMARY.md:89
msgid "Match Guards" msgid "Match Guards"
msgstr "Guardas de Correspondência (match)" msgstr "Guardas de Correspondência (Match Guards)"
#: src/SUMMARY.md:91 #: src/SUMMARY.md:91
msgid "Health Statistics" msgid "Health Statistics"
@ -3413,7 +3413,7 @@ msgid ""
"* We create a slice by borrowing `a` and specifying the starting and ending " "* We create a slice by borrowing `a` and specifying the starting and ending "
"indexes in brackets.\n" "indexes in brackets.\n"
"\n" "\n"
"* If the slice starts at index 0, Rust's range syntax allows us to drop the " "* If the slice starts at index 0, Rusts range syntax allows us to drop the "
"starting index, meaning that `&a[0..a.len()]` and `&a[..a.len()]` are " "starting index, meaning that `&a[0..a.len()]` and `&a[..a.len()]` are "
"identical.\n" "identical.\n"
" \n" " \n"
@ -3490,10 +3490,10 @@ msgid ""
msgstr "" msgstr ""
"```rust,editable\n" "```rust,editable\n"
"fn main() {\n" "fn main() {\n"
" let s1: &str = \"World\";\n" " let s1: &str = \"Mundo\";\n"
" println!(\"s1: {s1}\");\n" " println!(\"s1: {s1}\");\n"
"\n" "\n"
" let mut s2: String = String::from(\"Hello \");\n" " let mut s2: String = String::from(\"Olá \");\n"
" println!(\"s2: {s2}\");\n" " println!(\"s2: {s2}\");\n"
" s2.push_str(s1);\n" " s2.push_str(s1);\n"
" println!(\"s2: {s2}\");\n" " println!(\"s2: {s2}\");\n"
@ -3615,6 +3615,33 @@ msgid ""
"}\n" "}\n"
"```" "```"
msgstr "" msgstr ""
"```rust,editable\n"
"fn main() {\n"
" imprimir_fizzbuzz_para(20);\n"
"}\n"
"\n"
"fn eh_divisivel(n: u32, divisor: u32) -> bool {\n"
" if divisor == 0 {\n"
" return false;\n"
" }\n"
" n % divisor == 0\n"
"}\n"
"\n"
"fn fizzbuzz(n: u32) -> String {\n"
" let fizz = if eh_divisivel(n, 3) { \"fizz\" } else { \"\" };\n"
" let buzz = if eh_divisivel(n, 5) { \"buzz\" } else { \"\" };\n"
" if fizz.is_empty() && buzz.is_empty() {\n"
" return format!(\"{n}\");\n"
" }\n"
" format!(\"{fizz}{buzz}\")\n"
"}\n"
"\n"
"fn imprimir_fizzbuzz_para(n: u32) {\n"
" for i in 1..=n {\n"
" println!(\"{}\", fizzbuzz(i));\n"
" }\n"
"}\n"
"```"
#: src/basic-syntax/functions.md:35 #: src/basic-syntax/functions.md:35
msgid "" msgid ""
@ -3638,8 +3665,8 @@ msgstr ""
"* Algumas funções não têm valor de retorno e retornam o 'tipo unitário', " "* Algumas funções não têm valor de retorno e retornam o 'tipo unitário', "
"`()`. O compilador irá inferir isso se o tipo de retorno `-> ()` for " "`()`. O compilador irá inferir isso se o tipo de retorno `-> ()` for "
"omitido.\n" "omitido.\n"
"* A expressão de intervalo no loop `for` em `fizzbuzz_to()` contém `=n`, o " "* A expressão de intervalo no loop `for` em `imprimir_fizzbuzz_para()` "
"que faz com que inclua o limite superior." "contém `=n`, o que faz com que inclua o limite superior."
#: src/basic-syntax/rustdoc.md:1 #: src/basic-syntax/rustdoc.md:1
msgid "# Rustdoc" msgid "# Rustdoc"
@ -3672,7 +3699,7 @@ msgstr ""
"/// Determine se o primeiro argumento é divisível pelo segundo argumento.\n" "/// Determine se o primeiro argumento é divisível pelo segundo argumento.\n"
"///\n" "///\n"
"/// Se o segundo argumento for zero, o resultado é falso.\n" "/// Se o segundo argumento for zero, o resultado é falso.\n"
"fn is_divisible_by(lhs: u32, rhs: u32) -> bool {\n" "fn divisivel_por(lhs: u32, rhs: u32) -> bool {\n"
" if rhs == 0 {\n" " if rhs == 0 {\n"
" return false; // Caso excepcional, retorne antes\n" " return false; // Caso excepcional, retorne antes\n"
" }\n" " }\n"
@ -3895,7 +3922,7 @@ msgid ""
msgstr "" msgstr ""
"* Conversões implícitas entre tipos.\n" "* Conversões implícitas entre tipos.\n"
"\n" "\n"
"* Matrizes (_Arrays_) e laços (loops) `for`." "* Matrizes (_Arrays_) e _loops_ (laços) `for`."
#: src/exercises/day-1/morning.md:11 #: src/exercises/day-1/morning.md:11
msgid "A few things to consider while solving the exercises:" msgid "A few things to consider while solving the exercises:"
@ -4055,7 +4082,7 @@ msgstr ""
#: src/exercises/day-1/for-loops.md:1 #: src/exercises/day-1/for-loops.md:1
msgid "# Arrays and `for` Loops" msgid "# Arrays and `for` Loops"
msgstr "# Matrizes (Arrays) e Laços (Loops) `for`" msgstr "# Matrizes (_Arrays_) e _Loops_ (Laços) `for`"
#: src/exercises/day-1/for-loops.md:3 #: src/exercises/day-1/for-loops.md:3
msgid "We saw that an array can be declared like this:" msgid "We saw that an array can be declared like this:"
@ -4429,7 +4456,8 @@ msgid ""
"Globally-scoped names for values can be given with static variables and " "Globally-scoped names for values can be given with static variables and "
"constant definitions." "constant definitions."
msgstr "" msgstr ""
"Nomes com escopo global podem ser dados com variáveis estáticas e constantes." "Nomes com escopo global podem ser obtidos por meio de variáveis estáticas e "
"definições de constantes."
#: src/basic-syntax/static-and-const.md:5 #: src/basic-syntax/static-and-const.md:5
msgid "## `const`" msgid "## `const`"
@ -4534,6 +4562,10 @@ msgid ""
"Because `static` variables are accessible from any thread, mutable static " "Because `static` variables are accessible from any thread, mutable static "
"variables require manual, unsafe, synchronization of accesses." "variables require manual, unsafe, synchronization of accesses."
msgstr "" msgstr ""
"Nós iremos ver [dados estáticos mutáveis](../unsafe/mutable-static-variables."
"md) no capítulo sobre Rust _inseguro_.\n"
"Variáveis estáticas mutáveis são acessíveis por qualquer _thread_ e por isso "
"necessitam de sincronização de acessos manual e insegura (_unsafe_)."
#: src/basic-syntax/static-and-const.md:50 #: src/basic-syntax/static-and-const.md:50
msgid "" msgid ""
@ -4836,8 +4868,8 @@ msgid ""
"If not done with care, this can lead to crashes, bugs, security " "If not done with care, this can lead to crashes, bugs, security "
"vulnerabilities, and memory leaks." "vulnerabilities, and memory leaks."
msgstr "" msgstr ""
"Se não for feito com cuidado, isso pode levar a travamentos, bugs, " "Se isto não for feito com cuidado, travamentos, bugs, vulnerabilidades de "
"vulnerabilidades de segurança e vazamentos de memória." "segurança e vazamentos de memória podem ocorrer."
#: src/memory-management/manual.md:7 #: src/memory-management/manual.md:7
msgid "## C Example" msgid "## C Example"
@ -5035,8 +5067,7 @@ msgstr ""
#: src/memory-management/rust.md:10 #: src/memory-management/rust.md:10
msgid "Rust achieves this by modeling _ownership_ explicitly." msgid "Rust achieves this by modeling _ownership_ explicitly."
msgstr "" msgstr "O Rust consegue isso modelando o _ownership_ (posse) explicitamente."
"O Rust consegue isso modelando a propriedade (_ownership_) explicitamente."
#: src/memory-management/rust.md:14 #: src/memory-management/rust.md:14
msgid "" msgid ""
@ -5185,7 +5216,7 @@ msgstr "# Semântica do `Move` (Mover)"
#: src/ownership/move-semantics.md:3 #: src/ownership/move-semantics.md:3
msgid "An assignment will transfer ownership between variables:" msgid "An assignment will transfer ownership between variables:"
msgstr "Uma atribuição transferirá a _ownership_ entre variáveis:" msgstr "Uma atribuição transferirá o _ownership_ entre variáveis:"
#: src/ownership/move-semantics.md:5 #: src/ownership/move-semantics.md:5
msgid "" msgid ""
@ -5215,7 +5246,7 @@ msgid ""
"* When `s2` goes out of scope, the string data is freed.\n" "* When `s2` goes out of scope, the string data is freed.\n"
"* There is always _exactly_ one variable binding which owns a value." "* There is always _exactly_ one variable binding which owns a value."
msgstr "" msgstr ""
"* A atribuição de `s1` a `s2` transfere a _ownership_.\n" "* A atribuição de `s1` a `s2` transfere o _ownership_.\n"
"* Os dados foram _movidos_ de `s1` e `s1` não está mais acessível.\n" "* Os dados foram _movidos_ de `s1` e `s1` não está mais acessível.\n"
"* Quando `s1` sai do escopo, nada acontece: ele não tem _ownership_.\n" "* Quando `s1` sai do escopo, nada acontece: ele não tem _ownership_.\n"
"* Quando `s2` sai do escopo, os dados da string são liberados.\n" "* Quando `s2` sai do escopo, os dados da string são liberados.\n"
@ -5564,8 +5595,8 @@ msgid ""
"struct Point(i32, i32);\n" "struct Point(i32, i32);\n"
"\n" "\n"
"fn main() {\n" "fn main() {\n"
" let p2 = p1;\n"
" let p1 = Point(3, 4);\n" " let p1 = Point(3, 4);\n"
" let p2 = p1;\n"
" println!(\"p1: {p1:?}\");\n" " println!(\"p1: {p1:?}\");\n"
" println!(\"p2: {p2:?}\");\n" " println!(\"p2: {p2:?}\");\n"
"}\n" "}\n"
@ -6643,7 +6674,7 @@ msgstr ""
#: src/structs.md:1 #: src/structs.md:1
msgid "# Structs" msgid "# Structs"
msgstr "# Estruturas (Structs)" msgstr "# _Structs_ (Estruturas)"
#: src/structs.md:3 #: src/structs.md:3
msgid "Like C and C++, Rust has support for custom structs:" msgid "Like C and C++, Rust has support for custom structs:"
@ -6742,7 +6773,7 @@ msgstr ""
#: src/structs/tuple-structs.md:1 #: src/structs/tuple-structs.md:1
msgid "# Tuple Structs" msgid "# Tuple Structs"
msgstr "# Estruturas Tupla (Tuple Structs)" msgstr "# Estruturas de Tuplas (_Tuple Structs_)"
#: src/structs/tuple-structs.md:3 #: src/structs/tuple-structs.md:3
msgid "If the field names are unimportant, you can use a tuple struct:" msgid "If the field names are unimportant, you can use a tuple struct:"
@ -6802,7 +6833,7 @@ msgstr ""
"struct Newtons(f64);\n" "struct Newtons(f64);\n"
"\n" "\n"
"fn calcular_forca_nas_turbinas() -> LibrasDeForca {\n" "fn calcular_forca_nas_turbinas() -> LibrasDeForca {\n"
" todo!(“Pergunte para um cientista de foguetes da NASA”)\n" " todo!(\"Pergunte para um cientista de foguetes da NASA\")\n"
"}\n" "}\n"
"\n" "\n"
"fn definir_forca_nas_turbinas(force: Newtons) {\n" "fn definir_forca_nas_turbinas(force: Newtons) {\n"
@ -6826,20 +6857,20 @@ msgid ""
"`OddNumber(u32)`.\n" "`OddNumber(u32)`.\n"
"* Demonstrate how to add a `f64` value to a `Newtons` type by accessing the " "* Demonstrate how to add a `f64` value to a `Newtons` type by accessing the "
"single field in the newtype.\n" "single field in the newtype.\n"
" * Rust generally doesn't like inexplicit things, like automatic " " * Rust generally doesnt like inexplicit things, like automatic "
"unwrapping or for instance using booleans as integers.\n" "unwrapping or for instance using booleans as integers.\n"
" * Operator overloading is discussed on Day 3 (generics).\n" " * Operator overloading is discussed on Day 3 (generics).\n"
"* The example is a subtle reference to the [Mars Climate Orbiter](https://en." "* The example is a subtle reference to the [Mars Climate Orbiter](https://en."
"wikipedia.org/wiki/Mars_Climate_Orbiter) failure." "wikipedia.org/wiki/Mars_Climate_Orbiter) failure."
msgstr "" msgstr ""
"_Newtypes_ são uma ótima maneira de codificar informações adicionais sobre o " "* _Newtypes_ são uma ótima maneira de codificar informações adicionais sobre "
"valor em um tipo primitivo, por exemplo:\n" "o valor em um tipo primitivo, por exemplo:\n"
" * O número é medido em alguma unidade: `Newtons` no exemplo acima.\n" " * O número é medido em algumas unidades: `Newtons` no exemplo acima.\n"
" * O valor passou por alguma validação quando foi criado, então não é " " * O valor passou por alguma validação quando foi criado, então não é "
"preciso validá-lo novamente a cada uso: `NumeroTelefone(String)` ou " "preciso validá-lo novamente a cada uso: `NumeroTelefone(String)` ou "
"`NumeroImpar(u32)`.\n" "`NumeroImpar(u32)`.\n"
"* Demonstre como somar um valor `f64` em um valor do tipo `Newtons` " "* Demonstre como somar um valor `f64` em um valor do tipo `Newtons` "
"acessando o campo único do _newtype_.\n" "acessando o campo único no _newtype_.\n"
" * Geralmente, Rust não gosta de coisas implícitas, como _unwrapping_ " " * Geralmente, Rust não gosta de coisas implícitas, como _unwrapping_ "
"automático ou, por exemplo, usar booleanos como inteiros.\n" "automático ou, por exemplo, usar booleanos como inteiros.\n"
" * Sobrecarga de operadores é discutido no Dia 3 (_generics_).\n" " * Sobrecarga de operadores é discutido no Dia 3 (_generics_).\n"
@ -6992,10 +7023,10 @@ msgstr ""
" ```\n" " ```\n"
"\n" "\n"
"* Métodos são definidos no bloco `impl`.\n" "* Métodos são definidos no bloco `impl`.\n"
"* Use struct update syntax to define a new structure using `peter`. Note " "* Use a sintaxe de atualização de estruturas para definir uma nova `struct` "
"that the variable `peter` will no longer be accessible afterwards.\n" "usando `pedro`. Note que a variável `pedro` não será mais acessível após.\n"
"* Utilize `{:#?}` para imprimir _structs_ para utilizar a representação " "* Utilize `{:#?}` para imprimir _structs_ utilizando a representação de "
"`Debug` (de Depuração)." "depuração (`Debug`)."
#: src/enums.md:1 #: src/enums.md:1
msgid "# Enums" msgid "# Enums"
@ -7007,7 +7038,7 @@ msgid ""
"different variants:" "different variants:"
msgstr "" msgstr ""
"A palavra-chave `enum` permite a criação de um tipo que possui algumas\n" "A palavra-chave `enum` permite a criação de um tipo que possui algumas\n"
"variações diferentes:" "variantes diferentes:"
#: src/enums.md:6 #: src/enums.md:6
msgid "" msgid ""
@ -7215,7 +7246,7 @@ msgid ""
"Rust enums are packed tightly, taking constraints due to alignment into " "Rust enums are packed tightly, taking constraints due to alignment into "
"account:" "account:"
msgstr "" msgstr ""
"Enums, em Rust, são empacotados firmemente, levando em consideração as " "Enums, em Rust, são agrupados de maneira compacta, levando em consideração "
"restrições devido ao alinhamento:" "restrições devido ao alinhamento:"
#: src/enums/sizes.md:5 #: src/enums/sizes.md:5
@ -8277,7 +8308,7 @@ msgstr ""
#: src/exercises/day-2/health-statistics.md:1 #: src/exercises/day-2/health-statistics.md:1
msgid "# Health Statistics" msgid "# Health Statistics"
msgstr "# Estatísticas de saúde" msgstr "# Estatísticas de Saúde"
#: src/exercises/day-2/health-statistics.md:3 #: src/exercises/day-2/health-statistics.md:3
msgid "" msgid ""
@ -8312,7 +8343,6 @@ msgstr ""
"que estão faltando:" "que estão faltando:"
#: src/exercises/day-2/health-statistics.md:13 #: src/exercises/day-2/health-statistics.md:13
#, fuzzy
msgid "" msgid ""
"```rust,should_panic\n" "```rust,should_panic\n"
"// TODO: remove this when you're done with your implementation.\n" "// TODO: remove this when you're done with your implementation.\n"
@ -8422,6 +8452,20 @@ msgstr ""
" nome: String,\n" " nome: String,\n"
" idade: u32,\n" " idade: u32,\n"
" peso: f32,\n" " peso: f32,\n"
" num_visitas: usize,\n"
" ult_pressao_sang: Option<(u32, u32)>,\n"
"}\n"
"\n"
"pub struct Medicoes {\n"
" altura: f32,\n"
" pressao_sangue: (u32, u32),\n"
"}\n"
"\n"
"pub struct RelatorioSaude<'a> {\n"
" nome_paciente: &'a str,\n"
" num_visitas: u32,\n"
" dif_altura: f32,\n"
" dif_pressao_sangue: Option<(i32, i32)>,\n"
"}\n" "}\n"
"\n" "\n"
"impl Usuario {\n" "impl Usuario {\n"
@ -8437,7 +8481,11 @@ msgstr ""
" unimplemented!()\n" " unimplemented!()\n"
" }\n" " }\n"
"\n" "\n"
" pub fn peso(&self) -> f32 {\n" " pub fn altura(&self) -> f32 {\n"
" unimplemented!()\n"
" }\n"
"\n"
" pub fn visitas_medico(&self) -> u32 {\n"
" unimplemented!()\n" " unimplemented!()\n"
" }\n" " }\n"
"\n" "\n"
@ -8445,7 +8493,7 @@ msgstr ""
" unimplemented!()\n" " unimplemented!()\n"
" }\n" " }\n"
"\n" "\n"
" pub fn definir_peso(&mut self, novo_peso: f32) {\n" " pub fn definir_altura(&mut self, novo_altura: f32) {\n"
" unimplemented!()\n" " unimplemented!()\n"
" }\n" " }\n"
"}\n" "}\n"
@ -8456,13 +8504,13 @@ msgstr ""
"}\n" "}\n"
"\n" "\n"
"#[test]\n" "#[test]\n"
"fn test_peso() {\n" "fn test_altura() {\n"
" let beto = Usuario::new(String::from(\"Beto\"), 32, 155.2);\n" " let beto = Usuario::new(String::from(\"Beto\"), 32, 155.2);\n"
" assert_eq!(beto.peso(), 155.2);\n" " assert_eq!(beto.altura(), 155.2);\n"
"}\n" "}\n"
"\n" "\n"
"#[test]\n" "#[test]\n"
"fn test_set_age() {\n" "fn test_definir_idade() {\n"
" let mut beto = Usuario::new(String::from(\"Beto\"), 32, 155.2);\n" " let mut beto = Usuario::new(String::from(\"Beto\"), 32, 155.2);\n"
" assert_eq!(beto.idade(), 32);\n" " assert_eq!(beto.idade(), 32);\n"
" beto.definir_idade(33);\n" " beto.definir_idade(33);\n"
@ -8472,7 +8520,7 @@ msgstr ""
#: src/exercises/day-2/points-polygons.md:1 #: src/exercises/day-2/points-polygons.md:1
msgid "# Polygon Struct" msgid "# Polygon Struct"
msgstr "# Estrutura para polígono" msgstr "# _Struct_ para Polígono"
#: src/exercises/day-2/points-polygons.md:3 #: src/exercises/day-2/points-polygons.md:3
msgid "" msgid ""
@ -8482,7 +8530,7 @@ msgid ""
"the\n" "the\n"
"tests pass:" "tests pass:"
msgstr "" msgstr ""
"Vamos criar uma estrutura `Poligono` que contém alguns `Pontos`. Copie o " "Vamos criar um _struct_ `Poligono` que contém alguns `Pontos`. Copie o "
"código abaixo\n" "código abaixo\n"
"em <https://play.rust-lang.org/> e preencha os métodos que faltam para fazer " "em <https://play.rust-lang.org/> e preencha os métodos que faltam para fazer "
"os\n" "os\n"
@ -10701,7 +10749,7 @@ msgid ""
"\n" "\n"
" ```rust,ignore\n" " ```rust,ignore\n"
" #[path = \"some/path.rs\"]\n" " #[path = \"some/path.rs\"]\n"
" mod some_module { }\n" " mod some_module;\n"
" ```\n" " ```\n"
"\n" "\n"
" This is useful, for example, if you would like to place tests for a module " " This is useful, for example, if you would like to place tests for a module "
@ -11065,7 +11113,6 @@ msgid ""
msgstr "" msgstr ""
"Rust oferece suporte a tipos genéricos, que permitem algoritmos ou " "Rust oferece suporte a tipos genéricos, que permitem algoritmos ou "
"estruturas de dados\n" "estruturas de dados\n"
" (como ordenação ou árvore binária)\n" " (como ordenação ou árvore binária)\n"
"abstrair os tipos de dados usados ou armazenados." "abstrair os tipos de dados usados ou armazenados."
@ -11515,7 +11562,6 @@ msgstr ""
" '- - - - - - - - - - - - - - - - - - - - - " " '- - - - - - - - - - - - - - - - - - - - - "
"- - -'\n" "- - -'\n"
"\n" "\n"
"```" "```"
#: src/traits/trait-objects.md:72 #: src/traits/trait-objects.md:72
@ -17085,7 +17131,7 @@ msgid ""
"exist. Once a pin is\n" "exist. Once a pin is\n"
" moved out of the port struct nobody else can take it.\n" " moved out of the port struct nobody else can take it.\n"
" * Changing the configuration of a pin consumes the old pin instance, so you " " * Changing the configuration of a pin consumes the old pin instance, so you "
"can't keep use the old\n" "cant keep use the old\n"
" instance afterwards.\n" " instance afterwards.\n"
" * The type of a value indicates the state that it is in: e.g. in this case, " " * The type of a value indicates the state that it is in: e.g. in this case, "
"the configuration state\n" "the configuration state\n"
@ -18152,9 +18198,9 @@ msgid ""
" writeln!(uart, \"main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})\").unwrap();\n" " writeln!(uart, \"main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})\").unwrap();\n"
"\n" "\n"
" loop {\n" " loop {\n"
" if let Some(b) = uart.read_byte() {\n" " if let Some(byte) = uart.read_byte() {\n"
" uart.write_byte(b);\n" " uart.write_byte(byte);\n"
" match b {\n" " match byte {\n"
" b'\\r' => {\n" " b'\\r' => {\n"
" uart.write_byte(b'\\n');\n" " uart.write_byte(b'\\n');\n"
" }\n" " }\n"
@ -21024,8 +21070,7 @@ msgstr "Seu arquivo `src/main.rs` deve se parecer com isto:"
#: src/exercises/concurrency/link-checker.md:57 #: src/exercises/concurrency/link-checker.md:57
msgid "" msgid ""
"```rust,compile_fail\n" "```rust,compile_fail\n"
"use reqwest::blocking::{get, Response};\n" "use reqwest::{blocking::Client, Url};\n"
"use reqwest::Url;\n"
"use scraper::{Html, Selector};\n" "use scraper::{Html, Selector};\n"
"use thiserror::Error;\n" "use thiserror::Error;\n"
"\n" "\n"
@ -21033,34 +21078,57 @@ msgid ""
"enum Error {\n" "enum Error {\n"
" #[error(\"request error: {0}\")]\n" " #[error(\"request error: {0}\")]\n"
" ReqwestError(#[from] reqwest::Error),\n" " ReqwestError(#[from] reqwest::Error),\n"
" #[error(\"bad http response: {0}\")]\n"
" BadResponse(String),\n"
"}\n" "}\n"
"\n" "\n"
"fn extract_links(response: Response) -> Result<Vec<Url>, Error> {\n" "#[derive(Debug)]\n"
" let base_url = response.url().to_owned();\n" "struct CrawlCommand {\n"
" let document = response.text()?;\n" " url: Url,\n"
" let html = Html::parse_document(&document);\n" " extract_links: bool,\n"
" let selector = Selector::parse(\"a\").unwrap();\n" "}\n"
"\n" "\n"
" let mut valid_urls = Vec::new();\n" "fn visit_page(client: &Client, command: &CrawlCommand) -> Result<Vec<Url>, "
" for element in html.select(&selector) {\n" "Error> {\n"
" if let Some(href) = element.value().attr(\"href\") {\n" " println!(\"Checking {:#}\", command.url);\n"
" match base_url.join(href) {\n" " let response = client.get(command.url.clone()).send()?;\n"
" Ok(url) => valid_urls.push(url),\n" " if !response.status().is_success() {\n"
" Err(err) => {\n" " return Err(Error::BadResponse(response.status().to_string()));\n"
" println!(\"On {base_url}: could not parse {href:?}: " " }\n"
"{err} (ignored)\",);\n" "\n"
" }\n" " let mut link_urls = Vec::new();\n"
" if !command.extract_links {\n"
" return Ok(link_urls);\n"
" }\n"
"\n"
" let base_url = response.url().to_owned();\n"
" let body_text = response.text()?;\n"
" let document = Html::parse_document(&body_text);\n"
"\n"
" let selector = Selector::parse(\"a\").unwrap();\n"
" let href_values = document\n"
" .select(&selector)\n"
" .filter_map(|element| element.value().attr(\"href\"));\n"
" for href in href_values {\n"
" match base_url.join(href) {\n"
" Ok(link_url) => {\n"
" link_urls.push(link_url);\n"
" }\n"
" Err(err) => {\n"
" println!(\"On {base_url:#}: ignored unparsable {href:?}: "
"{err}\");\n"
" }\n" " }\n"
" }\n" " }\n"
" }\n" " }\n"
"\n" " Ok(link_urls)\n"
" Ok(valid_urls)\n"
"}\n" "}\n"
"\n" "\n"
"fn main() {\n" "fn main() {\n"
" let client = Client::new();\n"
" let start_url = Url::parse(\"https://www.google.org\").unwrap();\n" " let start_url = Url::parse(\"https://www.google.org\").unwrap();\n"
" let response = get(start_url).unwrap();\n" " let crawl_command = CrawlCommand{ url: start_url, extract_links: "
" match extract_links(response) {\n" "true };\n"
" match visit_page(&client, &crawl_command) {\n"
" Ok(links) => println!(\"Links: {links:#?}\"),\n" " Ok(links) => println!(\"Links: {links:#?}\"),\n"
" Err(err) => println!(\"Could not extract links: {err:#}\"),\n" " Err(err) => println!(\"Could not extract links: {err:#}\"),\n"
" }\n" " }\n"
@ -21068,11 +21136,11 @@ msgid ""
"```" "```"
msgstr "" msgstr ""
#: src/exercises/concurrency/link-checker.md:100 #: src/exercises/concurrency/link-checker.md:120
msgid "Run the code in `src/main.rs` with" msgid "Run the code in `src/main.rs` with"
msgstr "Execute o código em `src/main.rs` com" msgstr "Execute o código em `src/main.rs` com"
#: src/exercises/concurrency/link-checker.md:102 #: src/exercises/concurrency/link-checker.md:122
#, fuzzy #, fuzzy
msgid "" msgid ""
"```shell\n" "```shell\n"
@ -21083,12 +21151,12 @@ msgstr ""
"$ cargo run\n" "$ cargo run\n"
"```" "```"
#: src/exercises/concurrency/link-checker.md:106 #: src/exercises/concurrency/link-checker.md:126
#: src/exercises/concurrency/chat-app.md:140 #: src/exercises/concurrency/chat-app.md:140
msgid "## Tasks" msgid "## Tasks"
msgstr "## Tarefas" msgstr "## Tarefas"
#: src/exercises/concurrency/link-checker.md:108 #: src/exercises/concurrency/link-checker.md:128
msgid "" msgid ""
"* Use threads to check the links in parallel: send the URLs to be checked to " "* Use threads to check the links in parallel: send the URLs to be checked to "
"a\n" "a\n"
@ -22847,7 +22915,7 @@ msgstr "# Dia 1 Exercícios matinais"
#: src/exercises/day-1/solutions-morning.md:3 #: src/exercises/day-1/solutions-morning.md:3
msgid "## Arrays and `for` Loops" msgid "## Arrays and `for` Loops"
msgstr "## Vetores e laços `for`" msgstr "## Matrizes e Loops `for`"
#: src/exercises/day-1/solutions-morning.md:5 #: src/exercises/day-1/solutions-morning.md:5
msgid "([back to exercise](for-loops.md))" msgid "([back to exercise](for-loops.md))"
@ -24668,6 +24736,211 @@ msgid ""
"```" "```"
msgstr "" msgstr ""
#: src/exercises/concurrency/solutions-morning.md:104
#, fuzzy
msgid "## Link Checker"
msgstr "# Verificador de links _multi-threads_"
#: src/exercises/concurrency/solutions-morning.md:106
#, fuzzy
msgid "([back to exercise](link-checker.md))"
msgstr "([voltar ao exercício](luhn.md))"
#: src/exercises/concurrency/solutions-morning.md:108
msgid ""
"```rust,compile_fail\n"
"// Copyright 2022 Google LLC\n"
"//\n"
"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
"// you may not use this file except in compliance with the License.\n"
"// You may obtain a copy of the License at\n"
"//\n"
"// http://www.apache.org/licenses/LICENSE-2.0\n"
"//\n"
"// Unless required by applicable law or agreed to in writing, software\n"
"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
"// See the License for the specific language governing permissions and\n"
"// limitations under the License.\n"
"\n"
"use std::{sync::Arc, sync::Mutex, sync::mpsc, thread};\n"
"\n"
"// ANCHOR: setup\n"
"use reqwest::{blocking::Client, Url};\n"
"use scraper::{Html, Selector};\n"
"use thiserror::Error;\n"
"\n"
"#[derive(Error, Debug)]\n"
"enum Error {\n"
" #[error(\"request error: {0}\")]\n"
" ReqwestError(#[from] reqwest::Error),\n"
" #[error(\"bad http response: {0}\")]\n"
" BadResponse(String),\n"
"}\n"
"// ANCHOR_END: setup\n"
"\n"
"// ANCHOR: visit_page\n"
"#[derive(Debug)]\n"
"struct CrawlCommand {\n"
" url: Url,\n"
" extract_links: bool,\n"
"}\n"
"\n"
"fn visit_page(client: &Client, command: &CrawlCommand) -> Result<Vec<Url>, "
"Error> {\n"
" println!(\"Checking {:#}\", command.url);\n"
" let response = client.get(command.url.clone()).send()?;\n"
" if !response.status().is_success() {\n"
" return Err(Error::BadResponse(response.status().to_string()));\n"
" }\n"
"\n"
" let mut link_urls = Vec::new();\n"
" if !command.extract_links {\n"
" return Ok(link_urls);\n"
" }\n"
"\n"
" let base_url = response.url().to_owned();\n"
" let body_text = response.text()?;\n"
" let document = Html::parse_document(&body_text);\n"
"\n"
" let selector = Selector::parse(\"a\").unwrap();\n"
" let href_values = document\n"
" .select(&selector)\n"
" .filter_map(|element| element.value().attr(\"href\"));\n"
" for href in href_values {\n"
" match base_url.join(href) {\n"
" Ok(link_url) => {\n"
" link_urls.push(link_url);\n"
" }\n"
" Err(err) => {\n"
" println!(\"On {base_url:#}: ignored unparsable {href:?}: "
"{err}\");\n"
" }\n"
" }\n"
" }\n"
" Ok(link_urls)\n"
"}\n"
"// ANCHOR_END: visit_page\n"
"\n"
"struct CrawlState {\n"
" domain: String,\n"
" visited_pages: std::collections::HashSet<String>,\n"
"}\n"
"\n"
"impl CrawlState {\n"
" fn new(start_url: &Url) -> CrawlState {\n"
" let mut visited_pages = std::collections::HashSet::new();\n"
" visited_pages.insert(start_url.as_str().to_string());\n"
" CrawlState {\n"
" domain: start_url.domain().unwrap().to_string(),\n"
" visited_pages,\n"
" }\n"
" }\n"
"\n"
" /// Determine whether links within the given page should be extracted.\n"
" fn should_extract_links(&self, url: &Url) -> bool {\n"
" let Some(url_domain) = url.domain() else {\n"
" return false;\n"
" };\n"
" url_domain == self.domain\n"
" }\n"
"\n"
" /// Mark the given page as visited, returning true if it had already\n"
" /// been visited.\n"
" fn mark_visited(&mut self, url: &Url) -> bool {\n"
" self.visited_pages.insert(url.as_str().to_string())\n"
" }\n"
"}\n"
"\n"
"type CrawlResult = Result<Vec<Url>, (Url, Error)>;\n"
"fn spawn_crawler_threads(\n"
" command_receiver: mpsc::Receiver<CrawlCommand>,\n"
" result_sender: mpsc::Sender<CrawlResult>,\n"
" thread_count: u32,\n"
") {\n"
" let command_receiver = Arc::new(Mutex::new(command_receiver));\n"
"\n"
" for _ in 0..thread_count {\n"
" let result_sender = result_sender.clone();\n"
" let command_receiver = command_receiver.clone();\n"
" thread::spawn(move || {\n"
" let client = Client::new();\n"
" loop {\n"
" let command_result = {\n"
" let receiver_guard = command_receiver.lock().unwrap();\n"
" receiver_guard.recv()\n"
" };\n"
" let Ok(crawl_command) = command_result else {\n"
" // The sender got dropped. No more commands coming in.\n"
" break;\n"
" };\n"
" let crawl_result = match visit_page(&client, &crawl_command) "
"{\n"
" Ok(link_urls) => Ok(link_urls),\n"
" Err(error) => Err((crawl_command.url, error)),\n"
" };\n"
" result_sender.send(crawl_result).unwrap();\n"
" }\n"
" });\n"
" }\n"
"}\n"
"\n"
"fn control_crawl(\n"
" start_url: Url,\n"
" command_sender: mpsc::Sender<CrawlCommand>,\n"
" result_receiver: mpsc::Receiver<CrawlResult>,\n"
") -> Vec<Url> {\n"
" let mut crawl_state = CrawlState::new(&start_url);\n"
" let start_command = CrawlCommand { url: start_url, extract_links: "
"true };\n"
" command_sender.send(start_command).unwrap();\n"
" let mut pending_urls = 1;\n"
"\n"
" let mut bad_urls = Vec::new();\n"
" while pending_urls > 0 {\n"
" let crawl_result = result_receiver.recv().unwrap();\n"
" pending_urls -= 1;\n"
"\n"
" match crawl_result {\n"
" Ok(link_urls) => {\n"
" for url in link_urls {\n"
" if crawl_state.mark_visited(&url) {\n"
" let extract_links = crawl_state."
"should_extract_links(&url);\n"
" let crawl_command = CrawlCommand { url, "
"extract_links };\n"
" command_sender.send(crawl_command).unwrap();\n"
" pending_urls += 1;\n"
" }\n"
" }\n"
" }\n"
" Err((url, error)) => {\n"
" bad_urls.push(url);\n"
" println!(\"Got crawling error: {:#}\", error);\n"
" continue;\n"
" }\n"
" }\n"
" }\n"
" bad_urls\n"
"}\n"
"\n"
"fn check_links(start_url: Url) -> Vec<Url> {\n"
" let (result_sender, result_receiver) = mpsc::channel::<CrawlResult>();\n"
" let (command_sender, command_receiver) = mpsc::channel::"
"<CrawlCommand>();\n"
" spawn_crawler_threads(command_receiver, result_sender, 16);\n"
" control_crawl(start_url, command_sender, result_receiver)\n"
"}\n"
"\n"
"fn main() {\n"
" let start_url = reqwest::Url::parse(\"https://www.google.org\")."
"unwrap();\n"
" let bad_urls = check_links(start_url);\n"
" println!(\"Bad URLs: {:#?}\", bad_urls);\n"
"}\n"
"```"
msgstr ""
#: src/exercises/concurrency/solutions-afternoon.md:1 #: src/exercises/concurrency/solutions-afternoon.md:1
#, fuzzy #, fuzzy
msgid "# Concurrency Afternoon Exercise" msgid "# Concurrency Afternoon Exercise"