1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2024-12-11 13:18:43 +02:00
comprehensive-rust/po/ko.po
Jooyung Han 6df343736a
Fix Day 2 (morning part) of the Korean translation (#327)
* fix: korean translation for day2

This covers 12, 13, 14 in TOC.

* Refine ko-translation regarding match with enum

---------

Co-authored-by: Jooyung Han <jooyung@google.com>
2023-02-09 12:18:40 +09:00

14407 lines
466 KiB
Plaintext

msgid ""
msgstr ""
"Project-Id-Version: [한국어]Comprehensive Rust 🦀\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2023-01-27 12:32+0100\n"
"Last-Translator: keispace <keispace.kyj@google.com>\n"
"Language-Team: \n"
"Language: ko\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: src/SUMMARY.md:3
msgid "Welcome to Comprehensive Rust 🦀"
msgstr "Comprehensive Rust에 오신 것을 환영합니다 🦀"
#: src/SUMMARY.md:4
msgid "Running the Course"
msgstr "강의 진행"
#: src/SUMMARY.md:5
msgid "Course Structure"
msgstr "강의 구성"
#: src/SUMMARY.md:6
msgid "Keyboard Shortcuts"
msgstr "단축키"
#: src/SUMMARY.md:7
msgid "Using Cargo"
msgstr "카고 사용하기"
#: src/SUMMARY.md:8
msgid "Rust Ecosystem"
msgstr "러스트 생태계"
#: src/SUMMARY.md:9
msgid "Code Samples"
msgstr "코드 샘플"
#: src/SUMMARY.md:10
msgid "Running Cargo Locally"
msgstr "카고(Cargo) 수행하기"
#: src/SUMMARY.md:13
msgid "Day 1: Morning"
msgstr "1일차 오전"
#: src/SUMMARY.md:17 src/SUMMARY.md:73 src/SUMMARY.md:126 src/SUMMARY.md:177
msgid "Welcome"
msgstr "개요"
#: src/SUMMARY.md:18
msgid "What is Rust?"
msgstr "러스트란?"
#: src/SUMMARY.md:19
msgid "Hello World!"
msgstr "Hello World!"
#: src/SUMMARY.md:20
msgid "Small Example"
msgstr "작은 예제"
#: src/SUMMARY.md:21
msgid "Why Rust?"
msgstr "러스트를 써야하는 이유"
#: src/SUMMARY.md:22
msgid "Compile Time Guarantees"
msgstr "컴파일 시 보장되는 것들"
#: src/SUMMARY.md:23
msgid "Runtime Guarantees"
msgstr "런타임 시 보장되는 것들"
#: src/SUMMARY.md:24
msgid "Modern Features"
msgstr "현대적인 특징"
#: src/SUMMARY.md:25
msgid "Basic Syntax"
msgstr "기본 문법"
#: src/SUMMARY.md:26
msgid "Scalar Types"
msgstr "스칼라 타입"
#: src/SUMMARY.md:27
msgid "Compound Types"
msgstr "복합 타입"
#: src/SUMMARY.md:28
msgid "References"
msgstr "참조"
#: src/SUMMARY.md:29
msgid "Dangling References"
msgstr "허상(dangling) 참조"
#: src/SUMMARY.md:30
msgid "Slices"
msgstr "슬라이스"
#: src/SUMMARY.md:31
msgid "String vs str"
msgstr "String과 str"
#: src/SUMMARY.md:32
msgid "Functions"
msgstr "함수"
#: src/SUMMARY.md:33 src/SUMMARY.md:80
msgid "Methods"
msgstr "메서드"
#: src/SUMMARY.md:34
msgid "Overloading"
msgstr "오버로딩"
#: src/SUMMARY.md:35 src/SUMMARY.md:64 src/SUMMARY.md:88 src/SUMMARY.md:117
#: src/SUMMARY.md:145 src/SUMMARY.md:169 src/SUMMARY.md:192 src/SUMMARY.md:219
msgid "Exercises"
msgstr "연습문제"
#: src/SUMMARY.md:36
msgid "Implicit Conversions"
msgstr "묵시적 형변환"
#: src/SUMMARY.md:37
msgid "Arrays and for Loops"
msgstr "배열과 for 반복문"
#: src/SUMMARY.md:39
msgid "Day 1: Afternoon"
msgstr "1일차 오후"
#: src/SUMMARY.md:41
msgid "Variables"
msgstr "변수"
#: src/SUMMARY.md:42
msgid "Type Inference"
msgstr "타입 추론"
#: src/SUMMARY.md:43
msgid "static & const"
msgstr "정적변수(static)와 상수(const)"
#: src/SUMMARY.md:44
msgid "Scopes and Shadowing"
msgstr "범위(Scopes)와 쉐도잉(Shadowing)"
#: src/SUMMARY.md:45
msgid "Memory Management"
msgstr "메모리 관리"
#: src/SUMMARY.md:46
msgid "Stack vs Heap"
msgstr "스택(Stack)과 힙(Heap)"
#: src/SUMMARY.md:47
msgid "Stack Memory"
msgstr "스택 메모리"
#: src/SUMMARY.md:48
msgid "Manual Memory Management"
msgstr "수동 메모리 관리"
#: src/SUMMARY.md:49
msgid "Scope-Based Memory Management"
msgstr "범위기반 메모리 관리"
#: src/SUMMARY.md:50
msgid "Garbage Collection"
msgstr "가비지 컬렉션"
#: src/SUMMARY.md:51
msgid "Rust Memory Management"
msgstr "러스트의 메모리 관리"
#: src/SUMMARY.md:52
msgid "Comparison"
msgstr "비교"
#: src/SUMMARY.md:53
msgid "Ownership"
msgstr "소유권"
#: src/SUMMARY.md:54
msgid "Move Semantics"
msgstr "Move 문법"
#: src/SUMMARY.md:55
msgid "Moved Strings in Rust"
msgstr "러스트에서의 문자열 이동"
#: src/SUMMARY.md:56
msgid "Double Frees in Modern C++"
msgstr "Modern C++에서 이중해제 문제"
#: src/SUMMARY.md:57
msgid "Moves in Function Calls"
msgstr "함수 호출에서의 이동(Move)"
#: src/SUMMARY.md:58
msgid "Copying and Cloning"
msgstr "복사와 복제"
#: src/SUMMARY.md:59
msgid "Borrowing"
msgstr "빌림"
#: src/SUMMARY.md:60
msgid "Shared and Unique Borrows"
msgstr "공유와 고유 빌림"
#: src/SUMMARY.md:61
msgid "Lifetimes"
msgstr "수명"
#: src/SUMMARY.md:62
msgid "Lifetimes in Function Calls"
msgstr "함수 호출에서의 수명"
#: src/SUMMARY.md:63
msgid "Lifetimes in Data Structures"
msgstr "구조체에서의 수명"
#: src/SUMMARY.md:65
msgid "Designing a Library"
msgstr "도서관 설계"
#: src/SUMMARY.md:66
msgid "Iterators and Ownership"
msgstr "반복자와 소유권"
#: src/SUMMARY.md:69
msgid "Day 2: Morning"
msgstr "2일차 오전"
#: src/SUMMARY.md:74
msgid "Structs"
msgstr "구조체"
#: src/SUMMARY.md:75
msgid "Tuple Structs"
msgstr "튜플"
#: src/SUMMARY.md:76
msgid "Field Shorthand Syntax"
msgstr "필드 할당 단축 문법"
#: src/SUMMARY.md:77
msgid "Enums"
msgstr "열거형"
#: src/SUMMARY.md:78
msgid "Variant Payloads"
msgstr "데이터를 포함하는 열거형(Variant Payloads)"
#: src/SUMMARY.md:79
msgid "Enum Sizes"
msgstr "열거형의 크기"
#: src/SUMMARY.md:81
msgid "Method Receiver"
msgstr "메서드 리시버(Receiver)"
#: src/SUMMARY.md:82 src/SUMMARY.md:187
msgid "Example"
msgstr "예제"
#: src/SUMMARY.md:83
msgid "Pattern Matching"
msgstr "패턴 매칭"
#: src/SUMMARY.md:84
msgid "Destructuring Enums"
msgstr "열거형 분해(역구조화)"
#: src/SUMMARY.md:85
msgid "Destructuring Structs"
msgstr "구조체 분해(역구조화)"
#: src/SUMMARY.md:86
msgid "Destructuring Arrays"
msgstr "배열 분해(역구조화)"
#: src/SUMMARY.md:87
msgid "Match Guards"
msgstr "검사식(Match Guards)"
#: src/SUMMARY.md:89
msgid "Health Statistics"
msgstr "건강상태 모니터링 시스템"
#: src/SUMMARY.md:90
msgid "Points and Polygons"
msgstr "점과 다각형"
#: src/SUMMARY.md:92
msgid "Day 2: Afternoon"
msgstr "2일차 오후"
#: src/SUMMARY.md:94
msgid "Control Flow"
msgstr "흐름 제어"
#: src/SUMMARY.md:95
msgid "Blocks"
msgstr "블록"
#: src/SUMMARY.md:96
msgid "if expressions"
msgstr "if 표현식"
#: src/SUMMARY.md:97
msgid "if let expressions"
msgstr "if let 표현식"
#: src/SUMMARY.md:98
msgid "while expressions"
msgstr "while 표현식"
#: src/SUMMARY.md:99
msgid "while let expressions"
msgstr "while let 표현식"
#: src/SUMMARY.md:100
msgid "for expressions"
msgstr "for 표현식"
#: src/SUMMARY.md:101
msgid "loop expressions"
msgstr "loop 표현식"
#: src/SUMMARY.md:102
msgid "match expressions"
msgstr "match 표현식"
#: src/SUMMARY.md:103
msgid "break & continue"
msgstr "break와 continue"
#: src/SUMMARY.md:104
msgid "Standard Library"
msgstr "표준 라이브러리"
#: src/SUMMARY.md:105
msgid "String"
msgstr "String"
#: src/SUMMARY.md:106
msgid "Option and Result"
msgstr "Option과 Result"
#: src/SUMMARY.md:107
msgid "Vec"
msgstr "Vec"
#: src/SUMMARY.md:108
msgid "HashMap"
msgstr "HashMap"
#: src/SUMMARY.md:109
msgid "Box"
msgstr "Box"
#: src/SUMMARY.md:110
msgid "Recursive Data Types"
msgstr "재귀적 자료구조"
#: src/SUMMARY.md:111
msgid "Niche Optimization"
msgstr "니치(틈새) 최적화(Niche Optimization)"
#: src/SUMMARY.md:112
msgid "Rc"
msgstr "Rc"
#: src/SUMMARY.md:113
msgid "Modules"
msgstr "모듈"
#: src/SUMMARY.md:114
msgid "Visibility"
msgstr "접근자(Visibility)"
#: src/SUMMARY.md:115
msgid "Paths"
msgstr "경로"
#: src/SUMMARY.md:116
msgid "Filesystem Hierarchy"
msgstr "파일시스템 계층"
#: src/SUMMARY.md:118
msgid "Luhn Algorithm"
msgstr "룬 알고리즘"
#: src/SUMMARY.md:119
msgid "Strings and Iterators"
msgstr "문자열과 반복자"
#: src/SUMMARY.md:122
msgid "Day 3: Morning"
msgstr "3일차 오전"
#: src/SUMMARY.md:127
msgid "Traits"
msgstr "트레이트(Trait)"
#: src/SUMMARY.md:128
msgid "Deriving Traits"
msgstr "트레이트 상속하기"
#: src/SUMMARY.md:129
msgid "Default Methods"
msgstr "기본 메서드"
#: src/SUMMARY.md:130
msgid "Important Traits"
msgstr "중요한 트레이트"
#: src/SUMMARY.md:131
msgid "Iterator"
msgstr "Iterator"
#: src/SUMMARY.md:132
msgid "FromIterator"
msgstr "FromIterator"
#: src/SUMMARY.md:133
msgid "From and Into"
msgstr "From과 Into"
#: src/SUMMARY.md:134
msgid "Read and Write"
msgstr "Read와 Write"
#: src/SUMMARY.md:135
msgid "Add, Mul, ..."
msgstr "Add, Mul, ..."
#: src/SUMMARY.md:136
msgid "Drop"
msgstr "Drop"
#: src/SUMMARY.md:137
msgid "Generics"
msgstr "제너릭"
#: src/SUMMARY.md:138
msgid "Generic Data Types"
msgstr "제너릭 데이터 타입"
#: src/SUMMARY.md:139
msgid "Generic Methods"
msgstr "제너릭 메서드"
#: src/SUMMARY.md:140
msgid "Trait Bounds"
msgstr "제너릭 타입 제한(트레이트 경계)"
#: src/SUMMARY.md:141
msgid "impl Trait"
msgstr "트레이트 구현하기"
#: src/SUMMARY.md:142
msgid "Closures"
msgstr "클로저"
#: src/SUMMARY.md:143
msgid "Monomorphization"
msgstr "단형화"
#: src/SUMMARY.md:144
msgid "Trait Objects"
msgstr "트레이트 객체"
#: src/SUMMARY.md:146
msgid "A Simple GUI Library"
msgstr "간단한 GUI 라이브러리"
#: src/SUMMARY.md:148
msgid "Day 3: Afternoon"
msgstr "3일차 오후"
#: src/SUMMARY.md:150
msgid "Error Handling"
msgstr "오류처리"
#: src/SUMMARY.md:151
msgid "Panics"
msgstr "패닉"
#: src/SUMMARY.md:152
msgid "Catching Stack Unwinding"
msgstr "스택 되감기"
#: src/SUMMARY.md:153
msgid "Structured Error Handling"
msgstr "구조화된 오류처리"
#: src/SUMMARY.md:154
msgid "Propagating Errors with ?"
msgstr "'?'를 이용한 오류 전파"
#: src/SUMMARY.md:155
msgid "Converting Error Types"
msgstr "오류타입 변환"
#: src/SUMMARY.md:156
msgid "Deriving Error Enums"
msgstr "또다른 오류 열거형"
#: src/SUMMARY.md:157
msgid "Adding Context to Errors"
msgstr "오류에 상황정보 추가"
#: src/SUMMARY.md:158
msgid "Testing"
msgstr "테스트"
#: src/SUMMARY.md:159
msgid "Unit Tests"
msgstr "단위 테스트"
#: src/SUMMARY.md:160
msgid "Test Modules"
msgstr "테스트 모듈"
#: src/SUMMARY.md:161
msgid "Documentation Tests"
msgstr "문서화주석 테스트"
#: src/SUMMARY.md:162
msgid "Integration Tests"
msgstr "통합 테스트"
#: src/SUMMARY.md:163
msgid "Unsafe Rust"
msgstr "안전하지 않은 러스트"
#: src/SUMMARY.md:164
msgid "Dereferencing Raw Pointers"
msgstr "원시 포인터 역참조(따라가기)"
#: src/SUMMARY.md:165
msgid "Mutable Static Variables"
msgstr "정적 가변 변수"
#: src/SUMMARY.md:166
msgid "Calling Unsafe Functions"
msgstr "안전하지 않은 함수 호출"
#: src/SUMMARY.md:167
msgid "Extern Functions"
msgstr "외부(다른언어) 함수들"
#: src/SUMMARY.md:168
msgid "Unions"
msgstr "Unions"
#: src/SUMMARY.md:170
msgid "Safe FFI Wrapper"
msgstr "FFI래퍼"
#: src/SUMMARY.md:173
msgid "Day 4: Morning"
msgstr "4일차 오전"
#: src/SUMMARY.md:178
msgid "Concurrency"
msgstr "동시성"
#: src/SUMMARY.md:179
msgid "Threads"
msgstr "스레드"
#: src/SUMMARY.md:180
msgid "Scoped Threads"
msgstr "범위 스레드(Scoped Threads)"
#: src/SUMMARY.md:181
msgid "Channels"
msgstr "채널"
#: src/SUMMARY.md:182
msgid "Unbounded Channels"
msgstr "무경계 채널"
#: src/SUMMARY.md:183
msgid "Bounded Channels"
msgstr "경계 채널"
#: src/SUMMARY.md:184
msgid "Shared State"
msgstr "상태 공유"
#: src/SUMMARY.md:185
msgid "Arc"
msgstr "Arc"
#: src/SUMMARY.md:186
msgid "Mutex"
msgstr "Mutex"
#: src/SUMMARY.md:188
msgid "Send and Sync"
msgstr "Send와 Sync"
#: src/SUMMARY.md:188
msgid "Send"
msgstr "Send"
#: src/SUMMARY.md:188
msgid "Sync"
msgstr "Sync"
#: src/SUMMARY.md:191
msgid "Examples"
msgstr "예제"
#: src/SUMMARY.md:193
msgid "Dining Philosophers"
msgstr "식사하는 철학자들"
#: src/SUMMARY.md:194
msgid "Multi-threaded Link Checker"
msgstr "멀티스레드 링크 검사기"
#: src/SUMMARY.md:196
msgid "Day 4: Afternoon"
msgstr "4일차 오후"
#: src/SUMMARY.md:200
msgid "Android"
msgstr "안드로이드"
#: src/SUMMARY.md:201
msgid "Setup"
msgstr "설치"
#: src/SUMMARY.md:202
msgid "Build Rules"
msgstr "빌드 규칙"
#: src/SUMMARY.md:203
msgid "Binary"
msgstr "바이너리"
#: src/SUMMARY.md:204
msgid "Library"
msgstr "라이브러리"
#: src/SUMMARY.md:205
msgid "AIDL"
msgstr "AIDL"
#: src/SUMMARY.md:206
msgid "Interface"
msgstr "AIDL 인터페이스"
#: src/SUMMARY.md:207
msgid "Implementation"
msgstr "서비스 구현"
#: src/SUMMARY.md:208
msgid "Server"
msgstr "AIDL 서버"
#: src/SUMMARY.md:209
msgid "Deploy"
msgstr "배포"
#: src/SUMMARY.md:210
msgid "Client"
msgstr "클라이언트"
#: src/SUMMARY.md:211
msgid "Changing API"
msgstr "API 수정"
#: src/SUMMARY.md:212
msgid "Logging"
msgstr "로깅"
#: src/SUMMARY.md:213
msgid "Interoperability"
msgstr "상호운용성"
#: src/SUMMARY.md:214
msgid "With C"
msgstr "C와의 상호운용성"
#: src/SUMMARY.md:215
msgid "Calling C with Bindgen"
msgstr "Bindgen을 사용한 C호출"
#: src/SUMMARY.md:216
msgid "Calling Rust from C"
msgstr "C에서 러스트 호출"
#: src/SUMMARY.md:217
msgid "With C++"
msgstr "C++ 와의 상호운용성"
#: src/SUMMARY.md:218
msgid "With Java"
msgstr "Java와의 상호운용성"
#: src/SUMMARY.md:221
msgid "Final Words"
msgstr "끝으로..."
#: src/SUMMARY.md:223
msgid "Thanks!"
msgstr "감사인사"
#: src/SUMMARY.md:224
msgid "Other Resources"
msgstr "러스트 참고 자료"
#: src/SUMMARY.md:225
msgid "Credits"
msgstr "도와주신 분들"
#: src/SUMMARY.md:229
msgid "Solutions"
msgstr "해답"
#: src/SUMMARY.md:234
msgid "Day 1 Morning"
msgstr "1일차 오전"
#: src/SUMMARY.md:235
msgid "Day 1 Afternoon"
msgstr "1일차 오후"
#: src/SUMMARY.md:236
msgid "Day 2 Morning"
msgstr "2일차 오전"
#: src/SUMMARY.md:237
msgid "Day 2 Afternoon"
msgstr "2일차 오후"
#: src/SUMMARY.md:238
msgid "Day 3 Morning"
msgstr "3일차 오전"
#: src/SUMMARY.md:239
msgid "Day 3 Afternoon"
msgstr "3일차 오후"
#: src/SUMMARY.md:240
msgid "Day 4 Morning"
msgstr "4일차 오전"
#: src/welcome.md:1
msgid "# Welcome to Comprehensive Rust 🦀"
msgstr "# Welcome to Comprehensive Rust 🦀"
#: src/welcome.md:3
msgid ""
"This is a four day Rust course developed by the Android team. The course "
"covers\n"
"the full spectrum of Rust, from basic syntax to advanced topics like "
"generics\n"
"and error handling. It also includes Android-specific content on the last "
"day."
msgstr ""
"이 4일짜리 러스트 강의는 안드로이드 팀이 만들었습니다.\n"
"기본 문법부터 제너릭, 에러 핸들링과 같은 고급주제까지 러스트의 모든 것을 포함"
"합니다.\n"
"마지막 날에는 안드로이드에 대한 것 까지 다룹니다."
#: src/welcome.md:7
msgid ""
"The goal of the course is to teach you Rust. We assume you don't know "
"anything\n"
"about Rust and hope to:"
msgstr ""
"강의는 당신이 러스트에 대해서 아무것도 모른다고 가정하고 아래의 목표를가지고 "
"있습니다."
#: src/welcome.md:10
msgid ""
"* Give you a comprehensive understanding of the Rust syntax and language.\n"
"* Enable you to modify existing programs and write new programs in Rust.\n"
"* Show you common Rust idioms."
msgstr ""
"* 러스트 구문과 언어에 대한 포괄적인 이해를 제공합니다.\n"
"* 기존 프로그램을 수정하고 러스트에서 새 프로그램을 작성할 수 있습니다.\n"
"* 일반적인 러스트 관용구를 보여줍니다."
#: src/welcome.md:14
msgid "On Day 4, we will cover Android-specific things such as:"
msgstr ""
"4일차 강의에 우리는 아래와 같은 안드로이드 특화된 내용들도 설명합니다."
#: src/welcome.md:16
msgid ""
"* Building Android components in Rust.\n"
"* AIDL servers and clients.\n"
"* Interoperability with C, C++, and Java."
msgstr ""
"* 러스트에서 Android 구성 요소를 구축.\n"
"* AIDL 서버 및 클라이언트.\n"
"* C, C++ 및 Java와의 상호 운용성."
#: src/welcome.md:20
msgid ""
"It is important to note that this course does not cover Android "
"**application** \n"
"development in Rust, and that the Android-specific parts are specifically "
"about\n"
"writing code for Android itself, the operating system. "
msgstr ""
"이 강의에서는 러스트로 안드로이드 **어플리케이션**을 개발하는 것은 다루지 않"
"습니다.\n"
"이 강의에서 다루는 안드로이드 특화된 내용은 안드로이드 OS의 일부를 러스트로개"
"발하는 것에 대한 것입니다."
#: src/welcome.md:24
msgid "## Non-Goals"
msgstr "## 제외사항"
#: src/welcome.md:26
msgid ""
"Rust is a large language and we won't be able to cover all of it in a few "
"days.\n"
"Some non-goals of this course are:"
msgstr ""
"러스트는 몇일만에 모든 것을 다루기에는 너무 큰 언어입니다. 그래서 아래와 같은"
"것을 목표로 하지 않습니다."
#: src/welcome.md:29
msgid ""
"* Learn how to use async Rust --- we'll only mention async Rust when\n"
" covering traditional concurrency primitives. Please see [Asynchronous\n"
" Programming in Rust](https://rust-lang.github.io/async-book/) instead for\n"
" details on this topic.\n"
"* Learn how to develop macros, please see [Chapter 19.5 in the Rust\n"
" Book](https://doc.rust-lang.org/book/ch19-06-macros.html) and [Rust by\n"
" Example](https://doc.rust-lang.org/rust-by-example/macros.html) instead."
msgstr ""
"* 비동기적 러스트 사용법 --- 간단하게 언급정도는 하겠지만 좀 더 자세한 내용"
"은 [Asynchronous Programming in Rust](https://rust-lang.github.io/async-"
"book/)를 참조해주세요.\n"
"* 매크로를 개발하는 방법. [Chapter 19.5 in the Rust Book](https://doc.rust-"
"lang.org/book/ch19-06-macros.html)와 [Rust by Example](https://doc.rust-lang."
"org/rust-by-example/macros.html)를 참조하세요."
#: src/welcome.md:37
msgid "## Assumptions"
msgstr "## 독자 수준에 대한 가정"
#: src/welcome.md:39
msgid ""
"The course assumes that you already know how to program. Rust is a "
"statically\n"
"typed language and we will sometimes make comparisons with C and C++ to "
"better\n"
"explain or contrast the Rust approach."
msgstr ""
"본 강의는 여러분이 프로그래밍 자체에 대해서는 알고 있다고 가정합니다.\n"
"러스트는 정적타입 언어이며, 강좌에서는 C/C++ 와의 비교, 대조를 통해 러스트를 "
"설명할 것입니다."
#: src/welcome.md:43
msgid ""
"If you know how to program in a dynamically typed language such as Python "
"or\n"
"JavaScript, then you will be able to follow along just fine too."
msgstr ""
"C/C++을 모르더라도 동적 타입 언어(Python이나 JavaScript 등) 프로그래밍 경험이 \n"
"있다면 따라오는데 큰 문제는 없을 것입니다."
#: src/welcome.md:46 src/cargo/rust-ecosystem.md:19
#: src/cargo/code-samples.md:22 src/cargo/running-locally.md:68
#: src/welcome-day-1.md:14 src/welcome-day-1/what-is-rust.md:19
#: src/hello-world.md:20 src/hello-world/small-example.md:21 src/why-rust.md:9
#: src/why-rust/compile-time.md:14 src/why-rust/runtime.md:8
#: src/why-rust/modern.md:19 src/basic-syntax/compound-types.md:28
#: src/basic-syntax/slices.md:18 src/basic-syntax/string-slices.md:25
#: src/basic-syntax/functions.md:33 src/basic-syntax/functions-interlude.md:25
#: src/exercises/day-1/morning.md:9 src/exercises/day-1/for-loops.md:90
#: src/basic-syntax/variables.md:15 src/basic-syntax/type-inference.md:24
#: src/basic-syntax/static-and-const.md:46
#: src/basic-syntax/scopes-shadowing.md:23 src/memory-management/stack.md:26
#: src/memory-management/rust.md:12 src/ownership/move-semantics.md:20
#: src/ownership/moves-function-calls.md:18 src/ownership/copy-clone.md:33
#: src/ownership/borrowing.md:25 src/ownership/shared-unique-borrows.md:23
#: src/ownership/lifetimes-function-calls.md:27
#: src/ownership/lifetimes-data-structures.md:23
#: src/exercises/day-1/afternoon.md:9 src/structs/tuple-structs.md:35
#: src/structs/field-shorthand.md:25 src/enums/variant-payloads.md:33
#: src/methods.md:28 src/pattern-matching/destructuring-enums.md:33
#: src/pattern-matching/match-guards.md:20 src/exercises/day-2/morning.md:9
#: src/exercises/day-2/points-polygons.md:115
#: src/control-flow/if-expressions.md:29
#: src/control-flow/if-let-expressions.md:19 src/std/string.md:28
#: src/std/option-result.md:16 src/std/box.md:32 src/std/rc.md:26
#: src/exercises/day-2/afternoon.md:5 src/traits.md:39
#: src/traits/iterator.md:30 src/traits/from-iterator.md:12
#: src/traits/operators.md:24 src/traits/drop.md:32 src/generics/methods.md:23
#: src/generics/trait-bounds.md:19 src/generics/impl-trait.md:22
#: src/generics/closures.md:23 src/exercises/day-3/morning.md:5
#: src/error-handling/result.md:25 src/error-handling/try-operator.md:48
#: src/error-handling/converting-error-types.md:53
#: src/error-handling/error-contexts.md:40 src/exercises/day-3/afternoon.md:5
#: src/concurrency/threads.md:28 src/concurrency/channels.md:25
#: src/concurrency/shared_state/arc.md:27
#: src/concurrency/shared_state/example.md:21 src/concurrency/send-sync.md:16
#: src/concurrency/send-sync/sync.md:12 src/exercises/day-4/morning.md:10
#: src/android/interoperability/with-c/rust.md:81
#: src/exercises/day-4/afternoon.md:10
msgid "<details>"
msgstr ""
#: src/welcome.md:48
msgid ""
"This is an example of a _speaker note_. We will use these to add additional\n"
"information to the slides. This could be key points which the instructor "
"should\n"
"cover as well as answers to typical questions which come up in class."
msgstr ""
"이것은 _발표자 노트_의 예제입니다. 이 부분을 이용해서 추가 정보를 제공합니"
"다. \n"
"주로 강의실에서 제기되는 일반적인 질문에 대한 답변과 강사가 다루어야 할 키 포"
"인트일 수 있습니다. "
#: src/welcome.md:52 src/cargo/rust-ecosystem.md:67
#: src/cargo/code-samples.md:35 src/cargo/running-locally.md:74
#: src/welcome-day-1.md:42 src/welcome-day-1/what-is-rust.md:29
#: src/hello-world.md:36 src/hello-world/small-example.md:44 src/why-rust.md:24
#: src/why-rust/compile-time.md:35 src/why-rust/runtime.md:22
#: src/why-rust/modern.md:66 src/basic-syntax/compound-types.md:62
#: src/basic-syntax/references.md:28 src/basic-syntax/slices.md:36
#: src/basic-syntax/functions.md:54 src/exercises/day-1/morning.md:28
#: src/exercises/day-1/for-loops.md:95 src/basic-syntax/variables.md:20
#: src/basic-syntax/type-inference.md:48
#: src/basic-syntax/static-and-const.md:52
#: src/basic-syntax/scopes-shadowing.md:39 src/memory-management/stack.md:32
#: src/memory-management/rust.md:18 src/ownership/move-semantics.md:26
#: src/ownership/moves-function-calls.md:26 src/ownership/borrowing.md:51
#: src/ownership/shared-unique-borrows.md:29
#: src/ownership/lifetimes-function-calls.md:60
#: src/exercises/day-1/afternoon.md:15 src/exercises/day-1/book-library.md:103
#: src/structs.md:40 src/enums/variant-payloads.md:39 src/enums/sizes.md:49
#: src/methods/example.md:53 src/pattern-matching/destructuring-enums.md:39
#: src/exercises/day-2/morning.md:15 src/exercises/day-2/points-polygons.md:125
#: src/control-flow/if-let-expressions.md:26 src/std.md:31 src/std/string.md:34
#: src/std/option-result.md:25 src/std/vec.md:35 src/std/box.md:37
#: src/std/rc.md:32 src/exercises/day-2/afternoon.md:11 src/traits.md:54
#: src/traits/from-iterator.md:23 src/traits/operators.md:38
#: src/traits/drop.md:42 src/generics/methods.md:31 src/generics/closures.md:38
#: src/exercises/day-3/morning.md:11 src/error-handling/try-operator.md:55
#: src/error-handling/converting-error-types.md:60
#: src/error-handling/error-contexts.md:47 src/exercises/day-3/afternoon.md:11
#: src/concurrency/threads.md:45 src/concurrency/channels.md:29
#: src/concurrency/shared_state/example.md:59
#: src/concurrency/send-sync/sync.md:18 src/exercises/day-4/morning.md:16
#: src/android/interoperability/with-c/rust.md:86
#: src/exercises/day-4/afternoon.md:15
msgid "</details>"
msgstr "</details>"
#: src/running-the-course.md:1
msgid "# Running the Course"
msgstr "# 강의 진행 방식"
#: src/running-the-course.md:3 src/running-the-course/course-structure.md:3
msgid "> This page is for the course instructor."
msgstr "> 강사를 위한 안내 페이지입니다."
#: src/running-the-course.md:5
msgid ""
"Here is a bit of background information about how we've been running the "
"course\n"
"internally at Google."
msgstr "다음은 GooGle 내부에서 과정을 운영하는 방법에 대한 배경 정보입니다."
#: src/running-the-course.md:8
msgid "To run the course, you need to:"
msgstr "강의를 실행하기 위한 준비:"
#: src/running-the-course.md:10
msgid ""
"1. Make yourself familiar with the course material. We've included speaker "
"notes\n"
" on some of the pages to help highlight the key points (please help us by\n"
" contributing more speaker notes!). You should make sure to open the "
"speaker\n"
" notes in a popup (click the link with a little arrow next to \"Speaker\n"
" Notes\"). This way you have a clean screen to present to the class."
msgstr ""
"1. 강의 자료를 숙지합니다. 주요 요점을 강조하기 위해 일부 페이지에 강의 참조"
"노트를 포함하였습니다. (추가적인 노트를 작성하여 제공해 주시면 감사하겠습니"
"다.) 강의 참조 노트의 링크를 누르면 강의노트가 별도의 팝업으로 분리가 되며, 메인 "
"화면에서는 사라집니다."
#: src/running-the-course.md:16
msgid ""
"2. Decide on the dates. Since the course is large, we recommend that you\n"
" schedule the four days over two weeks. Course participants have said "
"that\n"
" they find it helpful to have a gap in the course since it helps them "
"process\n"
" all the information we give them."
msgstr ""
"2. 강의 날짜를 정합니다. 강의 내용이 많고 수강생들이 모든 정보를 공부할 수 있"
"도록 중간에 틈을 두어 2주에 걸쳐 4일을 잡는 것을 추천합니다. "
#: src/running-the-course.md:21
msgid ""
"3. Find a room large enough for your in-person participants. We recommend a\n"
" class size of 15-20 people. That's small enough that people are "
"comfortable\n"
" asking questions --- it's also small enough that one instructor will "
"have\n"
" time to answer the questions."
msgstr ""
"3. 충분한 공간을 확보합니다. 수강생과 강사가 질의를 하기에 충분한 시간과 공간"
"이어야 합니다. 15에서 20명 규모의 공간을 추천합니다."
#: src/running-the-course.md:26
msgid ""
"4. On the day of your course, show up to the room a little early to set "
"things\n"
" up. We recommend presenting directly using `mdbook serve` running on "
"your\n"
" laptop. This ensures optimal performance with no lag as you change "
"pages.\n"
" Using your laptop will also allow you to fix typos as you or the course\n"
" participants spot them."
msgstr ""
"4. 강의 당일 조금 일찍 와서 준비합니다. 강사 노트북에서 `mdbook serve -d book/ko`를 "
"이용해 직접 프레젠테이션 하면 페이지 이동시의 지연이 없습니다. 또한, 그렇게 하면 "
"강의도중 오타를 발견했을 때 그 자리에서 바로 수정가능하다는 장점도 있습니다."
#: src/running-the-course.md:32
msgid ""
"5. Let people solve the exercises by themselves or in small groups. Make "
"sure to\n"
" ask people if they're stuck or if there is anything you can help with. "
"When\n"
" you see that several people have the same problem, call it out to the "
"class\n"
" and offer a solution, e.g., by showing people where to find the relvant\n"
" information in the standard library."
msgstr ""
"5. 수강생들이 직접 (개별 혹은 그룹으로) 연습문제를 풀도록 합니다. 수시로 "
"진행이 막혀 도움을 필요로 하는 수강생이 없는지 수시로 확인합니다. 만약 같은 "
"문제를 여러 사람이 겪고 있다면, 그 문제를 강의실 전체 인원에게 알리고 해결책을 "
"제시합니다. 예를 들어 표준 라이브러리 어디에 가면 그 문제에 대한 해답을 찾을 "
"수 있는지 알려 줍니다."
#: src/running-the-course.md:38
msgid ""
"6. If you don't skip the Android specific parts on Day 4, you will need an "
"[AOSP\n"
" checkout][1]. Make a checkout of the [course repository][2] on the same\n"
" machine and move the `src/android/` directory into the root of your AOSP\n"
" checkout. This will ensure that the Android build system sees the\n"
" `Android.bp` files in `src/android/`."
msgstr ""
"6. 4일차에있을 안드로이드 부분을 건너띄지 않는다면 [AOSP 코드][1]를 체크아웃"
"해야 합니다. 그런 다음, 같은 컴퓨터 에서 [과정 저장소][2]를 체크아웃하고 "
"`src/android/` 디렉터리를 AOSP 코드의 루트로 이동합니다. 이렇게 하면 "
"안드로이드 빌드 시스템에서 과제용으로 추가된 `Android.bp`파일을 인식할 수 "
"있습니다."
#: src/running-the-course.md:44
msgid ""
" Ensure that `adb sync` works with your emulator or real device and pre-"
"build\n"
" all Android examples using `src/android/build_all.sh`. Read the script to "
"see\n"
" the commands it runs and make sure they work when you run them by hand."
msgstr ""
"`adb sync` 명렁어가 에뮬레이터 혹은 실제 장치와 작동하는지 확인합니다. 그리고 \n"
"`src/android/build_all.sh`를 수행해서 모든 안드로이드 예제를 미리 빌드해 보세요.\n"
"그 쉘 스크립트를 읽고, 그 안에서 수행되는 명령어들을 확인한 후 각 명령어들을 \n"
"수동으로 실행해도 잘 되는지 확인하세요."
#: src/running-the-course.md:48
msgid ""
"That is all, good luck running the course! We hope it will be as much fun "
"for\n"
"you as it has been for us!"
msgstr ""
"이제 준비는 끝났습니다. 우리가 그랬듯이 여러분들도 이 강의를 즐기시길 바랍니다."
#: src/running-the-course.md:51
msgid ""
"Please [provide feedback][3] afterwards so that we can keep improving the\n"
"course. We would love to hear what worked well for you and what can be made\n"
"better. Your students are also very welcome to [send us feedback][4]!"
msgstr ""
"강의를 계속 개선할 수 있도록 [피드백][3]을 제공해 주십시오. 우리는 무엇이 \n"
"좋았고, 무엇이 모자랐는지 듣고 싶습니다. 수강생들로 부터의 피드백[4]도 \n"
"환영합니다."
#: src/running-the-course.md:55
msgid ""
"[1]: https://source.android.com/docs/setup/download/downloading\n"
"[2]: https://github.com/google/comprehensive-rust\n"
"[3]: https://github.com/google/comprehensive-rust/discussions/86\n"
"[4]: https://github.com/google/comprehensive-rust/discussions/100"
msgstr ""
#: src/running-the-course/course-structure.md:1
msgid "# Course Structure"
msgstr "# 강의 구성"
#: src/running-the-course/course-structure.md:5
msgid "The course is fast paced and covers a lot of ground:"
msgstr ""
"강의는 빠른 속도로 진행되며, 아래 내용들을 다룹니다."
#: src/running-the-course/course-structure.md:7
msgid ""
"* Day 1: Basic Rust, ownership and the borrow checker.\n"
"* Day 2: Compound data types, pattern matching, the standard library.\n"
"* Day 3: Traits and generics, error handling, testing, unsafe Rust.\n"
"* Day 4: Concurrency in Rust and interoperability with other languages"
msgstr ""
"* 1일차: 러스트 기본, 소유권(ownership)과 빌림(borrow) 체크\n"
"* 2일차: 복합 데이터 유형, 패턴 매칭, 표준 라이브러리\n"
"* 3일차: 트레이트(trait)와 제너릭(generic), 오류 처리, 테스트, "
"안전하지 않은 러스트\n"
"* 4일차: 러스트의 동시성 및 다른 언어와의 상호 운용성"
#: src/running-the-course/course-structure.md:12
msgid ""
"> **Exercise for Day 4:** Do you interface with some C/C++ code in your "
"project\n"
"> which we could attempt to move to Rust? The fewer dependencies the "
"better.\n"
"> Parsing code would be ideal."
msgstr ""
" **4일차의 연습:** 러스트 프로젝트에서 C/C++로 작성된 코드를 이전해서 연결하"
"려고 한다면 종속성이 적을 수록 좋습니다. 구문 분석 코드라면 이상적입니다."
#: src/running-the-course/course-structure.md:16
msgid "## Format"
msgstr "## 강의 형식"
#: src/running-the-course/course-structure.md:18
msgid ""
"The course is meant to be very interactive and we recommend letting the\n"
"questions drive the exploration of Rust!"
msgstr ""
"이 강의는 강사와 수강생이 양방향으로 소통하면서 진행하도록 디자인 되었습니다.\n"
"다양한 질문을 통해 러스트의 여러 부분을 탐험할 수 있도록 하세요!"
#: src/running-the-course/keyboard-shortcuts.md:1
msgid "# Keyboard Shortcuts"
msgstr "# 단축키"
#: src/running-the-course/keyboard-shortcuts.md:3
msgid "There are several useful keyboard shortcuts in mdBook:"
msgstr "mdBook 시스템(현 사이트)에서 유용한 단축키들 입니다."
#: src/running-the-course/keyboard-shortcuts.md:5
msgid ""
"* <kbd>Arrow-Left</kbd>: Navigate to the previous page.\n"
"* <kbd>Arrow-Right</kbd>: Navigate to the next page.\n"
"* <kbd>Ctrl + Enter</kbd>: Execute the code sample that has focus.\n"
"* <kbd>s</kbd>: Activate the search bar."
msgstr ""
"* <kbd>왼쪽 화살표</kbd>: 이전 페이지로 이동합니다.\n"
"* <kbd>오른쪽 화살표</kbd>: 다음 페이지로 이동합니다.\n"
"* <kbd>Ctrl + Enter</kbd>: 현재 포커스를 받은 코드 샘플 블록을 실행합니다.\n"
"* <kbd>s</kbd>: 검색창을 활성화합니다.(mdbook 문제로 23.01.19 기준 영어로만 "
"가능합니다.)"
#: src/cargo.md:1
msgid "# Using Cargo"
msgstr "# 카고(Cargo) 사용하기"
#: src/cargo.md:3
msgid ""
"When you start reading about Rust, you will soon meet [Cargo](https://doc."
"rust-lang.org/cargo/), the standard tool\n"
"used in the Rust ecosystem to build and run Rust applications. Here we want "
"to\n"
"give a brief overview of what Cargo is and how it fits into the wider "
"ecosystem\n"
"and how it fits into this training."
msgstr ""
"러스트를 시작하려고하면 당신은 곧 [Cargo](https://doc.rust-lang.org/cargo/)라"
"는, 러스트 생태계에서 사용하는 표준 빌드/실행 도구를 만날 것 입니다. \n"
"여기서는 카고가 무엇인지, 그리고 카고가 러스트 생태계에서 어떤 역할을 하는지, 그"
"리고 이 강의에서 어떻게 사용될 지에 대해 간략히 설명하겠습니다."
#: src/cargo.md:8
msgid "## Installation"
msgstr "## 설치하기"
#: src/cargo.md:10
msgid "### Rustup (Recommended)"
msgstr "#### Rustup (추천)"
#: src/cargo.md:12
msgid ""
"You can follow the instructions to install cargo and rust compiler, among "
"other standard ecosystem tools with the [rustup][3] tool, which is "
"maintained by the Rust Foundation."
msgstr ""
"러스트 재단에서 관리하고 있는 [rustup][3] 도구를 사용하여 카고 및 러스트 컴파"
"일러 등 표준 도구를 설치 할 수 있습니다."
#: src/cargo.md:14
msgid ""
"Along with cargo and rustc, Rustup will install itself as a command line "
"utility that you can use to install/switch toolchains, setup cross "
"compilation, etc."
msgstr ""
"카고(cargo)와 러스트 컴파일러(rustc)와 함께, rustup은 툴체인을 설치하고, 다른 \n"
"툴체인으로 전환하고, 크로스 컴파일 설정을 하는 일을 담당하는 커맨드 라인 유틸리티 \n"
"입니다."
#: src/cargo.md:16
msgid "### Package Managers"
msgstr "### 패키지 매니저"
#: src/cargo.md:18
msgid "#### Debian"
msgstr "#### 데비안"
#: src/cargo.md:20
msgid "On Debian/Ubuntu, you can install Cargo and the Rust source with"
msgstr "데비안이나 우분투에서 cargo와 러스트 소스코드를 아래 커맨드로 설치합니다. "
#: src/cargo.md:22
msgid ""
"```shell\n"
"$ sudo apt install cargo rust-src\n"
"```"
msgstr ""
#: src/cargo.md:26
msgid ""
"This will allow [rust-analyzer][1] to jump to the definitions. We suggest "
"using\n"
"[VS Code][2] to edit the code (but any LSP compatible editor works)."
msgstr ""
"이렇게 하면 [rust-analyzer][1]를 이용해서 특정 심볼이 정의된 위치로 쉽게 \n"
"이동할 수 있습니다. 우리는 에디터로 [VS Code][2]를 추천합니다만, 사실 LSP \n"
"를 지원한다면 어떤 에디터도 무방합니다."
#: src/cargo.md:29
msgid ""
"Some folks also like to use the [Jetbrains][4] family of IDEs, which do "
"their own analysis but have their own tradeoffs. If you prefer them, you can "
"install the [Rust Plugin][5]. Please take note that as of January 2023 "
"debugging only works on the CLion version of the Jetbrains IDEA suite."
msgstr ""
"어떤 사람들은 [Jetbrains][4] 제품군을 선호하기도 합니다. 이 제품들은 rust-analyzer "
"를 활용하지 않고 IDE 자체적으로 구분분석을 합니다. 만약 이 IDE를 설치하셨다면"
"[Rust Plugin][5]를 설치하시기 바랍니다. "
"다만 2023년 1월 기준, 디버깅은 Jetbrains IDEA suite의 CLion 버전에서만 작동한"
"다는 점에 유의하시기 바랍니다."
#: src/cargo.md:31
msgid ""
"[1]: https://rust-analyzer.github.io/\n"
"[2]: https://code.visualstudio.com/\n"
"[3]: https://rustup.rs/\n"
"[4]: https://www.jetbrains.com/clion/\n"
"[5]: https://www.jetbrains.com/rust/"
msgstr ""
#: src/cargo/rust-ecosystem.md:1
msgid "# The Rust Ecosystem"
msgstr "# 러스트 생태계"
#: src/cargo/rust-ecosystem.md:3
msgid ""
"The Rust ecosystem consists of a number of tools, of which the main ones are:"
msgstr ""
"러스트의 생태계는 여러가지 도구들로 구성되어 있으며, 그 중 중요한 것들은 아래"
"와 같습니다: "
#: src/cargo/rust-ecosystem.md:5
msgid ""
"* `rustc`: the Rust compiler which turns `.rs` files into binaries and "
"other\n"
" intermediate formats[^rustc]."
msgstr ""
"* `rustc`: `.rs` 확장자 파일을 바이너리 혹은 다른 중간자 형식으로 변환해주는 "
"Rust 컴파일러입니다."
#: src/cargo/rust-ecosystem.md:8
msgid ""
"* `cargo`: the Rust dependency manager and build tool. Cargo knows how to\n"
" download dependencies hosted on <https://crates.io> and it will pass them "
"to\n"
" `rustc` when building your project. Cargo also comes with a built-in test\n"
" runner which is used to execute unit tests[^cargo]."
msgstr ""
"* `cargo`: 러스트 의존성 관리자 및 빌드도구 입니다. 여러분의 프로젝트에 명시된 \n"
"의존성들을 <https://crates.io>에서 자동으로 다운로드 받고, 그 소스코드를 \n"
"`rustc`로 전달하여 빌드를 시킵니다. 또한 유닛 테스트를 실행하는 테스트 러너를 \n"
"내장하고 있습니다."
#: src/cargo/rust-ecosystem.md:13
msgid ""
"* `rustup`: the Rust toolchain installer and updater. This tool is used to\n"
" install and update `rustc` and `cargo` when new versions of Rust is "
"released.\n"
" In addition, `rustup` can also download documentation for the standard\n"
" library. You can have multiple versions of Rust installed at once and "
"`rustup`\n"
" will let you switch between them as needed."
msgstr ""
"* `rustup`: 러스트 툴체인 설치 프로그램 및 업데이트 프로그램. \n"
" 이 도구는 새 버전의 러스트가 출시될 때 `rustc` 및 `cargo` 설치하고 업데이트"
"하는 데 사용됩니다. \n"
" 또한 `rustup`은 표준 라이브러리에 대한 문서를 다운로드할 수도 있습니다. \n"
" 한 번에 여러 버전의 러스트를 설치할 수 있으며 `rustup`을 통해 필요에 따라 "
"이들 버전을 전환할 수 있습니다"
#: src/cargo/rust-ecosystem.md:21 src/hello-world.md:25
#: src/hello-world/small-example.md:27 src/why-rust/runtime.md:10
#: src/why-rust/modern.md:21 src/basic-syntax/compound-types.md:30
#: src/error-handling/try-operator.md:50
#: src/error-handling/converting-error-types.md:55
#: src/concurrency/threads.md:30
msgid "Key points:"
msgstr "키 포인트:"
#: src/cargo/rust-ecosystem.md:23
msgid ""
"* Rust has a rapid release schedule with a new release coming out\n"
" every six weeks. New releases maintain backwards compatibility with\n"
" old releases --- plus they enable new functionality."
msgstr ""
"* 러스트는 6주마다 새로운 릴리즈가 발표되며 이전 릴리즈와의 호환성을 유지하"
"고 있습니다."
#: src/cargo/rust-ecosystem.md:27
msgid ""
"* There are three release channels: \"stable\", \"beta\", and \"nightly\"."
msgstr ""
"* 릴리즈는 3가지 버전으로 제공됩니다: \"stable\", \"beta\" 그리고 "
"\"nightly\"."
#: src/cargo/rust-ecosystem.md:29
msgid ""
"* New features are being tested on \"nightly\", \"beta\" is what becomes\n"
" \"stable\" every six weeks."
msgstr ""
"* 새로운 기능은 \"nightly\" -> \"beta\" -(6주 후)-> \"stable\" 로 변경됩니"
"다."
#: src/cargo/rust-ecosystem.md:32
msgid ""
"* Rust also has [editions]: the current edition is Rust 2021. Previous\n"
" editions were Rust 2015 and Rust 2018."
msgstr ""
"* 러스트는 [editions]으로 으로 진행됩니다: 현재는 Rust 2021 에디션입니다. 그"
"전에는 Rust 2015와 Rust 2018입니다."
#: src/cargo/rust-ecosystem.md:35
msgid ""
" * The editions are allowed to make backwards incompatible changes to\n"
" the language."
msgstr " * 에디션은 이전 에디션과 호환이 되지 않을 수 있습니다."
#: src/cargo/rust-ecosystem.md:38
msgid ""
" * To prevent breaking code, editions are opt-in: you select the\n"
" edition for your crate via the `Cargo.toml` file."
msgstr ""
" * 에디션이 바뀌면서 프로그램이 의도치 않게 깨지는 문제를 막기 위해, \n"
" 각 프로그램은 자신이 빌드될 에디션을 명시적으로 `Cargo.toml`에 지정\n"
" 해야 합니다."
#: src/cargo/rust-ecosystem.md:41
msgid ""
" * To avoid splitting the ecosystem, Rust compilers can mix code\n"
" written for different editions."
msgstr ""
" * 러스트 생태계가 에디션 별로 파편회 되는 것을 막기 위해, 러스트 컴파일\n"
" 러는 서로 다른 에디션에서 작성된 코드들을 하나의 바이너리로 묶을 수 \n"
" 있습니다."
#: src/cargo/rust-ecosystem.md:44
msgid ""
" * Mention that it is quite rare to ever use the compiler directly not "
"through `cargo` (most users never do)."
msgstr ""
" * `cargo`를 사용하지 않고 컴파일러를 직접 사용하는 경우는 거의 없음을 언급"
"해 주시기 바랍니다."
#: src/cargo/rust-ecosystem.md:46
msgid ""
" * It might be worth alluding that Cargo itself is an extremely powerful "
"and comprehensive tool. It is capable of many advanced features including "
"but not limited to: \n"
" * Project/package structure\n"
" * [workspaces]\n"
" * Dev Dependencies and Runtime Dependency management/caching\n"
" * [build scripting]\n"
" * [global installation]\n"
" * It is also extensible with sub command plugins as well (such as "
"[cargo clippy]).\n"
" * Read more from the [official Cargo Book]"
msgstr ""
" * 카고 자체가 매우 강력하고 포괄적인 도구임을 적극적으로 알리세요.\n"
" 카고는 다음과 같은 다양한 고급 기능을 제공합니다.\n"
" * 프로젝트/패키지 구조화\n"
" * [workspaces]\n"
" * 개발/런타임 종속성 관리 및 캐싱\n"
" * [build scripting]\n"
" * [global installation]\n"
" * [cargo clippy]와 같은 하위 플러그인으로 확장 가능\n"
" * [official Cargo Book]에서 자세한 사항을 확인하시기 바랍니다."
#: src/cargo/rust-ecosystem.md:55
msgid "[editions]: https://doc.rust-lang.org/edition-guide/"
msgstr ""
#: src/cargo/rust-ecosystem.md:57
msgid "[workspaces]: https://doc.rust-lang.org/cargo/reference/workspaces.html"
msgstr ""
#: src/cargo/rust-ecosystem.md:59
msgid ""
"[build scripting]: https://doc.rust-lang.org/cargo/reference/build-scripts."
"html"
msgstr ""
#: src/cargo/rust-ecosystem.md:61
msgid ""
"[global installation]: https://doc.rust-lang.org/cargo/commands/cargo-"
"install.html"
msgstr ""
#: src/cargo/rust-ecosystem.md:63
msgid "[cargo clippy]: https://github.com/rust-lang/rust-clippy"
msgstr ""
#: src/cargo/rust-ecosystem.md:65
msgid "[official Cargo Book]: https://doc.rust-lang.org/cargo/"
msgstr ""
#: src/cargo/code-samples.md:1
msgid "# Code Samples in This Training"
msgstr "# 강의에서의 코드 샘플"
#: src/cargo/code-samples.md:3
msgid ""
"For this training, we will mostly explore the Rust language through "
"examples\n"
"which can be executed through your browser. This makes the setup much easier "
"and\n"
"ensures a consistent experience for everyone."
msgstr ""
"이 강의자료에 있는 모든 예제는 브라우저에서 바로 수행 가능합니다. \n"
"이렇게 한 이유는, 준비 과정을 단순화 시키고, 모두가 같은 환경에서 작업할 수 \n"
"있도록 하기 위함입니다."
#: src/cargo/code-samples.md:7
msgid ""
"Installing Cargo is still encouraged: it will make it easier for you to do "
"the\n"
"exercises. On the last day, we will do a larger exercise which shows you how "
"to\n"
"work with dependencies and for that you need Cargo."
msgstr ""
"그럼에도 불구하고, 카고(cargo)를 직접 설치하는 것을 강력 권장합니다. 이게 "
"과제 작성에 더 도움이 될겁니다. \n"
"또한, 마지막 날에는 의존성이 있는 예제를 작업하게 될 텐데, 그 때에는 어차피 \n"
"카고가 필요합니다."
#: src/cargo/code-samples.md:11
msgid "The code blocks in this course are fully interactive:"
msgstr "이 강의 자료의 코드 블록들은 전부 인터엑티브 합니다."
#: src/cargo/code-samples.md:13
msgid ""
"```rust,editable\n"
"fn main() {\n"
" println!(\"Edit me!\");\n"
"}\n"
"```"
msgstr ""
#: src/cargo/code-samples.md:19
msgid ""
"You can use <kbd>Ctrl + Enter</kbd> to execute the code when focus is in "
"the\n"
"text box."
msgstr ""
"코드 블록에 포커스를 두고 <kbd>Ctrl-Enter</kbd>를 눌러 실행해 볼 수 있습니"
"다. "
#: src/cargo/code-samples.md:24
msgid ""
"Most code samples are editable like shown above. A few code samples\n"
"are not editable for various reasons:"
msgstr ""
"강의에서 대부분의 코드 샘플은 위와 같이 수정할수 있지만 일부 코드는 다음과 "
"같은 이유로 수정할 수 없습니다: "
#: src/cargo/code-samples.md:27
msgid ""
"* The embedded playgrounds cannot execute unit tests. Copy-paste the\n"
" code and open it in the real Playground to demonstrate unit tests."
msgstr ""
"* 유닛 테스트는 내장 플레이그라운드에서 실행이 안됩니다. 외부 플레이그라운드 "
"사이트에 붙여넣어 테스트를 실행하시기 바랍니다."
#: src/cargo/code-samples.md:30
msgid ""
"* The embedded playgrounds lose their state the moment you navigate\n"
" away from the page! This is the reason that the students should\n"
" solve the exercises using a local Rust installation or via the\n"
" Playground."
msgstr ""
"* 내장된 플레이그라운드에서는 페이지 이동시 작성된 모든 내용이 사라집니다. "
"따라서 로컬 환경이나 외부 플레이그라운드 사이트에서 연습문제를 해결하는 것이 "
"좋습니다."
#: src/cargo/running-locally.md:1
msgid "# Running Code Locally with Cargo"
msgstr "# 로컬 환경의 카고"
#: src/cargo/running-locally.md:3
msgid ""
"If you want to experiment with the code on your own system, then you will "
"need\n"
"to first install Rust. Do this by following the [instructions in the Rust\n"
"Book][1]. This should give you a working `rustc` and `cargo`. At the time "
"of\n"
"writing, the latest stable Rust release has these version numbers:"
msgstr ""
"만약 개인용 컴퓨터에서 코드를 실행해보려면 먼저 러스트를 설치해야 합니"
"다. \n"
"[Rust Book][1]의 지침에 따라 `rustc`와 `cargo`를 함께 설치 하시기 바랍니"
"다. \n"
" 설치 후 아래 커맨드를 통해 각 툴의 버전을 확인 할 수 있습니다. "
#: src/cargo/running-locally.md:8
msgid ""
"```shell\n"
"% rustc --version\n"
"rustc 1.61.0 (fe5b13d68 2022-05-18)\n"
"% cargo --version\n"
"cargo 1.61.0 (a028ae4 2022-04-29)\n"
"```"
msgstr ""
#: src/cargo/running-locally.md:15
msgid ""
"With this is in place, then follow these steps to build a Rust binary from "
"one\n"
"of the examples in this training:"
msgstr ""
"정상적으로 설치가 되었으면 강의의 코드 블록중 하나를 아래 단계를 따라 로컬에"
"서 실행할 수 있습니다."
#: src/cargo/running-locally.md:18
msgid ""
"1. Click the \"Copy to clipboard\" button on the example you want to copy."
msgstr "1. 예시 블록에 있는 \"Copy to clipboard\"버튼을 클릭해서 복사합니다."
#: src/cargo/running-locally.md:20
msgid ""
"2. Use `cargo new exercise` to create a new `exercise/` directory for your "
"code:"
msgstr ""
"2. 터미널에서 `cargo new exercise`를 입력해서 새로운 `exercise/` 폴더를 만듭"
"니다."
#: src/cargo/running-locally.md:22
msgid ""
" ```shell\n"
" $ cargo new exercise\n"
" Created binary (application) `exercise` package\n"
" ```"
msgstr ""
#: src/cargo/running-locally.md:27
msgid ""
"3. Navigate into `exercise/` and use `cargo run` to build and run your "
"binary:"
msgstr ""
"3. `exercise/` 폴더로 이동한 후, `cargo run` 커맨드로 코드를 실행합니다."
#: src/cargo/running-locally.md:29
msgid ""
" ```shell\n"
" $ cd exercise\n"
" $ cargo run\n"
" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n"
" Finished dev [unoptimized + debuginfo] target(s) in 0.75s\n"
" Running `target/debug/exercise`\n"
" Hello, world!\n"
" ```"
msgstr ""
#: src/cargo/running-locally.md:38
msgid ""
"4. Replace the boiler-plate code in `src/main.rs` with your own code. For\n"
" example, using the example on the previous page, make `src/main.rs` look "
"like"
msgstr ""
"4. `src/main.rs`에 코드를 작성합니다. 예를 들어 이전 페이지의 소스를 아래와 "
"같이 `src/main.rs`에 작성합니다."
#: src/cargo/running-locally.md:41
msgid ""
" ```rust\n"
" fn main() {\n"
" println!(\"Edit me!\");\n"
" }\n"
" ```"
msgstr ""
#: src/cargo/running-locally.md:47
msgid "5. Use `cargo run` to build and run your updated binary:"
msgstr "5. `cargo run`커맨드로 소스를 빌드하고 실행합니다."
#: src/cargo/running-locally.md:49
msgid ""
" ```shell\n"
" $ cargo run\n"
" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n"
" Finished dev [unoptimized + debuginfo] target(s) in 0.24s\n"
" Running `target/debug/exercise`\n"
" Edit me!\n"
" ```"
msgstr ""
#: src/cargo/running-locally.md:57
msgid ""
"6. Use `cargo check` to quickly check your project for errors, use `cargo "
"build`\n"
" to compile it without running it. You will find the output in `target/"
"debug/`\n"
" for a normal debug build. Use `cargo build --release` to produce an "
"optimized\n"
" release build in `target/release/`."
msgstr ""
"6. `cargo check`커맨드는 빠르게 에러를 확인할 수 있습니다.\n"
" * `cargo build`는 실행없이 컴파일만 합니다. 이 경우에 `target/"
"debug/`폴더에서 output을 확인 할 수 있습니다. \n"
" * `cargo build --release`커맨드는 릴리즈 버전용 최적화를 켜서 컴파"
"일하며 `target/release/`폴더에서 확인 할 수 있습니다."
#: src/cargo/running-locally.md:62
msgid ""
"7. You can add dependencies for your project by editing `Cargo.toml`. When "
"you\n"
" run `cargo` commands, it will automatically download and compile missing\n"
" dependencies for you."
msgstr ""
"7. `Cargo.toml`파일에는 의존성 패키지를 추가할 수 있습니다. \n"
" - `cargo`커맨드를 실행하면 자동으로 의존성 패키지를 다운로"
"드하고 컴파일 까지 해 줍니다."
#: src/cargo/running-locally.md:66
msgid "[1]: https://doc.rust-lang.org/book/ch01-01-installation.html"
msgstr ""
#: src/cargo/running-locally.md:70
msgid ""
"Try to encourage the class participants to install Cargo and use a\n"
"local editor. It will make their life easier since they will have a\n"
"normal development environment."
msgstr ""
"수강생들이 카고를 설치하고 로컬 편집기를 이용하도록 독려하세요. \n"
"조금 귀찮을 수도 있지만, 이렇게 해야만 좀 더 실제와 가까운 개발환경을 \n"
"갖추게 되는 것입니다."
#: src/welcome-day-1.md:1
msgid "# Welcome to Day 1"
msgstr "# 1일차 개요"
#: src/welcome-day-1.md:3
msgid ""
"This is the first day of Comprehensive Rust. We will cover a lot of ground\n"
"today:"
msgstr "강의 첫 날입니다. 오늘 배울 것이 참 많습니다."
#: src/welcome-day-1.md:6
msgid ""
"* Basic Rust syntax: variables, scalar and compound types, enums, structs,\n"
" references, functions, and methods."
msgstr ""
"* 러스트 기본 문법: 변수, 스칼라 / 복합 타입, 열거형, 구조체, 참조형, 함수"
"와 메서드."
#: src/welcome-day-1.md:9
msgid ""
"* Memory management: stack vs heap, manual memory management, scope-based "
"memory\n"
" management, and garbage collection."
msgstr ""
"* 메모리 관리: 스택과 힙, 수동 메모리 관리, 스코프(범위)기반 메모리 관리, 가"
"비지 컬렉션(GC)"
#: src/welcome-day-1.md:12
msgid ""
"* Ownership: move semantics, copying and cloning, borrowing, and lifetimes."
msgstr "* 소유권: Move 문법, 복사와 복제, 빌림, 수명"
#: src/welcome-day-1.md:16
msgid "Please remind the students that:"
msgstr "학생들에게 다음을 상기시켜 주시기 바랍니다:"
#: src/welcome-day-1.md:18
msgid ""
"* They should ask questions when they get them, don't save them to the end.\n"
"* The class is meant to be interactive and discussions are very much "
"encouraged!\n"
" * As an instructor, you should try to keep the discussions relevant, i."
"e.,\n"
" keep the related to how Rust does things vs some other language. It can "
"be\n"
" hard to find the right balance, but err on the side of allowing "
"discussions\n"
" since they engage people much more than one-way communication.\n"
"* The questions will likely mean that we about things ahead of the slides.\n"
" * This is perfectly okay! Repetition is an important part of leaning. "
"Remember\n"
" that the slides are just a support and you are free to skip them as you\n"
" like."
msgstr ""
"* 궁금한 점이 있으면 주저하지 말고 질문 해야 합니다.\n"
"* 이 수업은 상호작용이 중요하고 토론을 권장합니다.\n"
" * 강사로서, 관련성 있는 토론이 유지되도록 노력해야 합니다. 즉, 러스트가 다"
"른 언어와 비교하여 어떻게 일을 처리하는지에 대한 관련성을 유지해야 합니다. 적"
"절한 균형을 찾기 어렵겠지만 일방적인 강의 보다 더 많은 사람들을 참여시킬 수 "
"있습니다.\n"
"* 질문들이 슬라이드보다 앞서가도 괜찮습니다. 슬라이드는 그저 도움을 줄 뿐, 원"
"하는 대로 건너띄어도 됩니다."
#: src/welcome-day-1.md:29
msgid ""
"The idea for the first day is to show _just enough_ of Rust to be able to "
"speak\n"
"about the famous borrow checker. The way Rust handles memory is a major "
"feature\n"
"and we should show students this right away."
msgstr ""
"첫 날 강의의 목표는, 러스트에서 그 유명한 빌림 확인에 대해서 이야기 할 수 있을 "
"정도 까지만 러스트를 소개하는 것입니다.\n"
"러스트의 가장 독특한 특징이 메모리를 다루는 방식이기 때문에, 학생들에게 이 부분 "
"을 우선적으로 보여주려 합니다."
#: src/welcome-day-1.md:33
msgid ""
"If you're teaching this in a classroom, this is a good place to go over the\n"
"schedule. We suggest splitting the day into two parts (following the slides):"
msgstr ""
"만약 당신이 강의실에서 가르치고 있다면, 이 슬라이드는 일정을 검토하기에 적"
"합한 곳입니다. \n"
"우리는 하루치 강의를 슬라이드에 따라서 두 부분으로 나누는 것을 추천합니다."
#: src/welcome-day-1.md:36
msgid ""
"* Morning: 9:00 to 12:00,\n"
"* Afternoon: 13:00 to 16:00."
msgstr ""
"* 오전: 9:00 to 12:00,\n"
"* 오후: 13:00 to 16:00."
#: src/welcome-day-1.md:39
msgid ""
"You can of course adjust this as necessary. Please make sure to include "
"breaks,\n"
"we recommend a break every hour!"
msgstr ""
"물론 필요에 따라 조절할 수 있습니다. 강의 중간에 쉬는시간을 넣는 것을 잊지 마세요.\n"
"매 시간 휴식을 갖는걸 추천합니다."
#: src/welcome-day-1/what-is-rust.md:1
msgid "# What is Rust?"
msgstr "# 러스트란?"
#: src/welcome-day-1/what-is-rust.md:3
msgid "Rust is a new programming language which had its 1.0 release in 2015:"
msgstr "러스트는, 2015년에 버전 1.0을 릴리즈 한, 새로운 프로그램 언어입니다: "
#: src/welcome-day-1/what-is-rust.md:5
msgid ""
"* Rust is a statically compiled language in a similar role as C++\n"
" * `rustc` uses LLVM as its backend.\n"
"* Rust supports many [platforms and\n"
" architectures](https://doc.rust-lang.org/nightly/rustc/platform-support."
"html):\n"
" * x86, ARM, WebAssembly, ...\n"
" * Linux, Mac, Windows, ...\n"
"* Rust is used for a wide range of devices:\n"
" * firmware and boot loaders,\n"
" * smart displays,\n"
" * mobile phones,\n"
" * desktops,\n"
" * servers."
msgstr ""
"* 러스트는 C++와 유사한 정적 컴파일 언어입니다.\n"
" * 'rustc'는 LLVM을 백엔드로 사용합니다.\n"
"* 러스트는 다양한 플랫폼과 아키텍쳐를 지원합니다.\n"
" * x86, ARM, WebAssembly, ...\n"
" * Linux, Mac, Windows, ...\n"
"* 러스트는 다양한 장치에서 사용될 수 있습니다. \n"
" * 펌웨어와 부트로더(임베디드)\n"
" * 스마트 디스플레이\n"
" * 스마트폰\n"
" * 데스크탑\n"
" * 서버\n"
" "
#: src/welcome-day-1/what-is-rust.md:21
msgid "Rust fits in the same area as C++:"
msgstr "러스트는 C++가 사용되는 대부분의 곳에서 사용 가능합니다."
#: src/welcome-day-1/what-is-rust.md:23
msgid ""
"* High flexibility.\n"
"* High level of control.\n"
"* Can be scaled down to very constrained devices like mobile phones.\n"
"* Has no runtime or garbage collection.\n"
"* Focuses on reliability and safety without sacrificing performance."
msgstr ""
"* 높은 유연성\n"
"* 높은 레벨 수준의 제어\n"
"* 휴대폰과 같은 매우 제한된 장치로 스케일 다운 가능\n"
"* 별도의 런타임을 필요로 하지 않으며, 가비지 컬렉션도 없음\n"
"* 성능을 타협하지 않으면서도 안정성과 안전에 중점을 둠"
#: src/hello-world.md:1
msgid "# Hello World!"
msgstr "# Hello World!"
#: src/hello-world.md:3
msgid ""
"Let us jump into the simplest possible Rust program, a classic Hello World\n"
"program:"
msgstr ""
"가장 간단한 러스트 프로그램으로써, 고전적인 Hello World 를 작성해 "
"보겠습니다."
#: src/hello-world.md:6
msgid ""
"```rust\n"
"fn main() {\n"
" println!(\"Hello 🌍!\");\n"
"}\n"
"```"
msgstr ""
#: src/hello-world.md:12
msgid "What you see:"
msgstr "확인 할 수 있는 것들: "
#: src/hello-world.md:14
msgid ""
"* Functions are introduced with `fn`.\n"
"* Blocks are delimited by curly braces like in C and C++.\n"
"* The `main` function is the entry point of the program.\n"
"* Rust has hygienic macros, `println!` is an example of this.\n"
"* Rust strings are UTF-8 encoded and can contain any Unicode character."
msgstr ""
"* 함수는 `fn`으로 선언합니다.\n"
"* C/C++ 와 마찬가지로 중괄호`{}`로 블록을 표시합니다. \n"
"* `main` 함수는 프로그램 진입점입니다. \n"
"* 러스트는 똑똑한 매크로(hygienic macros) 시스템을 가지고 있습니다. `println!`"
"는 그 예시입니다.\n"
"* 러스트의 문자열은 UTF-8로 인코딩되며 이모지와 같은 유니코드 문자를 포함할 "
"수 있습니다."
#: src/hello-world.md:22
msgid ""
"This slide tries to make the students comfortable with Rust code. They will "
"see\n"
"a ton of it over the next four days so we start small with something "
"familiar."
msgstr ""
"이 슬라이드는 학생들이 러스트 코드에 익숙해지기 위해 작성되었습니다. 앞으로 4"
"일 동안 많은 코드를 접할 것이기 때문에 우선 친숙한 코드부터 시작합니다."
#: src/hello-world.md:27
msgid ""
"* Rust is very much like other languages in the C/C++/Java tradition. It is\n"
" imperative (not functional) and it doesn't try to reinvent things unless\n"
" absolutely necessary."
msgstr ""
"* 러스트는 C/C++/Java와 같은 전통적인 다른 언어와 매우 유사합니다. 러스트는 \n"
" 절차적(함수형 아님) 언어입니다. 정말로 필요한 경우가 아니라면, 러스트는 \n"
" 이미 존재하는 것을 새로 구현하려고 하지 않습니다."
#: src/hello-world.md:31
msgid "* Rust is modern with full support for things like Unicode."
msgstr "* 러스트는 유니코드 지원과 같은 현대 언어의 특징을 전부 지원합니다."
#: src/hello-world.md:33
msgid ""
"* Rust uses macros for situations where you want to have a variable number "
"of\n"
" arguments (no function [overloading](basic-syntax/functions-interlude.md))."
msgstr ""
"* 러스트는 인자의 개수를 사전에 지정할 수 없는 상황에서 함수 "
"[오버로딩](basic-syntax/functions-interlude.md)대신 매크로를 사용합니다."
#: src/hello-world/small-example.md:1
msgid "# Small Example"
msgstr "# 작은 예제"
#: src/hello-world/small-example.md:3
msgid "Here is a small example program in Rust:"
msgstr "러스트로 작성된 작은 예제입니다. "
#: src/hello-world/small-example.md:5
msgid ""
"```rust,editable\n"
"fn main() { // Program entry point\n"
" let mut x: i32 = 6; // Mutable variable binding\n"
" print!(\"{x}\"); // Macro for printing, like printf\n"
" while x != 1 { // No parenthesis around expression\n"
" if x % 2 == 0 { // Math like in other languages\n"
" x = x / 2;\n"
" } else {\n"
" x = 3 * x + 1;\n"
" }\n"
" print!(\" -> {x}\");\n"
" }\n"
" println!();\n"
"}\n"
"```"
msgstr ""
"```rust,editable\n"
"fn main() { // 프로그램 진입점입니다.\n"
" let mut x: i32 = 6; // 가변 변수 할당(binding)입니다.\n"
" print!(\"{x}\"); // printf와 같은 출력을 위한 매크로 입니다.\n"
" while x != 1 { // 표현식에 괄호는 없습니다.\n"
" if x % 2 == 0 { // 다른 언어와 같은 수학연산식이 사용됩니다.\n"
" x = x / 2;\n"
" } else {\n"
" x = 3 * x + 1;\n"
" }\n"
" print!(\" -> {x}\");\n"
" }\n"
" println!();\n"
"}\n"
"```"
#: src/hello-world/small-example.md:23
msgid ""
"The code implements the Collatz conjecture: it is believed that the loop "
"will\n"
"always end, but this is not yet proved. Edit the code and play with "
"different\n"
"inputs."
msgstr ""
"이 코드는 콜라츠 추측(Collatz conjecture)으로 구현됩니다:반복문이 언제나 종료"
"될 것이라고 믿지만 증명된 것은 아닙니다. 코드를 수정하고 실행해 보시기 바랍니"
"다."
#: src/hello-world/small-example.md:29
msgid ""
"* Explain that all variables are statically typed. Try removing `i32` to "
"trigger\n"
" type inference. Try with `i8` instead and trigger a runtime integer "
"overflow."
msgstr ""
"* 모든 변수가 컴파일 시 정해진 타입을 가짐을 설명합니다. i32를 삭제하여 "
" 컴파일러가 타입 추론을 하도록 해 봅니다. "
" i32을 i8로 변경하여 런타임 오버플로를 유발해 볼 수 있습"
"니다."
#: src/hello-world/small-example.md:32
msgid "* Change `let mut x` to `let x`, discuss the compiler error."
msgstr "* `let mut x`를 `let x`로 수정하여 컴파일 오류에 대해 토론합니다."
#: src/hello-world/small-example.md:34
msgid ""
"* Show how `print!` gives a compilation error if the arguments don't match "
"the\n"
" format string."
msgstr ""
"* 인자가 포맷 문자열과 일치하지 않는 경우 `print!`에서 컴파일 오류가 발생함"
"을 언급하는 것도 좋습니다."
#: src/hello-world/small-example.md:37
msgid ""
"* Show how you need to use `{}` as a placeholder if you want to print an\n"
" expression which is more complex than just a single variable."
msgstr ""
"* 단일 변수보다 복잡한 식을 출려하려면 `{}`을 자리 표시자로 사용하는 방"
"법을 보여 줍니다."
#: src/hello-world/small-example.md:40
msgid ""
"* Show the students the standard library, show them how to search for `std::"
"fmt`\n"
" which has the rules of the formatting mini-language. It's important that "
"the\n"
" students become familiar with searching in the standard library."
msgstr ""
"학생들에게 표준 라이브러리가 어디 있는지 알려 주고는, `print!`가 지원하는 "
"포맷팅 언어의 문법을 알기 위해 `std::fmt`를 검색해야 한다는 것을 가르치세요."
"학생들이 표준 라이브러리의 검색 기능에 익숙해 지도록 하는 것이 중요합니다."
#: src/why-rust.md:1
msgid "# Why Rust?"
msgstr "# 러스트를 써야하는 이유"
#: src/why-rust.md:3
msgid "Some unique selling points of Rust:"
msgstr "러스트만의 독특한 세일즈 포인트(장점):"
#: src/why-rust.md:5
msgid ""
"* Compile time memory safety.\n"
"* Lack of undefined runtime behavior.\n"
"* Modern language features."
msgstr ""
"* 컴파일 시 메모리 안전이 보장됨\n"
"* 정의되지 않은 런타임 동작이 없음\n"
"* 현대적인 언어 기능"
#: src/why-rust.md:11
msgid ""
"Make sure to ask the class which languages they have experience with. "
"Depending\n"
"on the answer you can highlight different features of Rust:"
msgstr ""
"수강생들에게 어떤 프로그래밍 언어를 사용했는지 물어보시기 바랍니다. "
"어떤 언어를 사용했느냐에 따라 러스트에서 어떤 점을 강조해야 할지를 고민해 "
"보세요."
#: src/why-rust.md:14
msgid ""
"* Experience with C or C++: Rust eliminates a whole class of _runtime "
"errors_\n"
" via the borrow checker. You get performance like in C and C++, but you "
"don't\n"
" have the memory unsafety issues. In addition, you get a modern language "
"with\n"
" constructs like pattern matching and built-in dependency management."
msgstr ""
"* C/C++: 러스트는 '빌림'검사기를 통해서 수행중에 발생할 수 있는 모든 에러를 "
" 제거합니다. 러스트는 C와 C++과 비슷한 수준의 성능을 보여주면서도, 그 언어들"
"에서 종종 발생하는 메모리 관련 오류가 없습니다. 또한, 패턴 매칭이나, 기본적으로 "
"제공되는 종속성 관리와 같은 현대적인 언어의 기능들을 제공합니다."
#: src/why-rust.md:19
msgid ""
"* Experience with Java, Go, Python, JavaScript...: You get the same memory "
"safety\n"
" as in those languages, plus a similar high-level language feeling. In "
"addition\n"
" you get fast and predictable performance like C and C++ (no garbage "
"collector)\n"
" as well as access to low-level hardware (should you need it)"
msgstr ""
"* Java, Go, Python, JaveScript: 이 언어들과 동일한 메모리 안정성과 함께, '하이레"
"벨'언어의 느낌을 느낄 수 있습니다. 거기에 더해, 가비지 컬렉터가 없는 C/C++와 유사한 "
"수준의 빠르고 예측 가능한 성능을 기대할 수 있습니다. 그리고 필요한 경우 저수준 "
"하드웨어를 다루는 코드로 작성할 수 있습니다."
#: src/why-rust/compile-time.md:1
msgid "# Compile Time Guarantees"
msgstr "# 컴파일 시 보장되는 것들"
#: src/why-rust/compile-time.md:3
msgid "Static memory management at compile time:"
msgstr "컴파일 시 정적 메모리 관리:"
#: src/why-rust/compile-time.md:5
msgid ""
"* No uninitialized variables.\n"
"* No memory leaks (_mostly_, see notes).\n"
"* No double-frees.\n"
"* No use-after-free.\n"
"* No `NULL` pointers.\n"
"* No forgotten locked mutexes.\n"
"* No data races between threads.\n"
"* No iterator invalidation."
msgstr ""
"* 초기화되지 않는 변수가 없습니다.\n"
"* 메모리 누출 없음(_거의_. 강의참조노트 참고.)\n"
"* 메모리 이중 해제가 원천적으로 불가능 합니다.\n"
"* 메모리 해제 후 사용이 원천적으로 불가능 합니다.\n"
"* `NULL`포인터는 없습니다.\n"
"* 뮤텍스를 잠궈 놓고 여는 것을 잊는 실수를 할 수 없습니다.\n"
"* 스레드간 데이터 레이스를 막아줍니다.\n"
"* 반복자가 갑자기 무효화 되는 경우가 없습니다."
#: src/why-rust/compile-time.md:16
msgid ""
"It is possible to produce memory leaks in (safe) Rust. Some examples\n"
"are:"
msgstr ""
"(안전한) 러스트에서도 메모리 누출이 발생할 수 있는 몇 가지 경우가 있습니다."
#: src/why-rust/compile-time.md:19
msgid ""
"* You can for use [`Box::leak`] to leak a pointer. A use of this could\n"
" be to get runtime-initialized and runtime-sized static variables\n"
"* You can use [`std::mem::forget`] to make the compiler \"forget\" about\n"
" a value (meaning the destructor is never run).\n"
"* You can also accidentally create a [reference cycle] with `Rc` or\n"
" `Arc`.\n"
"* In fact, some will consider infinitely populating a collection a memory\n"
" leak and Rust does not protect from those."
msgstr ""
"* [`Box::leak`]을 이용하여 포인터를 의도적으로 누출시킬 수 있습니다. 이를 이용해서 "
" 런타임이 생성하고 런타임이 크기를 정한 정적 변수를 가져올 수 있습니다.\n"
"* [`std::mem::forget`]을 사용하여 컴파일러가 값에 대해 \"잊도록\" 만들 수 있"
"습니다(소멸자가 실행되지 않음을 의미합니다).\n"
"* `Rc` 또는 `Arc`를 사용하여 실수로 [순환참조][reference cycle]을 생성할 수도 있습니"
"다.\n"
"* 컬렉션을 무한정 채우는 것을 메모리 누출로 간주할 수도 있지만, 러스트는 이"
"를 보호하진 못합니다."
#: src/why-rust/compile-time.md:28
msgid ""
"For the purpose of this course, \"No memory leaks\" should be understood\n"
"as \"Pretty much no *accidental* memory leaks\"."
msgstr ""
"본 강의에서는 \"메모리 누출 없음\"을 \"우발적인 메모리 누출 없음\"으로 이해해"
"야 합니다."
#: src/why-rust/compile-time.md:31
msgid ""
"[`Box::leak`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method."
"leak\n"
"[`std::mem::forget`]: https://doc.rust-lang.org/std/mem/fn.forget.html\n"
"[reference cycle]: https://doc.rust-lang.org/book/ch15-06-reference-cycles."
"html"
msgstr ""
#: src/why-rust/runtime.md:1
msgid "# Runtime Guarantees"
msgstr "# 런타임 시 보장되는 것들"
#: src/why-rust/runtime.md:3
msgid "No undefined behavior at runtime:"
msgstr "런타임 시 정의되지 않음(undefined) 동작 없음:"
#: src/why-rust/runtime.md:5
msgid ""
"* Array access is bounds checked.\n"
"* Integer overflow is defined."
msgstr ""
"* 배열 접근시 경계 체크\n"
"* 정수형 타입의 변수에서 오버플로우 발생시 동작이 잘 정의되어있습니다."
#: src/why-rust/runtime.md:12
msgid ""
"* Integer overflow is defined via a compile-time flag. The options are\n"
" either a panic (a controlled crash of the program) or wrap-around\n"
" semantics. By default, you get panics in debug mode (`cargo build`)\n"
" and wrap-around in release mode (`cargo build --release`)."
msgstr ""
"* 정수형 오버플로우는 컴파일 타임 플레그를 통해 정의됩니다. 옵션은 패닉(프로"
"그램 크레시) 혹은 올림(wrap-around)입니다. 기본적으로 디버그 모드(`cargo "
"build`)에서는 패닉이, 릴리즈 모드(`cargo build --release`)에서는 wrap-around"
"가 발생합니다."
#: src/why-rust/runtime.md:17
msgid ""
"* Bounds checking cannot be disabled with a compiler flag. It can also\n"
" not be disabled directly with the `unsafe` keyword. However,\n"
" `unsafe` allows you to call functions such as `slice::get_unchecked`\n"
" which does not do bounds checking."
msgstr ""
"* 컴파일 플래그를 사용하여 경계체크를 무력화 할 수 없습니다. `unsafe`를 사용"
"하더라도 마찬가지입니다. 하지만 `unsafe`에서 호출 가능한 `slice::"
"get_unchecked`같은 함수는 경계 검사를 수행하지 않습니다."
#: src/why-rust/modern.md:1
msgid "# Modern Features"
msgstr "# 현대적인 특징"
#: src/why-rust/modern.md:3
msgid "Rust is built with all the experience gained in the last 40 years."
msgstr ""
"러스트는 지난 40년간의 모든 (프로그래밍 언어들의) 경험으로 만들어졌습니다."
#: src/why-rust/modern.md:5
msgid "## Language Features"
msgstr "## 언어적 특징"
#: src/why-rust/modern.md:7
msgid ""
"* Enums and pattern matching.\n"
"* Generics.\n"
"* No overhead FFI.\n"
"* Zero-cost abstractions."
msgstr ""
"* 열거형과 패턴 매칭\n"
"* 제너릭\n"
"* FFI 런타임 오버헤드 없음.\n"
" * _역주: FFI: Foreign Function Interface. 타 언어 코드를 호출하기 위한 인터"
"페이스_\n"
"* 제로 코스트 추상화"
#: src/why-rust/modern.md:12
msgid "## Tooling"
msgstr "## 도구들"
#: src/why-rust/modern.md:14
msgid ""
"* Great compiler errors.\n"
"* Built-in dependency manager.\n"
"* Built-in support for testing.\n"
"* Excellent Language Server Protocol support."
msgstr ""
"* 친절한 컴파일러 오류메시지\n"
"* 내장 종속성 관리자\n"
"* 내장 테스트 지원\n"
"* LSP (Language Server Protocol, 언어 서버 프로토콜) 지원이 잘되어 있음"
#: src/why-rust/modern.md:23
msgid ""
"* Zero-cost abstractions, similar to C++, means that you don't have to "
"'pay'\n"
" for higher-level programming constructs with memory or CPU. For example,\n"
" writing a loop using `for` should result in roughly the same low level\n"
" instructions as using the `.iter().fold()` construct."
msgstr ""
"* C++ 와 유사하게 제로 코스트 추상화는 CPU나 메모리를 사용하여 상위레벨 프로그"
"래밍 구조를 만드는데 '비용'을 지불할 필요가 없습니다. \n"
"예를 들어 `for` 루프와와 `iter().fold()` 구조를 사용하는 것과 거의 동일한 낮"
"은 수준의 명령어가 생성될 것 입니다."
#: src/why-rust/modern.md:28
msgid ""
"* It may be worth mentioning that Rust enums are 'Algebraic Data Types', "
"also\n"
" known as 'sum types', which allow the type system to express things like\n"
" `Option<T>` and `Result<T, E>`."
msgstr ""
"* 러스트의 열거형(enum)은 합계 타입(`sum types`)으로 알려진 대수학적 데이터형"
"('Algebraic Data Types')으로, 타입 시스템이 `Option<T>`와 `Result<T, E>`등을 "
"표현할 수 있게 해줍니다."
#: src/why-rust/modern.md:32
msgid ""
"* Remind people to read the errors --- many developers have gotten used to\n"
" ignore lengthly compiler output. The Rust compiler is significantly more\n"
" talkative than other compilers. It will often provide you with "
"_actionable_\n"
" feedback, ready to copy-paste into your code."
msgstr ""
"* 오류를 읽어보시기 바랍니다 --- 오랜기간 많은 개발자들이 컴파일러 출력을 무"
"시하는데 익숙해져 있습니다. 러스트 컴파일러는 다른 컴파일러보다 더 수다스럽"
"고, 복사-붙여넣기 할 수 있는 정도의 코드 피드백을 제공하는 경우가 많습니다. "
#: src/why-rust/modern.md:37
msgid ""
"* The Rust standard library is small compared to languages like Java, "
"Python,\n"
" and Go. Rust does not come with several things you might consider standard "
"and\n"
" essential:"
msgstr ""
"* 러스트 표준 라이브러리는 Java, Python이나 Go와 같은 언어에 비해서 규모가 "
"작습니다. 당연히 포함되어야 한다고 생각할 수도 있는 아래와 같은 것들이 "
"러스트의 표준 라이브러리에 없습니다."
#: src/why-rust/modern.md:41
msgid ""
" * a random number generator, but see [rand].\n"
" * support for SSL or TLS, but see [rusttls].\n"
" * support for JSON, but see [serde_json]."
msgstr ""
" * 난수 생성기, 하지만 [rand]문서를 참조하시기 바랍니다.\n"
" * SSL 또는 TLS지원, 하지만 [rusttls]문서를 참조하시기 바랍니다.\n"
" * JSON 지원, 하지만 [serde_json] 문서를 참조하시기 바랍니다."
#: src/why-rust/modern.md:45
msgid ""
" The reasoning behind this is that functionality in the standard library "
"cannot\n"
" go away, so it has to be very stable. For the examples above, the Rust\n"
" community is still working on finding the best solution --- and perhaps "
"there\n"
" isn't a single \"best solution\" for some of these things."
msgstr ""
"그 이유는 표준 라이브러리에서 한 번 어떤 기능을 제공하면 뺄 수 없으며, 매우 "
"안정적이어야 하기 때문입니다. 위에 언급한 기능들은 아직 러스트 커뮤니티가 "
"최고의 솔루션을 찾지 못했기 때문에 표준 라이브러리에 포함되지 않았습니다. "
"어쩌면 이들 중 몇 개는 '최고의 솔루션'이 아예 존재할 수 없을 지도 모릅니다."
#: src/why-rust/modern.md:50
msgid ""
" Rust comes with a built-in package manager in the form of Cargo and this "
"makes\n"
" it trivial to download and compile third-party crates. A consequence of "
"this\n"
" is that the standard library can be smaller."
msgstr ""
"* 러스트는 카고라는 패키지 관리자가 내장되어 있고, 서드파티 크레이트를 다운"
"로드, 컴파일 하기 매우 쉽습니다. 이 또한 표준 라이브러리가 작은 이유입니다."
#: src/why-rust/modern.md:54
msgid ""
" Discovering good third-party crates can be a problem. Sites like\n"
" <https://lib.rs/> help with this by letting you compare health metrics "
"for\n"
" crates to find a good and trusted one.\n"
" \n"
"* [rust-analyzer] is a well supported LSP implementation used in major\n"
" IDEs and text editors."
msgstr ""
"* 좋은 서드파티 크레이트를 찾는 것은 어렵습니다. <https://"
"lib.rs> 와 같은 사이트가 신뢰할수 있는 좋은 크레이트를 비교하여 찾는데 좋습니다."
"* [rust-analyzer]는 주요 IDE나 텍스트 에디터에서 사용되는 러스트용 LSP서버 입니다."
#: src/why-rust/modern.md:61
msgid ""
"[rand]: https://docs.rs/rand/\n"
"[rusttls]: https://docs.rs/rustls/\n"
"[serde_json]: https://docs.rs/serde_json/\n"
"[rust-analyzer]: https://rust-analyzer.github.io/"
msgstr ""
#: src/basic-syntax.md:1
msgid "# Basic Syntax"
msgstr "# 기본 문법"
#: src/basic-syntax.md:3
msgid "Much of the Rust syntax will be familiar to you from C or C++:"
msgstr "대부분의 러스트 문법은 C/C++ 와 유사합니다:"
#: src/basic-syntax.md:5
msgid ""
"* Blocks and scopes are delimited by curly braces.\n"
"* Line comments are started with `//`, block comments are delimited by `/"
"* ...\n"
" */`.\n"
"* Keywords like `if` and `while` work the same.\n"
"* Variable assignment is done with `=`, comparison is done with `==`."
msgstr ""
"* 블록과 범위는 중괄호`{}`로 표현합니다. \n"
"* 인라인 주석은 `//`, 블록 주석은 `/* ... */`로 사용합니다. \n"
"* `if`나 `while`같은 키워드도 동일합니다. \n"
"* 변수 할당은 `=`, 비교는 `==`를 사용합니다."
#: src/basic-syntax/scalar-types.md:1
msgid "# Scalar Types"
msgstr "# 스칼라 타입"
#: src/basic-syntax/scalar-types.md:3
msgid ""
"| | Types | "
"Literals |\n"
"|------------------------|--------------------------------------------|-------------------------------|\n"
"| Signed integers | `i8`, `i16`, `i32`, `i64`, `i128`, `isize` | "
"`-10`, `0`, `1_000`, `123i64` |\n"
"| Unsigned integers | `u8`, `u16`, `u32`, `u64`, `u128`, `usize` | `0`, "
"`123`, `10u16` |\n"
"| Floating point numbers | `f32`, `f64` | "
"`3.14`, `-10.0e20`, `2f32` |\n"
"| Strings | `&str` | "
"`\"foo\"`, `r#\"\\\\\"#` |\n"
"| Unicode scalar values | `char` | "
"`'a'`, `'α'`, `'∞'` |\n"
"| Byte strings | `&[u8]` | "
"`b\"abc\"`, `br#\" \" \"#` |\n"
"| Booleans | `bool` | "
"`true`, `false` |"
msgstr ""
"| | 타입 | 스칼라 리터"
"럴 값 |\n"
"|-----------------|--------------------------------------------|-------------------------------|\n"
"| 부호있는 정수 | `i8`, `i16`, `i32`, `i64`, `i128`, `isize` | `-10`, `0`, "
"`1_000`, `123i64` |\n"
"| 부호없는 정수 | `u8`, `u16`, `u32`, `u64`, `u128`, `usize` | `0`, `123`, "
"`10u16` |\n"
"| 부동소수 | `f32`, `f64` | `3.14`, "
"`-10.0e20`, `2f32` |\n"
"| 문자열 | `&str` | `\"foo\"`, "
"`r#\"\\\\\"#` |\n"
"| 유니코드 문자 | `char` | `'a'`, "
"`'α'`, `'∞'` |\n"
"| 바이트 문자 | `&[u8]` | `b\"abc\"`, "
"`br#\" \" \"#` |\n"
"| 불리언 | `bool` | `true`, "
"`false` |"
#: src/basic-syntax/scalar-types.md:13
msgid "The types have widths as follows:"
msgstr "각 타입의 크기는 다음과 같습니다:"
#: src/basic-syntax/scalar-types.md:15
msgid ""
"* `iN`, `uN`, and `fN` are _N_ bits wide,\n"
"* `isize` and `usize` are the width of a pointer,\n"
"* `char` is 32 bit wide,\n"
"* `bool` is 8 bit wide."
msgstr ""
"* 정수(`i`) 및 부동소수형(`f`)은 뒤의 숫자와 같은 비트 수 입니다. (`i8` = 8비트)\n"
"* `isize` 와 `usize` 는 포인터와 같은 크기입니다.\n"
" * _역주: 32 비트 시스템에서는 32 비트, 64 비트 시스템에서는 64 비트. C의 `int`와 "
"같음._\n"
"* `char` 32 비트 입니다.\n"
"* `bool`은 8 비트 입니다. "
#: src/basic-syntax/compound-types.md:1
msgid "# Compound Types"
msgstr "# 복합 타입"
#: src/basic-syntax/compound-types.md:3
msgid ""
"| | Types | Literals "
"|\n"
"|--------|-------------------------------|-----------------------------------|\n"
"| Arrays | `[T; N]` | `[20, 30, 40]`, `[0; 3]` "
"|\n"
"| Tuples | `()`, `(T,)`, `(T1, T2)`, ... | `()`, `('x',)`, `('x', 1.2)`, ... "
"|"
msgstr ""
"| | Types | "
"Literals |\n"
"|--------------|-------------------------------|-----------------------------------|\n"
"| 배열(Arrays) | `[T; N]` | `[20, 30, 40]`, `[0; "
"3]` |\n"
"| 튜플(Tuples) | `()`, `(T,)`, `(T1, T2)`, ... | `()`, `('x',)`, `('x', "
"1.2)`, ... |"
#: src/basic-syntax/compound-types.md:8
msgid "Array assignment and access:"
msgstr ""
"* _역주: js기준으로 설명하면 튜플은 ‘순서가 중요해서 사이즈 N으로 고정된 불"
"변(immutable) 배열’ 이라고 보면 됨._\n"
" _정확히는 서수(순서가 의미가 있는 내용)의 묶음(모음). 갯수N개에 대해서 N-"
"tuple이라고 부르며 2-tuple을 흔히 쓰긴 함.(cf. 열거형)_\n"
"\n"
"배열 선언과 접근:"
#: src/basic-syntax/compound-types.md:10
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let mut a: [i8; 10] = [42; 10];\n"
" a[5] = 0;\n"
" println!(\"a: {:?}\", a);\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/compound-types.md:18
msgid "Tuple assignment and access:"
msgstr "튜플 선언과 접근:"
#: src/basic-syntax/compound-types.md:20
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let t: (i8, bool) = (7, true);\n"
" println!(\"1st index: {}\", t.0);\n"
" println!(\"2nd index: {}\", t.1);\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/compound-types.md:32
msgid "Arrays:"
msgstr "배열:"
#: src/basic-syntax/compound-types.md:34
msgid ""
"* Arrays have elements of the same type, `T`, and length, `N`, which is a "
"compile-time constant.\n"
" Note that the length of the array is *part of its type*, which means that "
"`[u8; 3]` and\n"
" `[u8; 4]` are considered two different types."
msgstr ""
"* 배열은, 같은 타입 `T`의 값이 `N`개 있는 것입니다. 여기서 `N`은 컴파일 "
"타임에 결정된 값이어야 합니다. 이 길이도 타입의 일부입니다. 따라서, "
"`[u8; 3]`와 `[u8; 4]`은 서로 다른 타입입니다."
#: src/basic-syntax/compound-types.md:38
msgid "* We can use literals to assign values to arrays."
msgstr "* 리터럴을 사용하여 배열에 값을 할당할 수 있습니다."
#: src/basic-syntax/compound-types.md:40
msgid ""
"* In the main function, the print statement asks for the debug "
"implementation with the `?` format\n"
" parameter: `{}` gives the default output, `{:?}` gives the debug output. "
"We\n"
" could also have used `{a}` and `{a:?}` without specifying the value after "
"the\n"
" format string."
msgstr ""
"* 포매팅 문자열에서 `?`는 디버깅 출력을 의미합니다. `{}`는 기본 출력이며, `{:?}`는 "
"디버깅 출력입니다. `{a}`와 `{a:?}`와 같이 출력할 변수 이름을 포매팅 문자열에 포함시킬 "
"수도 있으며, 이 경우 인자 `a`는 별도의 인자로 추가하지 않습니다."
#: src/basic-syntax/compound-types.md:45
msgid ""
"* Adding `#`, eg `{a:#?}`, invokes a \"pretty printing\" format, which can "
"be easier to read."
msgstr ""
"* `#`을 추가하면(`{a:#}`) 좀 더 읽기 쉬운 \"이쁜\" 형태로 출력이 됩니다."
#: src/basic-syntax/compound-types.md:47
msgid "Tuples:"
msgstr "튜플:"
#: src/basic-syntax/compound-types.md:49
msgid "* Like arrays, tuples have a fixed length."
msgstr "* 배열과 마찬가지로 튜플은 고정 길이를 갖습니다."
#: src/basic-syntax/compound-types.md:51
msgid "* Tuples group together values of different types into a compound type."
msgstr "* 튜플은 서로 다른 타입의 값들을 하나의 복합 타입으로 묶습니다."
#: src/basic-syntax/compound-types.md:53
msgid ""
"* Fields of a tuple can be accessed by the period and the index of the "
"value, e.g. `t.0`, `t.1`."
msgstr "* 튜플에 속한 값은 `t.0`, `t.1`과 같이 인덱스로 접근할 수 있습니다."
#: src/basic-syntax/compound-types.md:55
msgid ""
"* The empty tuple `()` is also known as the \"unit type\". It is both a "
"type, and\n"
" the only valid value of that type - that is to say both the type and its "
"value\n"
" are expressed as `()`. It is used to indicate, for example, that a "
"function or\n"
" expression has no return value, as we'll see in a future slide. \n"
" * You can think of it as `void` that can be familiar to you from other \n"
" programming languages."
msgstr ""
"* 비어있는 튜플`()`은 단위 타입(unit type)이라고도 합니다. 이는 타입이면서 해"
"당 타입의 유일하며 유효한 값입니다. 즉 타입과 값이 모두 `()`입니다. 예를 들"
"어 함수나 식에서 반환 값이 없음을 나타낼 때 사용합니다. * 다른 언어에서 익숙"
"한 `void` 개념으로 생각할 수 있습니다."
#: src/basic-syntax/references.md:1
msgid "# References"
msgstr "# 참조"
#: src/basic-syntax/references.md:3
msgid "Like C++, Rust has references:"
msgstr "C++와 마찬가지로 러스트도 참조형을 갖습니다:"
#: src/basic-syntax/references.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let mut x: i32 = 10;\n"
" let ref_x: &mut i32 = &mut x;\n"
" *ref_x = 20;\n"
" println!(\"x: {x}\");\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/references.md:14
msgid "Some notes:"
msgstr "참고사항:"
#: src/basic-syntax/references.md:16
msgid ""
"* We must dereference `ref_x` when assigning to it, similar to C and C++ "
"pointers.\n"
"* Rust will auto-dereference in some cases, in particular when invoking\n"
" methods (try `ref_x.count_ones()`).\n"
"* References that are declared as `mut` can be bound to different values "
"over their lifetime."
msgstr ""
"* `ref_x`에 값을 할당할 때, C/C++의 포인터와 유사하게 `*`를 이용해서 참조를 따라가야(역참조) 합니다.\n"
"* 러스트는 특정한 경우(메서드 호출)에 자동으로 역참조를 합니다.(`ref_x."
"count_one()`을 하면 `*ref_x`가 `count_one`의 인자로 전달됩니다.)\n"
"* `mut`로 선언된 참조는 그 변수가 살아있는 동안 다른 값을 가질 수 있습니다."
#: src/basic-syntax/references.md:21
msgid ""
"<details>\n"
"Key points:"
msgstr ""
"<details>\n"
"키 포인트:"
#: src/basic-syntax/references.md:24
msgid ""
"* Be sure to note the difference between `let mut ref_x: &i32` and `let "
"ref_x:\n"
" &mut i32`. The first one represents a mutable reference which can be bound "
"to\n"
" different values, while the second represents a reference to a mutable "
"value."
msgstr ""
"`let mut ref_x: &i32`와 `let ref_x: &mut i32`의 차이점에 주의 하시기 바랍니"
"다.\n"
"첫번째 값은 다른 값에 바인딩 될 수 있는 가변 참조이고, \n"
"두번째 값은 가변 값에 대한 참조입니다."
#: src/basic-syntax/references-dangling.md:1
msgid "# Dangling References"
msgstr "# 허상(dangling) 참조"
#: src/basic-syntax/references-dangling.md:3
msgid "Rust will statically forbid dangling references:"
msgstr ""
"러스트는 허상(dangling) 참조를 컴파일러 단계에서 찾아내고 금지합니다:\n"
"* _역주: 허상 참조: 참조 포인터가 더이상 유효하지 않은 값을 가르키게 되는 경"
"우_"
#: src/basic-syntax/references-dangling.md:5
msgid ""
"```rust,editable,compile_fail\n"
"fn main() {\n"
" let ref_x: &i32;\n"
" {\n"
" let x: i32 = 10;\n"
" ref_x = &x;\n"
" }\n"
" println!(\"ref_x: {ref_x}\");\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/references-dangling.md:16
msgid ""
"* A reference is said to \"borrow\" the value it refers to.\n"
"* Rust is tracking the lifetimes of all references to ensure they live long\n"
" enough.\n"
"* We will talk more about borrowing when we get to ownership."
msgstr ""
"* 참조는 어떤 값을 \"빌리는\" 것입니다.\n"
"* 러스트는 참조 대상의 값이, 그 값에 대한 모든 참조들보다 더 오래 살아있음을 추적합니다.\n"
"* 소유권에 대한 주제를 다룰 때 이 빌림에 대해 더 자세히 이야기 하겠습니다."
#: src/basic-syntax/slices.md:1
msgid "# Slices"
msgstr "# 슬라이스"
#: src/basic-syntax/slices.md:3
msgid "A slice gives you a view into a larger collection:"
msgstr "슬라이스는 큰 컬랙션의 일부(혹은 전체)를 보여주는 뷰(view)입니다."
#: src/basic-syntax/slices.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let a: [i32; 6] = [10, 20, 30, 40, 50, 60];\n"
" println!(\"a: {a:?}\");"
msgstr ""
#: src/basic-syntax/slices.md:10
msgid ""
" let s: &[i32] = &a[2..4];\n"
" println!(\"s: {s:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/slices.md:15
msgid ""
"* Slices borrow data from the sliced type.\n"
"* Question: What happens if you modify `a[3]`?"
msgstr ""
"* 슬라이스는 다른(슬라이스 된) 타입으로부터 데이터를 '빌려'옵니다. \n"
"* 질문: `a[3]`을 수정하면 무슨 일이 있어날까요?"
#: src/basic-syntax/slices.md:20
msgid ""
"* We create a slice by borrowing `a` and specifying the starting and ending "
"indexes in brackets."
msgstr ""
"* 슬라이스는 우선 `a`를 빌린다음, 시작과 끝 인덱스를 브래킷(`[]`)안에 지정해서 만듭니다."
#: src/basic-syntax/slices.md:22
msgid ""
"* If the slice starts at index 0, Rust’s range syntax allows us to drop the "
"starting index, meaning that `&a[0..a.len()]` and `&a[..a.len()]` are "
"identical.\n"
" \n"
"* The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are "
"identical."
msgstr ""
"* 슬라이스가 인덱스 0부터 시작한다면 시작 인덱스는 생략 가능합니다. 즉 "
"`&a[0..a.len()]`와 `&a[..a.len()]` 는 동일합니다.\n"
"* 마지막 인덱스도 생략 가능합니다. 그래서 `&a[2..a.len()]` 와 `&a[2..]`는 동일합니다."
#: src/basic-syntax/slices.md:26
msgid ""
"* To easily create a slice of the full array, we can therefore use `&a[..]`."
msgstr "* 따라서 전체 배열에 대한 슬라이스는 `&a[..]`가 됩니다."
#: src/basic-syntax/slices.md:28
msgid ""
"* `s` is a reference to a slice of `i32`s. Notice that the type of `s` "
"(`&[i32]`) no longer mentions the array length. This allows us to perform "
"computation on slices of different sizes.\n"
" \n"
"* Slices always borrow from another object. In this example, `a` has to "
"remain 'alive' (in scope) for at least as long as our slice. \n"
" \n"
"* The question about modifying `a[3]` can spark an interesting discussion, "
"but the answer is that for memory safety reasons\n"
" you cannot do it through `a` after you created a slice, but you can read "
"the data from both `a` and `s` safely. \n"
" More details will be explained in the borrow checker section."
msgstr ""
"* `s`는 `i32`들로 이루어진 슬라이스에 대한 참조입니다. `s`의 타입(`&[i32]`)에 배열의 크기가"
" 빠져있음에 주목하시기 바랍니다. 즉, 슬라이스를 이용하면 다양한 길이의 데이터를 "
" 다룰 수 있습니다.\n"
" \n"
"* 슬라이스는 항상 다른 객체로부터 '빌려' 옵니다. 이 예시에서 객체 `a`는 슬라이스 "
" `s`보다 더 오래 살아 있어야만 합니다.\n"
" \n"
"* `a[3]`의 값을 바꿀 수 있냐는 질문은 좋은 질문입니다. 여기에 대한 답은 `a`와"
" `s`를 통해 데이터를 읽을 수는 있지만 수정할 수는 없으며, 이는 메모리 안전을"
" 위해서라는 것입니다. 왜 그런지에 대한 좀더 구체적인 답은 빌림 검사 부분에서"
" 자세히 설명합니다."
#: src/basic-syntax/string-slices.md:1
msgid "# `String` vs `str`"
msgstr "# String과 str"
#: src/basic-syntax/string-slices.md:3
msgid "We can now understand the two string types in Rust:"
msgstr "이제 러스트의 두 가지 문자열 타입에 대해서 이해해 보겠습니다.:"
#: src/basic-syntax/string-slices.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let s1: &str = \"World\";\n"
" println!(\"s1: {s1}\");"
msgstr ""
#: src/basic-syntax/string-slices.md:10
msgid ""
" let mut s2: String = String::from(\"Hello \");\n"
" println!(\"s2: {s2}\");\n"
" s2.push_str(s1);\n"
" println!(\"s2: {s2}\");\n"
" \n"
" let s3: &str = &s2[6..];\n"
" println!(\"s3: {s3}\");\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/string-slices.md:20
msgid "Rust terminology:"
msgstr "러스트 용어:"
#: src/basic-syntax/string-slices.md:22
msgid ""
"* `&str` an immutable reference to a string slice.\n"
"* `String` a mutable string buffer."
msgstr ""
"* `&str`은 문자열 슬라이스에 대한 (불변) 참조입니다.\n"
"* `String`은 문자열을 담을 수 있는 버퍼입니다."
#: src/basic-syntax/string-slices.md:27
msgid ""
"* `&str` introduces a string slice, which is an immutable reference to UTF-8 "
"encoded string data \n"
" stored in a block of memory. String literals (`”Hello”`), are stored in "
"the program’s binary."
msgstr ""
"* `&str`은 문자열 슬라이스의 불변 참조입니다."
" 러스트에서 문자열은 UTF-8로 인코딩된 데이터를 의미합니다.\n"
" 문자열 리터럴(`”Hello”`)은 프로그램 바이너리에 저장됩니다. "
#: src/basic-syntax/string-slices.md:30
msgid ""
"* Rust’s `String` type is a wrapper around a vector of bytes. As with a "
"`Vec<T>`, it is owned.\n"
" \n"
"* As with many other types `String::from()` creates a string from a string "
"literal; `String::new()` \n"
" creates a new empty string, to which string data can be added using the "
"`push()` and `push_str()` methods."
msgstr ""
"* 러스트의 `String`타입은 실제로는 문자열을 이루는 바이트에 대한 백터"
"(`Vec<u8>`)입니다. `Vec<T>`가 `T`를 소유하고 있듯이, `String`이 가리키고 있는"
" 문자열은 `String`의 소유입니다.\n"
"* 다른 많은 타입들처럼 `String::from`는 문자열 리터럴로부터 문자열을 생성합니"
"다.\n"
" * `String::new()`는 새로운 빈 문자열을 생성합니다. \n"
" * `push()`와 `push_str()`메서드를 사용하여 문자열 데이터를 추가 할 수 있습"
"니다."
#: src/basic-syntax/string-slices.md:35
msgid ""
"* The `format!()` macro is a convenient way to generate an owned string from "
"dynamic values. It \n"
" accepts the same format specification as `println!()`.\n"
" \n"
"* You can borrow `&str` slices from `String` via `&` and optionally range "
"selection.\n"
" \n"
"* For C++ programmers: think of `&str` as `const char*` from C++, but the "
"one that always points \n"
" to a valid string in memory. Rust `String` is a rough equivalent of `std::"
"string` from C++ \n"
" (main difference: it can only contain UTF-8 encoded bytes and will never "
"use a small-string optimization).\n"
" \n"
"</details>"
msgstr ""
"* `format!()` 매크로는 변수의 값을 문자열로 변환하는 편리한 방법입니다.\n"
" 이 매크로는 `println!()` 매크로와 동일한 포맷팅 형식을 지원합니다.\n"
"* `&`와 범위 연산자를 이용하여 `String`에서 `&str`슬라이스를 빌려올 수 있습니다.\n"
"* 당신이 C++ 프로그래머 라면: `&str`는 C++의 `const char*`와 유사하지만 항상"
" 유효한 문자열을 가리킨다는 점이 다릅니다. 러스트의 `String`은 C++의 `std::string` 과 "
"대략 거의 동일합니다.\n"
" (주요 차이점: 러스트의 `String`은 UTF-8 인코딩 바이트만 포함할 수 있으며 작은 문자열 최적화"
"(small-string optimization)는 사용하지 않습니다.\n"
" \n"
"</details>"
#: src/basic-syntax/functions.md:1
msgid "# Functions"
msgstr "# 함수"
#: src/basic-syntax/functions.md:3
msgid ""
"A Rust version of the famous [FizzBuzz](https://en.wikipedia.org/wiki/"
"Fizz_buzz) interview question:"
msgstr ""
"러스트 버전의 [FizzBuzz](https://en.wikipedia.org/wiki/Fizz_buzz) 함수입니"
"다: \n"
"* _역주_\n"
" * _corner case: 복합 경계 조건. 변수와 환경적인 요소로 인해서 로직에 문제"
"가 있는 경우.(나누기 로직에서 0으로 나누는 경우.)_\n"
" * _edge case: 경계조건. 매개변수 값이 극단적인 최대/최소값 (로직 유효범"
"위 끝) 이상인 경우._\n"
" * _fizzbuzz: 숫자를 입력받아서 3으로 나뉘면 fizz, 5으로 나뉘면 buss, 둘다 "
"나뉘면 fizzbuzz, 안나뉘면 입력값을 출력하는 테스트로 자주 쓰는 문제입니다._"
#: src/basic-syntax/functions.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" fizzbuzz_to(20); // Defined below, no forward declaration needed\n"
"}"
msgstr ""
"```rust,editable\n"
"fn main() {\n"
" fizzbuzz_to(20); //C/C++ 와 달리 호출부 하단에 정의해도 문제 없습니다.\n"
"}"
#: src/basic-syntax/functions.md:10
msgid ""
"fn is_divisible_by(lhs: u32, rhs: u32) -> bool {\n"
" if rhs == 0 {\n"
" return false; // Corner case, early return\n"
" }\n"
" lhs % rhs == 0 // The last expression in a block is the return "
"value\n"
"}"
msgstr ""
"fn is_divisible_by(lhs: u32, rhs: u32) -> bool {\n"
" if rhs == 0 {\n"
" return false; // Corner case이므로 반환합니다.\n"
" }\n"
" lhs % rhs == 0 // 마지막 표현식은 반환 값입니다.(;없음에 주목)\n"
"}"
#: src/basic-syntax/functions.md:17
msgid ""
"fn fizzbuzz(n: u32) -> () { // No return value means returning the unit "
"type `()`\n"
" match (is_divisible_by(n, 3), is_divisible_by(n, 5)) {\n"
" (true, true) => println!(\"fizzbuzz\"),\n"
" (true, false) => println!(\"fizz\"),\n"
" (false, true) => println!(\"buzz\"),\n"
" (false, false) => println!(\"{n}\"),\n"
" }\n"
"}"
msgstr ""
"fn fizzbuzz(n: u32) -> () { // `()`는 반환값이 없다는 것을 의미합니다. \n"
" match (is_divisible_by(n, 3), is_divisible_by(n, 5)) {\n"
" (true, true) => println!(\"fizzbuzz\"),\n"
" (true, false) => println!(\"fizz\"),\n"
" (false, true) => println!(\"buzz\"),\n"
" (false, false) => println!(\"{n}\"),\n"
" }\n"
"}"
#: src/basic-syntax/functions.md:26
msgid ""
"fn fizzbuzz_to(n: u32) { // `-> ()` is normally omitted\n"
" for i in 1..=n {\n"
" fizzbuzz(i);\n"
" }\n"
"}\n"
"```"
msgstr ""
"fn fizzbuzz_to(n: u32) { // `-> ()` 는 일반적으로 생략합니다.\n"
" for i in 1..=n {\n"
" fizzbuzz(i);\n"
" }\n"
"}\n"
"```"
#: src/basic-syntax/functions.md:35
msgid ""
"* We refer in `main` to a function written below. Neither forward "
"declarations nor headers are necessary. \n"
"* Declaration parameters are followed by a type (the reverse of some "
"programming languages), then a return type.\n"
"* The last expression in a function body (or any block) becomes the return "
"value. Simply omit the `;` at the end of the expression.\n"
"* Some functions have no return value, and return the 'unit type', `()`. The "
"compiler will infer this if the `-> ()` return type is omitted.\n"
"* The range expression in the `for` loop in `fizzbuzz_to()` contains `=n`, "
"which causes it to include the upper bound.\n"
"* The `match` expression in `fizzbuzz()` is doing a lot of work. It is "
"expanded below to show what is happening."
msgstr ""
"* `main` 함수에서 그 다음에 오는 함수들을 사용할 수 있습니다. 상단에 선언이나 헤더 같은건 필요 없"
"습니다.\n"
"* 매개변수를 선언할 때에는 이름을 먼저 쓰고, 타입을 나중에 씁니다. 이름과"
" 타입은 `:` 로 구분합니다. 이는 일부 언어(예를 들어 C)와 반대임에 유의하시기"
" 바랍니다. 마찬가지로, 리턴 타입도 함수의 시작이 아닌 가장 뒷부분에 선언합니다.\n"
"* 함수 본문의 마지막 표현식은 반환 값이 됩니다. 간단히, 식 끝에 있는 `;`를 생"
"략하면 됩니다.\n"
"* 반환값이 없는 함수의 경우, `유닛 타입 ()`을 반환합니다. `-> ()`가 생략된 경"
"우 컴파일러는 이를 추론합니다.* `fizzbuzz_to()`함수 내 `for` 반목문의 rage 표"
"현식 중 `=n`은 해당 범위까지 포함한다는 의미입니다. \n"
"* `fizzbuzz()`함수의 `match` 표현식은 많은 일을 합니다. 무슨 일이 일어나는지 "
"조금 더 이해하기 쉽도록 아래 코드를 확인하시기 바랍니다."
#: src/basic-syntax/functions.md:42
msgid " (Type annotations added for clarity, but they can be elided.)"
msgstr " (명확한 설명을 위해 타입이 명시적으로 선언 되었지만 생략 가능합니다.)"
#: src/basic-syntax/functions.md:44
msgid ""
" ```rust,ignore\n"
" let by_3: bool = is_divisible_by(n, 3);\n"
" let by_5: bool = is_divisible_by(n, 5);\n"
" let by_35: (bool, bool) = (by_3, by_5);\n"
" match by_35 {\n"
" // ...\n"
" ```"
msgstr ""
#: src/basic-syntax/functions.md:52
msgid " "
msgstr ""
#: src/basic-syntax/methods.md:1 src/methods.md:1
msgid "# Methods"
msgstr "# 메서드"
#: src/basic-syntax/methods.md:3
msgid ""
"Rust has methods, they are simply functions that are associated with a "
"particular type. The\n"
"first argument of a method is an instance of the type it is associated with:"
msgstr ""
"러스트의 메서드는 특정 타입과 연결된 함수입니다.\n"
"메서드의 첫번째 인자의 타입이 바로 그 메서드가 연결된 타입입니다."
#: src/basic-syntax/methods.md:6
msgid ""
"```rust,editable\n"
"struct Rectangle {\n"
" width: u32,\n"
" height: u32,\n"
"}"
msgstr ""
#: src/basic-syntax/methods.md:12
msgid ""
"impl Rectangle {\n"
" fn area(&self) -> u32 {\n"
" self.width * self.height\n"
" }"
msgstr ""
#: src/basic-syntax/methods.md:17
msgid ""
" fn inc_width(&mut self, delta: u32) {\n"
" self.width += delta;\n"
" }\n"
"}"
msgstr ""
#: src/basic-syntax/methods.md:22
msgid ""
"fn main() {\n"
" let mut rect = Rectangle { width: 10, height: 5 };\n"
" println!(\"old area: {}\", rect.area());\n"
" rect.inc_width(5);\n"
" println!(\"new area: {}\", rect.area());\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/methods.md:30
msgid ""
"* We will look much more at methods in today's exercise and in tomorrow's "
"class."
msgstr "* 오늘과 내일 강의에서 더 많은 메서드 사용법을 다룰 것입니다."
#: src/basic-syntax/functions-interlude.md:1
msgid "# Function Overloading"
msgstr "# (함수) 오버로딩"
#: src/basic-syntax/functions-interlude.md:3
msgid "Overloading is not supported:"
msgstr "오버로딩은 지원되지 않습니다: "
#: src/basic-syntax/functions-interlude.md:5
msgid ""
"* Each function has a single implementation:\n"
" * Always takes a fixed number of parameters.\n"
" * Always takes a single set of parameter types.\n"
"* Default values are not supported:\n"
" * All call sites have the same number of arguments.\n"
" * Macros are sometimes used as an alternative."
msgstr ""
"* 개별함수는 단일 구현만 갖습니다.\n"
" * 항상 고정된 수의 파라매터만 갖습니다.\n"
" * 파라매터들의 타입은 항상 고정되어 있습니다.\n"
"* 파라매터의 기본 값은 지원되지 않습니다.\n"
" * 모든 호출부에서는 동일한 수의 인자를 설정해야합니다. \n"
" * 이런 사항들이 제약이 될 경우, 대안으로 매크로를 사용하기도 합니다. "
#: src/basic-syntax/functions-interlude.md:12
msgid "However, function parameters can be generic:"
msgstr "하지만, 함수의 매개변수는 제너릭을 적용할 수 있습니다:"
#: src/basic-syntax/functions-interlude.md:14
msgid ""
"```rust,editable\n"
"fn pick_one<T>(a: T, b: T) -> T {\n"
" if std::process::id() % 2 == 0 { a } else { b }\n"
"}"
msgstr ""
#: src/basic-syntax/functions-interlude.md:19
msgid ""
"fn main() {\n"
" println!(\"coin toss: {}\", pick_one(\"heads\", \"tails\"));\n"
" println!(\"cash prize: {}\", pick_one(500, 1000));\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/functions-interlude.md:27
msgid ""
"* When using generics, the standard library's `Into<T>` can provide a kind "
"of limited\n"
" polymorphism on argument types. We will see more details in a later "
"section."
msgstr ""
"* 제너릭을 사용할 때 표준 라이브러리의 `Into<T>`은 타입에 대한 다형성을 제공"
"할 수 있습니다. 나중에 자세히 설명하겠습니다."
#: src/basic-syntax/functions-interlude.md:30
msgid "</defails>"
msgstr ""
#: src/exercises/day-1/morning.md:1
msgid "# Day 1: Morning Exercises"
msgstr "# 1일차 오전 연습문제"
#: src/exercises/day-1/morning.md:3
msgid "In these exercises, we will explore two parts of Rust:"
msgstr "이번 연습문제는 러스트의 두 부분을 알아볼 것입니다:"
#: src/exercises/day-1/morning.md:5
msgid "* Implicit conversions between types."
msgstr "* 타입의 묵시적 변환 "
#: src/exercises/day-1/morning.md:7
msgid "* Arrays and `for` loops."
msgstr "* 배열과 `for` 반복문"
#: src/exercises/day-1/morning.md:11
msgid "A few things to consider while solving the exercises:"
msgstr "연습문제를 해결하는데 고려해야 할 사항들: "
#: src/exercises/day-1/morning.md:13
msgid ""
"* Use a local Rust installation, if possible. This way you can get\n"
" auto-completion in your editor. See the page about [Using Cargo] for "
"details\n"
" on installing Rust."
msgstr ""
"* 가능하다면 러스트가 설치된 로컬 환경에서 진행하세요. 그러는 편이 "
"텍스트 에디터의 자동완성 기능의 도움을 받을 수 있어서 좋습니다. "
"[카고 사용하기][Using Cargo] 을 참조하시기 바랍니다."
#: src/exercises/day-1/morning.md:17
msgid "* Alternatively, use the Rust Playground."
msgstr "* 혹은 러스트 플레이그라운드를 이용할 수 있습니다. "
#: src/exercises/day-1/morning.md:19
msgid ""
"The code snippets are not editable on purpose: the inline code snippets "
"lose\n"
"their state if you navigate away from the page."
msgstr ""
"페이지 밖으로 이동할 경우 작성한 내용이 소실되기 때문에 제공되는 코드 스니펫"
"은 의도적으로 편집할 수 없습니다. "
#: src/exercises/day-1/morning.md:22 src/exercises/day-1/afternoon.md:11
#: src/exercises/day-2/morning.md:11 src/exercises/day-2/afternoon.md:7
#: src/exercises/day-3/morning.md:7 src/exercises/day-4/morning.md:12
msgid ""
"After looking at the exercises, you can look at the [solutions] provided."
msgstr "연습문제를 살펴 본 후, 제공된 [solutions]을 살펴볼 수 있습니다."
#: src/exercises/day-1/morning.md:24 src/exercises/day-2/morning.md:13
#: src/exercises/day-3/morning.md:9 src/exercises/day-4/morning.md:14
msgid "[solutions]: solutions-morning.md"
msgstr ""
#: src/exercises/day-1/morning.md:26
msgid "[Using Cargo]: ../../cargo.md"
msgstr ""
#: src/exercises/day-1/implicit-conversions.md:1
msgid "# Implicit Conversions"
msgstr "# 묵시적 형변환"
#: src/exercises/day-1/implicit-conversions.md:3
msgid ""
"Rust will not automatically apply _implicit conversions_ between types "
"([unlike\n"
"C++][3]). You can see this in a program like this:"
msgstr ""
"러스트는 [C++ 와 다르게][3] 타입 간 _묵시적 변환_을 자동으로 적용하지 않습니"
"다.\n"
"아래 예시를 확인해 보세요:"
#: src/exercises/day-1/implicit-conversions.md:6
msgid ""
"```rust,editable,compile_fail\n"
"fn multiply(x: i16, y: i16) -> i16 {\n"
" x * y\n"
"}"
msgstr ""
#: src/exercises/day-1/implicit-conversions.md:11
msgid ""
"fn main() {\n"
" let x: i8 = 15;\n"
" let y: i16 = 1000;"
msgstr ""
#: src/exercises/day-1/implicit-conversions.md:15
msgid ""
" println!(\"{x} * {y} = {}\", multiply(x, y));\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-1/implicit-conversions.md:19
msgid ""
"The Rust integer types all implement the [`From<T>`][1] and [`Into<T>`][2]\n"
"traits to let us convert between them. The `From<T>` trait has a single "
"`from()`\n"
"method and similarly, the `Into<T>` trait has a single `into()` method.\n"
"Implementing these traits is how a type expresses that it can be converted "
"into\n"
"another type."
msgstr ""
"러스트의 정수형 타입은 모두 [`From<T>`][1] 와 [`Into<T>`][2] 트레이트를 구현"
"하고 있으며, 이를 통해 타입 변환이 이루어 집니다.\n"
"`From<T>` 트레이트는 `from()` 메서드를 가지고 있고, `Into<T>`트레이트"
"는 `into()` 메서드를 가지고 있습니다.\n"
"러스트에서는 `From`과 `Into` 트레이트를 구현함으로써, 타입 간 변환이 "
"가능하다는 것을 표현합니다."
#: src/exercises/day-1/implicit-conversions.md:25
msgid ""
"The standard library has an implementation of `From<i8> for i16`, which "
"means\n"
"that we can convert a variable `x` of type `i8` to an `i16` by calling \n"
"`i16::from(x)`. Or, simpler, with `x.into()`, because `From<i8> for i16`\n"
"implementation automatically create an implementation of `Into<i16> for i8`."
msgstr ""
"표준 라이브러리에는 `From<i8> for i16`가 구현되어 있는데 이것은 `i8` "
"타입의 변수 `x`를 `i16::from(x)`를 호출하여 `i16`타입으로 변환할 수 있다는 "
"의미입니다.\n"
"혹은 더 간단하게 `x.into()`를 사용할 수도 있습니다. 이것이 가능한 이유는 "
"`From<i8> for i16` 구현을 가지고 있으면 `Into<i16> for i8` 구현이 자동으로 "
"생성되기 때문입니다."
#: src/exercises/day-1/implicit-conversions.md:30
msgid ""
"The same applies for your own `From` implementations for your own types, so "
"it is\n"
"sufficient to only implement `From` to get a respective `Into` "
"implementation automatically."
msgstr ""
"이는 사용자 정의 타입에도 동일하게 적용되는 규칙입니다. 따라서 "
"`From`만을 구현해도 `Into`까지 자동으로 구현이 됩니다."
#: src/exercises/day-1/implicit-conversions.md:33
msgid "1. Execute the above program and look at the compiler error."
msgstr "1. 위 예제코드를 실행하고 어떤 컴파일 에러가 발생하는지 확인해 보세요."
#: src/exercises/day-1/implicit-conversions.md:35
msgid "2. Update the code above to use `into()` to do the conversion."
msgstr "2. `into()`를 사용하여 코드를 수정하세요."
#: src/exercises/day-1/implicit-conversions.md:37
msgid ""
"3. Change the types of `x` and `y` to other things (such as `f32`, `bool`,\n"
" `i128`) to see which types you can convert to which other types. Try\n"
" converting small types to big types and the other way around. Check the\n"
" [standard library documentation][1] to see if `From<T>` is implemented "
"for\n"
" the pairs you check."
msgstr ""
"3. `x`와 `y`를 `f32'이나 'bool', 'i128' 등으로 바꿔서 해당 타입들로 변환이 되"
"는지 확인해보세요 \n"
" - 작은 사이즈 타입에서 큰 사이즈로 변경해보시고 그 반대로도 해보세요 \n"
" - [표준 라이브러리 문서][1]에서 시도해 본 케이스가 구현되어 있는지 확인해 "
"보세요."
#: src/exercises/day-1/implicit-conversions.md:43
msgid ""
"[1]: https://doc.rust-lang.org/std/convert/trait.From.html\n"
"[2]: https://doc.rust-lang.org/std/convert/trait.Into.html\n"
"[3]: https://en.cppreference.com/w/cpp/language/implicit_conversion"
msgstr ""
#: src/exercises/day-1/for-loops.md:1
msgid "# Arrays and `for` Loops"
msgstr "# 배열과 `for`반복문"
#: src/exercises/day-1/for-loops.md:3
msgid "We saw that an array can be declared like this:"
msgstr "배열을 아래와 같이 선언 할 수 있음을 배웠습니다:"
#: src/exercises/day-1/for-loops.md:5
msgid ""
"```rust\n"
"let array = [10, 20, 30];\n"
"```"
msgstr ""
#: src/exercises/day-1/for-loops.md:9
msgid ""
"You can print such an array by asking for its debug representation with `{:?}"
"`:"
msgstr "배열을 출력하려면 `{:?}`를 씁니다."
#: src/exercises/day-1/for-loops.md:11
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let array = [10, 20, 30];\n"
" println!(\"array: {array:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-1/for-loops.md:18
msgid ""
"Rust lets you iterate over things like arrays and ranges using the `for`\n"
"keyword:"
msgstr "러스트에서는 `for` 키워드를 사용해 배열이나 범위를 반복할 수 있습니다:"
#: src/exercises/day-1/for-loops.md:21
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let array = [10, 20, 30];\n"
" print!(\"Iterating over array:\");\n"
" for n in array {\n"
" print!(\" {n}\");\n"
" }\n"
" println!();"
msgstr ""
#: src/exercises/day-1/for-loops.md:30
msgid ""
" print!(\"Iterating over range:\");\n"
" for i in 0..3 {\n"
" print!(\" {}\", array[i]);\n"
" }\n"
" println!();\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-1/for-loops.md:38
msgid ""
"Use the above to write a function `pretty_print` which pretty-print a matrix "
"and\n"
"a function `transpose` which will transpose a matrix (turn rows into "
"columns):"
msgstr ""
"위 코드를 이용해서, 행렬을 예쁘게 출력하는 `pretty_print`함수와, 행렬을 전치(행과 "
"열을 서로 바꾸는)시키는 `transpose`함수를 작성해 보시기 바랍니다."
#: src/exercises/day-1/for-loops.md:41
msgid ""
"```bob\n"
" ⎛⎡1 2 3⎤⎞ ⎡1 4 7⎤\n"
"\"transpose\"⎜⎢4 5 6⎥⎟ \"==\"⎢2 5 8⎥\n"
" ⎝⎣7 8 9⎦⎠ ⎣3 6 9⎦\n"
"```"
msgstr ""
#: src/exercises/day-1/for-loops.md:47
msgid "Hard-code both functions to operate on 3 × 3 matrices."
msgstr "두 함수 모두 행렬의 크기는 3 x 3 으로 하드코딩 합니다."
#: src/exercises/day-1/for-loops.md:49
msgid ""
"Copy the code below to <https://play.rust-lang.org/> and implement the\n"
"functions:"
msgstr ""
"아래 코드를 <https://play.rust-lang.org/>에 복사해서 구현하시면 됩니다."
#: src/exercises/day-1/for-loops.md:52 src/exercises/day-1/book-library.md:20
#: src/exercises/day-2/health-statistics.md:13
msgid ""
"```rust,should_panic\n"
"// TODO: remove this when you're done with your implementation.\n"
"#![allow(unused_variables, dead_code)]"
msgstr ""
"```rust,should_panic\n"
"// TODO: 구현이 완료되면 아래 줄은 삭제합니다.\n"
"#![allow(unused_variables, dead_code)]"
#: src/exercises/day-1/for-loops.md:56
msgid ""
"fn transpose(matrix: [[i32; 3]; 3]) -> [[i32; 3]; 3] {\n"
" unimplemented!()\n"
"}"
msgstr ""
#: src/exercises/day-1/for-loops.md:60
msgid ""
"fn pretty_print(matrix: &[[i32; 3]; 3]) {\n"
" unimplemented!()\n"
"}"
msgstr ""
#: src/exercises/day-1/for-loops.md:64
msgid ""
"fn main() {\n"
" let matrix = [\n"
" [101, 102, 103], // <-- the comment makes rustfmt add a newline\n"
" [201, 202, 203],\n"
" [301, 302, 303],\n"
" ];"
msgstr ""
#: src/exercises/day-1/for-loops.md:71
#: src/exercises/day-1/solutions-morning.md:70
msgid ""
" println!(\"matrix:\");\n"
" pretty_print(&matrix);"
msgstr ""
#: src/exercises/day-1/for-loops.md:74
msgid ""
" let transposed = transpose(matrix);\n"
" println!(\"transposed:\");\n"
" pretty_print(&transposed);\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-1/for-loops.md:80
msgid "## Bonus Question"
msgstr "## 보너스 문제"
#: src/exercises/day-1/for-loops.md:82
msgid ""
"Could you use `&[i32]` slices instead of hard-coded 3 × 3 matrices for your\n"
"argument and return types? Something like `&[&[i32]]` for a two-dimensional\n"
"slice-of-slices. Why or why not?"
msgstr ""
"`&[i32]`슬라이스를 잘 이용하면 행렬 크기를 3 x 3으로 하드코딩 하지 않을 수 있을까요?\n"
"예컨데 `&[&[i32]]`는 2차원 슬라이스의 슬라이스 입니다. 가능하다면/"
"하지 않다면 왜 그런가요?"
#: src/exercises/day-1/for-loops.md:87
msgid ""
"See the [`ndarray` crate](https://docs.rs/ndarray/) for a production "
"quality\n"
"implementation."
msgstr ""
"상용 품질의 구현에 대해서는 [`ndarray` 크레이트](https://docs.rs/"
"ndarray/)를 참조하시기 바랍니다."
#: src/exercises/day-1/for-loops.md:92
msgid ""
"The solution and the answer to the bonus section are available in the \n"
"[Solution](solutions-morning.md#arrays-and-for-loops) section."
msgstr ""
"보너스 문제에 대한 답변 역시 [Solution](solutions-morning.md#arrays-and-for-"
"loops)에서 확인할 수 있습니다."
#: src/basic-syntax/variables.md:1
msgid "# Variables"
msgstr "# 변수"
#: src/basic-syntax/variables.md:3
msgid ""
"Rust provides type safety via static typing. Variable bindings are immutable "
"by\n"
"default:"
msgstr ""
"러스트는 정적 타이핑을 통해 타입 안전성을 제공합니다. \n"
"변수는 기본적으로 불변(immutable)합니다.: "
#: src/basic-syntax/variables.md:6
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let x: i32 = 10;\n"
" println!(\"x: {x}\");\n"
" // x = 20;\n"
" // println!(\"x: {x}\");\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/variables.md:17
msgid ""
"* Due to type inference the `i32` is optional. We will gradually show the "
"types less and less as the type progresses.\n"
"* Note that since `println!` is a macro, `x` is not moved, even using the "
"function like syntax of `println!(\"x: {}\", x)`"
msgstr ""
"* 타입 추론에 덕분에 `i32`는 생략 가능합니다. 강의가 진행될 수록 생략 가능"
"한 부분은 점점 생략할 것입니다.\n"
"* `println!(\"x: {}\", x)`는 함수 호출 처럼 보이지만 실은 매크로 호출입니다."
"때문에 `x`는 이동되지 않습니다."
#: src/basic-syntax/type-inference.md:1
msgid "# Type Inference"
msgstr "# 타입 추론"
#: src/basic-syntax/type-inference.md:3
msgid "Rust will look at how the variable is _used_ to determine the type:"
msgstr "러스트는 변수가 어떻게 사용되는지를 보고 그 변수의 타입을 추론합니다. "
#: src/basic-syntax/type-inference.md:5
msgid ""
"```rust,editable\n"
"fn takes_u32(x: u32) {\n"
" println!(\"u32: {x}\");\n"
"}"
msgstr ""
#: src/basic-syntax/type-inference.md:10
msgid ""
"fn takes_i8(y: i8) {\n"
" println!(\"i8: {y}\");\n"
"}"
msgstr ""
#: src/basic-syntax/type-inference.md:14
msgid ""
"fn main() {\n"
" let x = 10;\n"
" let y = 20;"
msgstr ""
#: src/basic-syntax/type-inference.md:18
msgid ""
" takes_u32(x);\n"
" takes_i8(y);\n"
" // takes_u32(y);\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/type-inference.md:26
msgid ""
"This slide demonstrates how the Rust compiler infers types based on "
"constraints given by variable declarations and usages.\n"
" \n"
"It is very important to emphasize that variables declared like this are not "
"of some sort of dynamic \"any type\" that can\n"
"hold any data. The machine code generated by such declaration is identical "
"to the explicit declaration of a type.\n"
"The compiler does the job for us and helps us to write a more concise code."
msgstr ""
"이 슬라이드는, 러스트 컴파일러가 변수가 어떻게 선언되어 있고, 어떻게 사용되는지를 "
"제약 조건으로 삼아서 변수의 타입을 추론하는 모습을 보여줍니다.\n"
" \n"
"여기서 중요한 것은, 이렇게 명시적인 타입을 생략하고 선언되었다고 해서 "
"\"어떤 타입\"이라도 다 담을 수 있는 타입이 되는 것은 아니라는 점입니다.\n"
"명시적인 타입 선언이 있던 없던, 컴파일러가 생성한 머신코드는 동일합니다. "
"컴파일러는 단지 타입 선언을 생략할 수 있도록 해서 프로그래머가 더 간결한 코드를 쓸 수 있도록 "
"도와줄 뿐입니다."
#: src/basic-syntax/type-inference.md:32
msgid ""
"The following code tells the compiler to copy into a certain generic "
"container without the code ever explicitly specifying the contained type, "
"using `_` as a placeholder:"
msgstr ""
"아래 코드는, 제너릭 컨테이너를 쓸 때 컨테이터 안에 포함된 데이터의 타입을 "
"명시적으로 쓰지 않고 `_`로 대체하여도 된다는 것을 보여줍니다."
#: src/basic-syntax/type-inference.md:34
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let mut v = Vec::new();\n"
" v.push((10, false));\n"
" v.push((20, true));\n"
" println!(\"v: {v:?}\");"
msgstr ""
#: src/basic-syntax/type-inference.md:41
msgid ""
" let vv = v.iter().collect::<std::collections::HashSet<_>>();\n"
" println!(\"vv: {vv:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/type-inference.md:46
msgid ""
"[`collect`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator."
"html#method.collect) relies on `FromIterator`, which [`HashSet`](https://doc."
"rust-lang.org/std/iter/trait.FromIterator.html) implements."
msgstr ""
"[`collect`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator."
"html#method.collect)는 [`HashSet`](https://doc.rust-lang.org/std/iter/trait."
"FromIterator.html)을 구현한 `FromIterator`에 의존합니다."
#: src/basic-syntax/static-and-const.md:1
msgid "# Static and Constant Variables"
msgstr "# 정적변수(static)과 상수(const)"
#: src/basic-syntax/static-and-const.md:3
msgid "Global state is managed with static and constant variables."
msgstr "프로그램의 글로벌 상태는 결국 정적 변수와 상수로 표현됩니다."
#: src/basic-syntax/static-and-const.md:5
msgid "## `const`"
msgstr "## 상수(`const`)"
#: src/basic-syntax/static-and-const.md:7
msgid "You can declare compile-time constants:"
msgstr "컴파일 시 값이 정해지는 상수를 선언할 수 있습니다."
#: src/basic-syntax/static-and-const.md:9
msgid ""
"```rust,editable\n"
"const DIGEST_SIZE: usize = 3;\n"
"const ZERO: Option<u8> = Some(42);"
msgstr ""
#: src/basic-syntax/static-and-const.md:13
msgid ""
"fn compute_digest(text: &str) -> [u8; DIGEST_SIZE] {\n"
" let mut digest = [ZERO.unwrap_or(0); DIGEST_SIZE];\n"
" for (idx, &b) in text.as_bytes().iter().enumerate() {\n"
" digest[idx % DIGEST_SIZE] = digest[idx % DIGEST_SIZE]."
"wrapping_add(b);\n"
" }\n"
" digest\n"
"}"
msgstr ""
#: src/basic-syntax/static-and-const.md:21
msgid ""
"fn main() {\n"
" let digest = compute_digest(\"Hello\");\n"
" println!(\"Digest: {digest:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/static-and-const.md:27
msgid "According the the [Rust RFC Book][1] these are inlined upon use."
msgstr ""
"[Rust RFC Book][1]에 따르면 상수는, 그 상수가 사용되는 곳에 인라인 됩니다."
#: src/basic-syntax/static-and-const.md:29
msgid "## `static`"
msgstr "## 정적변수(`static`)"
#: src/basic-syntax/static-and-const.md:31
msgid "You can also declare static variables:"
msgstr "마찬가지로 정적 변수도 선언할 수 있습니다."
#: src/basic-syntax/static-and-const.md:33
msgid ""
"```rust,editable\n"
"static BANNER: &str = \"Welcome to RustOS 3.14\";"
msgstr ""
#: src/basic-syntax/static-and-const.md:36
msgid ""
"fn main() {\n"
" println!(\"{BANNER}\");\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/static-and-const.md:41
msgid ""
"As noted in the [Rust RFC Book][1], these are not inlined upon use and have "
"an actual associated memory location. This is useful for unsafe and "
"embedded code, and the variable lives through the entirety of the program "
"execution."
msgstr ""
"[Rust RFC Book][1]에서 언급한 바와 같이, 정적 변수는 별도의 메모리 공간을 가지며, "
"인라인 되지 않습니다. 정적 변수는 안전하지 않은(unsafe) 러스트와 임베디드 시스템용 "
"코드에서 유용합니다. 이들의 수명은 프로그램이 수행되는 전체 시간과 동일합니다."
#: src/basic-syntax/static-and-const.md:44
msgid ""
"We will look at mutating static data in the [chapter on Unsafe Rust](../"
"unsafe.md)."
msgstr ""
"가변 정적 데이터에 대해서는 안전하지 않은 [러스트 파트](../unsafe.md)에서 살"
"펴봅니다."
#: src/basic-syntax/static-and-const.md:48
msgid ""
"* Mention that `const` behaves semantically similar to C++'s `constexpr`.\n"
"* `static`, on the other hand, is much more similar to a `const` or mutable "
"global variable in C++.\n"
"* It isn't super common that one would need a runtime evaluated constant, "
"but it is helpful and safer than using a static."
msgstr ""
"* `const`는 C++의 `constexpr`과 매우 비슷합니다.\n"
"* 반면에 `static`은 C++의 `const`나 가변 정적 변수와 훨씬 더 유사합니다.\n"
"* 프로그램 수행시 그 값이 정해지는 상수가 필요한 경우는 드뭅니다. 그러나 "
"그렇다고 해도, 정적 변수를 사용하는 것 보다는 더 유용하고 안전합니다."
#: src/basic-syntax/static-and-const.md:54
msgid "[1]: https://rust-lang.github.io/rfcs/0246-const-vs-static.html"
msgstr ""
#: src/basic-syntax/scopes-shadowing.md:1
msgid "# Scopes and Shadowing"
msgstr "# 범위(Scopes)와 쉐도잉(Shadowing)"
#: src/basic-syntax/scopes-shadowing.md:3
msgid ""
"You can shadow variables, both those from outer scopes and variables from "
"the\n"
"same scope:"
msgstr "현재 범위에 있는 변수와, 바깥 범위에 있는 변수 모두 가릴(쉐도잉)수 있습니다:"
#: src/basic-syntax/scopes-shadowing.md:6
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let a = 10;\n"
" println!(\"before: {a}\");"
msgstr ""
#: src/basic-syntax/scopes-shadowing.md:11
msgid ""
" {\n"
" let a = \"hello\";\n"
" println!(\"inner scope: {a}\");"
msgstr ""
#: src/basic-syntax/scopes-shadowing.md:15
msgid ""
" let a = true;\n"
" println!(\"shadowed in inner scope: {a}\");\n"
" }"
msgstr ""
#: src/basic-syntax/scopes-shadowing.md:19
msgid ""
" println!(\"after: {a}\");\n"
"}\n"
"```"
msgstr ""
#: src/basic-syntax/scopes-shadowing.md:25
msgid ""
"* Definition: Shadowing is different from mutation, because after shadowing "
"both variable's memory locations exist at the same time. Both are available "
"under the same name, depending where you use it in the code. \n"
"* A shadowing variable can have a different type. \n"
"* Shadowing looks obscure at first, but is convenient for holding on to "
"values after `.unwrap()`.\n"
"* The following code demonstrates why the compiler can't simply reuse memory "
"locations when shadowing an immutable variable in a scope, even if the type "
"does not change."
msgstr ""
"* 쉐도잉은 기존 변수에 새로운 값을 할당하는 것이 아닙니다. 쉐도잉을 하면 새로운 "
"변수기 생기며, 이전 변수와 새 변수는 메모리의 서로 다룬 위치에 존재합니다. "
"그 두 변수는 단지 이름이 같은 뿐이며, 코드 중 어디에서 그 이름이 사용되었느냐에 "
"따라 어떤 변수를 지칭하는 지가 결정됩니다.\n"
"* 쉐도잉 시 타입을 바꿀 수 있습니다.\n"
"* 처음에 쉐도잉을 보면 코드를 더 모호하게 만든다고 생각할 수 도 있습니다. 그러나 "
"실제로 쉐도잉을 이용하면, 어떤 변수에서 `.unwrap()` 된 값을 새로운 변수에 담을 경우 "
"새로운 이름을 지을 필요 없이 기존 이름을 유지할 수 있어서 편리합니다.\n"
"* 아래 코드는 불변 변수를 쉐도잉할 때 타입이 동일하"
"더라도 새 변수가 원래 변수의 메모리 위치를 재사용 할 수 없는지 그 이유를 보여줍니다."
#: src/basic-syntax/scopes-shadowing.md:30
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let a = 1;\n"
" let b = &a;\n"
" let a = a + 1;\n"
" println!(\"{a} {b}\");\n"
"}\n"
"```"
msgstr ""
#: src/memory-management.md:1
msgid "# Memory Management"
msgstr "# 메모리 관리"
#: src/memory-management.md:3
msgid "Traditionally, languages have fallen into two broad categories:"
msgstr "전통적으로, 두 종류의 프로그래밍 언어가 있습니다:"
#: src/memory-management.md:5
msgid ""
"* Full control via manual memory management: C, C++, Pascal, ...\n"
"* Full safety via automatic memory management at runtime: Java, Python, Go, "
"Haskell, ..."
msgstr ""
"* 메모리 관리가 프로그래머의 완전한 통제하에 있지만 수동(_역주_: 그래서 안전하지 않을 수 있는)이 언어: C, C++, Pascal, ...\n"
"* 메모리 관리가 런타임에 의해 되므로 안전하지만 자동(_역주_: 그래서 프로그래머가 개입할 여지가 적거나 없는)인 언어: Java, Python, Go, "
"Haskell, ... "
#: src/memory-management.md:8
msgid "Rust offers a new mix:"
msgstr "러스트는 이 둘을 혼합한 새로운 형태의 메모리 관리 기법을 제공합니다:"
#: src/memory-management.md:10
msgid ""
"> Full control *and* safety via compile time enforcement of correct memory\n"
"> management."
msgstr "> 완전한 통제와 안전"
#: src/memory-management.md:13
msgid "It does this with an explicit ownership concept."
msgstr "이를 가능하게 하는 러스트의 컨셉은 명시적인 소유권입니다."
#: src/memory-management.md:15
msgid "First, let's refresh how memory management works."
msgstr "우선 메모리 관리가 이뤄지는 방식을 다시 살펴 보겠습니다."
#: src/memory-management/stack-vs-heap.md:1
msgid "# The Stack vs The Heap"
msgstr "# 스택(Stack)과 힙(Heap)"
#: src/memory-management/stack-vs-heap.md:3
msgid ""
"* Stack: Continuous area of memory for local variables.\n"
" * Values have fixed sizes known at compile time.\n"
" * Extremely fast: just move a stack pointer.\n"
" * Easy to manage: follows function calls.\n"
" * Great memory locality."
msgstr ""
"* 스택: 지역 변수를 위한 연속적인 메모리 영역\n"
" * 여기 저장되는 값은 컴파일 시 결정되는 고정 크기를 갖습니다. \n"
" * 매우 빠름: 메모리 할당/반환이 단지 스택 포인터의 이동만으로 구현됩니다.\n"
" * 관리가 쉬움: 함수가 호출되면 할당되고, 리턴하면 반환됩니다.\n"
" * 스택에 있는 값들은 매우 높은 메모리 인접성을 가집니다(_역주_: 그래서 캐시를 효과적으로 활용할 수 있습니다)"
#: src/memory-management/stack-vs-heap.md:9
msgid ""
"* Heap: Storage of values outside of function calls.\n"
" * Values have dynamic sizes determined at runtime.\n"
" * Slightly slower than the stack: some book-keeping needed.\n"
" * No guarantee of memory locality."
msgstr ""
"* 힙: 함수 호출/리턴과 상관 없이 유지되는 값이 저장되는 곳\n"
" * 여기 저장되는 값은 프로그램 수행시 그 크기가 결정됩니다.\n"
" * 스택 보다는 느림: 메모리 할당/반환시 해야 할 일이 좀 더 있습니다.\n"
" * 메모리 인접성을 보장하지 않습니다."
#: src/memory-management/stack.md:1
msgid "# Stack Memory"
msgstr "# 스택 메모리"
#: src/memory-management/stack.md:3
msgid ""
"Creating a `String` puts fixed-sized data on the stack and dynamically "
"sized\n"
"data on the heap:"
msgstr ""
"`String` 타입은 고정 크기 데이터(_역주_: 문자열의 길이, 문자열이 저장된 버퍼의 주소 등)는 "
"스택에 저장하고, 가변 크기 데이터(_역주_: 문자열 버퍼)는 힙에 저장합니다:"
#: src/memory-management/stack.md:6
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let s1 = String::from(\"Hello\");\n"
"}\n"
"```"
msgstr ""
#: src/memory-management/stack.md:12
msgid ""
"```bob\n"
" Stack Heap\n"
".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - -.\n"
": : : :\n"
": s1 : : :\n"
": +-----------+-------+ : : +----+----+----+----+----+ :\n"
": | ptr | o---+---+-----+-->| H | e | l | l | o | :\n"
": | len | 5 | : : +----+----+----+----+----+ :\n"
": | capacity | 5 | : : :\n"
": +-----------+-------+ : : :\n"
": : `- - - - - - - - - - - - - - - -'\n"
"`- - - - - - - - - - - - - -'\n"
"```"
msgstr ""
#: src/memory-management/stack.md:28
msgid ""
"* Mention that a `String` is backed by a `Vec`, so it has a capacity and "
"length and can grow if mutable via reallocation on the heap."
msgstr ""
"* 문자열(`String`)은 실제로는 `Vec`입니다. 크기(capacity)와 현재 길이(length) "
"정보를 가지며, 더 큰 크기가 필요할 경우 힙에서 재 할당을 합니다."
#: src/memory-management/stack.md:30
msgid ""
"* If students ask about it, you can mention that the underlying memory is "
"heap allocated using the [System Allocator] and custom allocators can be "
"implemented using the [Allocator API]"
msgstr ""
" 힙은 기본적으로 [System Allocator]를 통해 할당됩니다. 그리고 [Allocator API]를 이용해서 "
"커스텀 메모리 할당자를 만들 수도 있습니다."
#: src/memory-management/stack.md:34
msgid ""
"[System Allocator]: https://doc.rust-lang.org/std/alloc/struct.System.html\n"
"[Allocator API]: https://doc.rust-lang.org/std/alloc/index.html"
msgstr ""
#: src/memory-management/manual.md:1
msgid "# Manual Memory Management"
msgstr "# 수동 메모리 관리"
#: src/memory-management/manual.md:3
msgid "You allocate and deallocate heap memory yourself."
msgstr "사용자가 직접 메모리를 할당, 해제 합니다."
#: src/memory-management/manual.md:5
msgid ""
"If not done with care, this can lead to crashes, bugs, security "
"vulnerabilities, and memory leaks."
msgstr ""
"조심하지 않으면, 충돌(crash), 버그, 보안취약성 및 메모리 누출이 발생할 수 있"
"습니다."
#: src/memory-management/manual.md:7
msgid "## C Example"
msgstr "## C 언어 예제"
#: src/memory-management/manual.md:9
msgid "You must call `free` on every pointer you allocate with `malloc`:"
msgstr "`malloc`으로 할당하는 포인터마다 `free`를 호출해야 합니다: "
#: src/memory-management/manual.md:11
msgid ""
"```c\n"
"void foo(size_t n) {\n"
" int* int_array = (int*)malloc(n * sizeof(int));\n"
" //\n"
" // ... lots of code\n"
" //\n"
" free(int_array);\n"
"}\n"
"```"
msgstr ""
#: src/memory-management/manual.md:21
msgid ""
"Memory is leaked if the function returns early between `malloc` and `free`: "
"the\n"
"pointer is lost and we cannot deallocate the memory."
msgstr ""
"만약`malloc` 과 `free` 사이에서 함수가 일찍 반환되면 메모리 누출이 일어납니"
"다:\n"
" 포인터를 잃어버리게 되어 메모리를 반환할 수 없게 됩니다."
#: src/memory-management/scope-based.md:1
msgid "# Scope-Based Memory Management"
msgstr "# 범위기반 메모리 관리"
#: src/memory-management/scope-based.md:3
msgid ""
"Constructors and destructors let you hook into the lifetime of an object."
msgstr "생성자와 소멸자를 사용하여 객체의 생명주기에 따라 메모리 할당/해제가 "
"일어나도록 할 수 있습니다."
#: src/memory-management/scope-based.md:5
msgid ""
"By wrapping a pointer in an object, you can free memory when the object is\n"
"destroyed. The compiler guarantees that this happens, even if an exception "
"is\n"
"raised."
msgstr ""
"포인터를 객체로 감싸도록 하면, 그 객체가 소멸될 때 그 포인터가 가리키는 메모리가 \n"
"해제되도록 할 수 있습니다. 컴파일러는 객체가 소멸될 때 반드시 소멸자가 호출되는 것을 \n"
"보장합니다. 심지어는 예외(exception)가 발생(_역주_: 함수의 리턴이나 스코프의 종료 뿐만이 아니라) "
"하더라도요."
#: src/memory-management/scope-based.md:9
msgid ""
"This is often called _resource acquisition is initialization_ (RAII) and "
"gives\n"
"you smart pointers."
msgstr ""
"이를 종종 RAII (Resource Acquisition Is Initialization)라고 하며, 이런 객체는 "
"일종의 스마트 포인터 역할을 합니다."
#: src/memory-management/scope-based.md:12
msgid "## C++ Example"
msgstr "## C++ 예제"
#: src/memory-management/scope-based.md:14
msgid ""
"```c++\n"
"void say_hello(std::unique_ptr<Person> person) {\n"
" std::cout << \"Hello \" << person->name << std::endl;\n"
"}\n"
"```"
msgstr ""
#: src/memory-management/scope-based.md:20
msgid ""
"* The `std::unique_ptr` object is allocated on the stack, and points to\n"
" memory allocated on the heap.\n"
"* At the end of `say_hello`, the `std::unique_ptr` destructor will run.\n"
"* The destructor frees the `Person` object it points to."
msgstr ""
"* `std::unique_ptr`객체는 스택에 할당되며, 힙에 할당된 메모리를 가리킵니다.\n"
"* `say_hello`함수가 끝나면 `std::unique_ptr`의 소멸자가 실행됩니다.\n"
"* 소멸자는 `Person` 객체가 가리키는 메모리를 해제합니다."
#: src/memory-management/scope-based.md:25
msgid ""
"Special move constructors are used when passing ownership to a function:"
msgstr "이동 생성자는 함수 호출 시 소유권을 전달할때 사용됩니다."
#: src/memory-management/scope-based.md:27
msgid ""
"```c++\n"
"std::unique_ptr<Person> person = find_person(\"Carla\");\n"
"say_hello(std::move(person));\n"
"```"
msgstr ""
#: src/memory-management/garbage-collection.md:1
msgid "# Automatic Memory Management"
msgstr "# 자동 메모리 관리"
#: src/memory-management/garbage-collection.md:3
msgid ""
"An alternative to manual and scope-based memory management is automatic "
"memory\n"
"management:"
msgstr "수동, 스코프기반 메모리 관리의 대안으로 자동 메모리 관리 방식이 있습니다:"
#: src/memory-management/garbage-collection.md:6
msgid ""
"* The programmer never allocates or deallocates memory explicitly.\n"
"* A garbage collector finds unused memory and deallocates it for the "
"programmer."
msgstr ""
"* 개발자는 메모리를 명시적으로 할당/해제 하지 않습니다. \n"
"* 가비지 컬렉터(GC)는 사용되지 않는 메모리를 찾아 해제합니다."
#: src/memory-management/garbage-collection.md:9
msgid "## Java Example"
msgstr "## Jave 예제"
#: src/memory-management/garbage-collection.md:11
msgid "The `person` object is not deallocated after `sayHello` returns:"
msgstr ""
"`person`객체는 `sayHello`함수 반환 후에도 해제되지 않습니다. (_역주_: GC가 나중에 알"
"아서 해제합니다.)"
#: src/memory-management/garbage-collection.md:13
msgid ""
"```java\n"
"void sayHello(Person person) {\n"
" System.out.println(\"Hello \" + person.getName());\n"
"}\n"
"```"
msgstr ""
#: src/memory-management/rust.md:1
msgid "# Memory Management in Rust"
msgstr "# 러스트에서의 메모리 관리"
#: src/memory-management/rust.md:3
msgid "Memory management in Rust is a mix:"
msgstr "러스트의 메모리 관리는 지금까지 설명한 방식들을 혼합해서 사용합니다:"
#: src/memory-management/rust.md:5
msgid ""
"* Safe and correct like Java, but without a garbage collector.\n"
"* Depending on which abstraction (or combination of abstractions) you "
"choose, can be a single unique pointer, reference counted, or atomically "
"reference counted.\n"
"* Scope-based like C++, but the compiler enforces full adherence.\n"
"* A Rust user can choose the right abstraction for the situation, some even "
"have no cost at runtime like C."
msgstr ""
"* 자바처럼 안전하고 정확합니다. 하지만 GC는 없습니다. \n"
"* 다양한 추상화를 제공합니다: 단일 포인터, 참조 카운트, 아토믹(atomic) 참조 카운트\n"
"* C++ 처럼 범위(스코프) 기반입니다. 하지만 컴파일러가 훨씬 더 엄격합니다.\n"
"* 사용자는 상황에 따라 적합한 추상화를 선택할 수 있습니다. 그 중에는 C 언어 처럼 "
"런타임 오버헤드가 없는 것도 있습니다."
#: src/memory-management/rust.md:10
msgid "It achieves this by modeling _ownership_ explicitly."
msgstr "러스트는 _소유권_을 언어 차원에서 명시적으로 모델링 함으로써 이를 이룹니다."
#: src/memory-management/rust.md:14
msgid ""
"* If asked how at this point, you can mention that in Rust this is usually "
"handled by RAII wrapper types such as [Box], [Vec], [Rc], or [Arc]. These "
"encapsulate ownership and memory allocation via various means, and prevent "
"the potential errors in C."
msgstr ""
"* 이 시점에서 그게 어떻게 가능하냐는 질문이 있으면, 러스트에서 이 작업은 "
"일반적으로 [Box], [Vec], [Rc] 또는 [Arc]와 같은 RAII 타입에 의해 처리된다고 "
"답변할 수 있습니다. "
"이들은 다양한 방법을 통해 소유권과 메모리 할당에 대한 구체적인 내용을을 캡슐화하여, "
"C 언어였다면 발생할 수 있었을 다양한 에러를 막습니다."
#: src/memory-management/rust.md:16
msgid ""
"* You may be asked about destructors here, the [Drop] trait is the Rust "
"equivalent."
msgstr ""
"* 소멸자에 대한 질문도 있을 수 있습니다. [Drop] 트레이트가 답입니다."
#: src/memory-management/rust.md:20
msgid ""
"[Box]: https://doc.rust-lang.org/std/boxed/struct.Box.html\n"
"[Vec]: https://doc.rust-lang.org/std/vec/struct.Vec.html\n"
"[Rc]: https://doc.rust-lang.org/std/rc/struct.Rc.html\n"
"[Arc]: https://doc.rust-lang.org/std/sync/struct.Arc.html\n"
"[Drop]: https://doc.rust-lang.org/std/ops/trait.Drop.html"
msgstr ""
#: src/memory-management/comparison.md:1
msgid "# Comparison"
msgstr "# 비교"
#: src/memory-management/comparison.md:3
msgid "Here is a rough comparison of the memory management techniques."
msgstr "메모리 관리 기술의 대략적인 비교입니다."
#: src/memory-management/comparison.md:5
msgid "## Pros of Different Memory Management Techniques"
msgstr "## 메모리 관리 방법 별 장점"
#: src/memory-management/comparison.md:7
msgid ""
"* Manual like C:\n"
" * No runtime overhead.\n"
"* Automatic like Java:\n"
" * Fully automatic.\n"
" * Safe and correct.\n"
"* Scope-based like C++:\n"
" * Partially automatic.\n"
" * No runtime overhead.\n"
"* Compiler-enforced scope-based like Rust:\n"
" * Enforced by compiler.\n"
" * No runtime overhead.\n"
" * Safe and correct."
msgstr ""
"* C와 같은 수동 관리: \n"
" * 런타임 오버헤드가 없음. \n"
"* JAVA와 같은 자동화 관리: \n"
" * 완전한 자동화.\n"
" * 안전하고 정확함.\n"
"* C++ 와 같은 범위 기반 관리: \n"
" * 부분 자동화\n"
" * 런타임 오버헤드가 없음.\n"
"* 러스트와 같은 컴파일러 수행 범위 기반 관리: \n"
" * 컴파일러에 의해 수행됩니다.\n"
" * 런타임 오버헤드가 없습니다. \n"
" * 안전하고 정확합니다. "
#: src/memory-management/comparison.md:20
msgid "## Cons of Different Memory Management Techniques"
msgstr "## 메모리 관리 방법 별 단점"
#: src/memory-management/comparison.md:22
msgid ""
"* Manual like C:\n"
" * Use-after-free.\n"
" * Double-frees.\n"
" * Memory leaks.\n"
"* Automatic like Java:\n"
" * Garbage collection pauses.\n"
" * Destructor delays.\n"
"* Scope-based like C++:\n"
" * Complex, opt-in by programmer.\n"
" * Potential for use-after-free.\n"
"* Compiler-enforced and scope-based like Rust:\n"
" * Some upfront complexity.\n"
" * Can reject valid programs."
msgstr ""
"* C와 같은 수동 관리: \n"
" * 사용 후 해제 문제\n"
" * 이중 해제 문제\n"
" * 메모리 누출 문제\n"
"* JAVA와 같은 자동화 관리: \n"
" * GC동작으로 인한 멈춤\n"
" * 소멸자 지연 (_역주_: 특정 메모리를 더이상 사용하지 않더라도 "
"곧바로 해제 되지 않고 GC가 동작할 때 까지 기다려야 한다는 점)\n"
"* C++ 와 같은 범위 기반 관리: \n"
" * 복잡하며, 개발자의 선택사항임\n"
" * 사용 후 해제 문제 가능성 있음\n"
"* 러스트와 같은 컴파일러가 강제하는 수행 범위 기반 관리: \n"
" * 약간의 초기 복잡성\n"
" * 올바른 프로그램이지만 컴파일러가 거부할 수 있음"
#: src/ownership.md:1
msgid "# Ownership"
msgstr "# 소유권"
#: src/ownership.md:3
msgid ""
"All variable bindings have a _scope_ where they are valid and it is an error "
"to\n"
"use a variable outside its scope:"
msgstr ""
"모든 변수 바인딩은 유효한 _범위(스코프)_를 가지며, 범위 밖에서 변수 사용하면 "
"에러가 발생합니다."
#: src/ownership.md:6
msgid ""
"```rust,editable,compile_fail\n"
"struct Point(i32, i32);"
msgstr ""
#: src/ownership.md:9
msgid ""
"fn main() {\n"
" {\n"
" let p = Point(3, 4);\n"
" println!(\"x: {}\", p.0);\n"
" }\n"
" println!(\"y: {}\", p.1);\n"
"}\n"
"```"
msgstr ""
#: src/ownership.md:18
msgid ""
"* At the end of the scope, the variable is _dropped_ and the data is freed.\n"
"* A destructor can run here to free up resources.\n"
"* We say that the variable _owns_ the value."
msgstr ""
"* 스코프가 종료되면 변수는 _삭제(drop)_되었다고 하며 그 변수의 데이터는 메모리에서 해제됩니다.\n"
"* 스코프가 종료될 때 다른 리소스를 해제하기 위해 소멸자가 호출되도록 할 수 있습니다.\n"
"* 이것을 두고 변수가 값을 _소유_한다고 표현합니다."
#: src/ownership/move-semantics.md:1
msgid "# Move Semantics"
msgstr "# Move 문법(Move Semantics)"
#: src/ownership/move-semantics.md:3
msgid "An assignment will transfer ownership between variables:"
msgstr "(변수의)할당은 소유권을 변수 간에 이동시킵니다:"
#: src/ownership/move-semantics.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let s1: String = String::from(\"Hello!\");\n"
" let s2: String = s1;\n"
" println!(\"s2: {s2}\");\n"
" // println!(\"s1: {s1}\");\n"
"}\n"
"```"
msgstr ""
#: src/ownership/move-semantics.md:14
msgid ""
"* The assignment of `s1` to `s2` transfers ownership.\n"
"* The data was _moved_ from `s1` and `s1` is no longer accessible.\n"
"* When `s1` goes out of scope, nothing happens: it has no ownership.\n"
"* When `s2` goes out of scope, the string data is freed.\n"
"* There is always _exactly_ one variable binding which owns a value."
msgstr ""
"* `s1`을 `s2`에 할당하여 소유권을 이전시킵니다.\n"
"* 데이터는 `s1`에서 _이동_됩니다. 따라서 프로그래머는 `s1`은 더 이상 접근 할 수 없습니다.\n"
"* `s1`의 스코프가 종료되면 아무 일도 없습니다: 왜냐하면 `s1`은 아무런 소유권이 없기 때문입니다.\n"
"* `s2`의 스코프가 종료되면 문자열 데이터는 해제됩니다.\n"
"* 값(데이터)의 소유권을 갖는 변수는 항상 _단_ 하나 입니다."
#: src/ownership/move-semantics.md:22
msgid ""
"* Mention that this is the opposite of the defaults in C++, which copies by "
"value unless you use `std::move` (and the move constructor is defined!)."
msgstr ""
"* 이는 C++과 정반대 임을 설명하세요. C++에서는 복사가 기본이고, `std::move` "
"를 이용해야만 (그리고 이동 생성자가 정의되어 있어야만!) 소유권 이전이 됩니다."
#: src/ownership/move-semantics.md:24
msgid "* In Rust, you clones are explicit (by using `clone`)."
msgstr "* 러스트에서는 복사할때에는 명시적으로 `clone`을 사용합니다."
#: src/ownership/moved-strings-rust.md:1
msgid "# Moved Strings in Rust"
msgstr "# 러스트에서의 문자열 이동(Move)"
#: src/ownership/moved-strings-rust.md:3
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let s1: String = String::from(\"Rust\");\n"
" let s2: String = s1;\n"
"}\n"
"```"
msgstr ""
#: src/ownership/moved-strings-rust.md:10
msgid ""
"* The heap data from `s1` is reused for `s2`.\n"
"* When `s1` goes out of scope, nothing happens (it has been moved from)."
msgstr ""
"* `s1`의 힙 데이터는 `s2`에서 재사용 됩니다. \n"
"* `s1`의 스코프가 종료되면 아무일도 일어나지 않습니다.(이미 이동되었습니다.)"
#: src/ownership/moved-strings-rust.md:13
msgid "Before move to `s2`:"
msgstr "`s2`로 이동 전 메모리:"
#: src/ownership/moved-strings-rust.md:15
msgid ""
"```bob\n"
" Stack Heap\n"
".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - -.\n"
": : : :\n"
": s1 : : :\n"
": +-----------+-------+ : : +----+----+----+----+ :\n"
": | ptr | o---+---+-----+-->| R | u | s | t | :\n"
": | len | 4 | : : +----+----+----+----+ :\n"
": | capacity | 4 | : : :\n"
": +-----------+-------+ : : :\n"
": : `- - - - - - - - - - - - - -'\n"
": :\n"
"`- - - - - - - - - - - - - -'\n"
"```"
msgstr ""
#: src/ownership/moved-strings-rust.md:30
msgid "After move to `s2`:"
msgstr "`s2`로 이동 후 메모리:"
#: src/ownership/moved-strings-rust.md:32
msgid ""
"```bob\n"
" Stack Heap\n"
".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - -.\n"
": : : :\n"
": s1 \"(inaccessible)\" : : :\n"
": +-----------+-------+ : : +----+----+----+----+ :\n"
": | ptr | o---+---+--+--+-->| R | u | s | t | :\n"
": | len | 4 | : | : +----+----+----+----+ :\n"
": | capacity | 4 | : | : :\n"
": +-----------+-------+ : | : :\n"
": : | `- - - - - - - - - - - - - -'\n"
": s2 : |\n"
": +-----------+-------+ : |\n"
": | ptr | o---+---+--'\n"
": | len | 4 | :\n"
": | capacity | 4 | :\n"
": +-----------+-------+ :\n"
": :\n"
"`- - - - - - - - - - - - - -'\n"
"```"
msgstr ""
#: src/ownership/double-free-modern-cpp.md:1
msgid "# Double Frees in Modern C++"
msgstr "# Modern C++에서 이중해제 문제"
#: src/ownership/double-free-modern-cpp.md:3
msgid "Modern C++ solves this differently:"
msgstr "Modern C++은 이 문제를 다르게 해결합니다:"
#: src/ownership/double-free-modern-cpp.md:5
msgid ""
"```c++\n"
"std::string s1 = \"Cpp\";\n"
"std::string s2 = s1; // Duplicate the data in s1.\n"
"```"
msgstr ""
#: src/ownership/double-free-modern-cpp.md:10
msgid ""
"* The heap data from `s1` is duplicated and `s2` gets its own independent "
"copy.\n"
"* When `s1` and `s2` go out of scope, they each free their own memory."
msgstr ""
"* `s1`의 힙 데이터는 복제되고, `s2`는 독립적인 복사본을 얻습니다.\n"
"* `s1` 와 `s2`의 스코프가 종료되면 각각의 메모리가 해제됩니다."
#: src/ownership/double-free-modern-cpp.md:13
msgid "Before copy-assignment:"
msgstr "복사 전"
#: src/ownership/double-free-modern-cpp.md:16
msgid ""
"```bob\n"
" Stack Heap\n"
".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n"
": : : :\n"
": s1 : : :\n"
": +-----------+-------+ : : +----+----+----+ :\n"
": | ptr | o---+---+--+--+-->| C | p | p | :\n"
": | len | 3 | : : +----+----+----+ :\n"
": | capacity | 3 | : : :\n"
": +-----------+-------+ : : :\n"
": : `- - - - - - - - - - - -'\n"
"`- - - - - - - - - - - - - -'\n"
"```"
msgstr ""
#: src/ownership/double-free-modern-cpp.md:30
msgid "After copy-assignment:"
msgstr "복사 후"
#: src/ownership/double-free-modern-cpp.md:32
msgid ""
"```bob\n"
" Stack Heap\n"
".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n"
": : : :\n"
": s1 : : :\n"
": +-----------+-------+ : : +----+----+----+ :\n"
": | ptr | o---+---+--+--+-->| C | p | p | :\n"
": | len | 3 | : : +----+----+----+ :\n"
": | capacity | 3 | : : :\n"
": +-----------+-------+ : : :\n"
": : : :\n"
": s2 : : :\n"
": +-----------+-------+ : : +----+----+----+ :\n"
": | ptr | o---+---+-----+-->| C | p | p | :\n"
": | len | 3 | : : +----+----+----+ :\n"
": | capacity | 3 | : : :\n"
": +-----------+-------+ : : :\n"
": : `- - - - - - - - - - - -'\n"
"`- - - - - - - - - - - - - -'\n"
"```"
msgstr ""
#: src/ownership/moves-function-calls.md:1
msgid "# Moves in Function Calls"
msgstr "# 함수 호출에서의 이동(Move)"
#: src/ownership/moves-function-calls.md:3
msgid ""
"When you pass a value to a function, the value is assigned to the function\n"
"parameter. This transfers ownership:"
msgstr ""
"값을 함수에 전달할때, 그 값은 매개변수에 할당됩니다. 이때 소유권의 이동이 일어납니다:"
#: src/ownership/moves-function-calls.md:6
msgid ""
"```rust,editable\n"
"fn say_hello(name: String) {\n"
" println!(\"Hello {name}\")\n"
"}"
msgstr ""
#: src/ownership/moves-function-calls.md:11
msgid ""
"fn main() {\n"
" let name = String::from(\"Alice\");\n"
" say_hello(name);\n"
" // say_hello(name);\n"
"}\n"
"```"
msgstr ""
#: src/ownership/moves-function-calls.md:20
msgid ""
"* With the first call to `say_hello`, `main` gives up ownership of `name`. "
"Afterwards, `name` cannot be used anymore within `main`.\n"
"* The heap memory allocated for `name` will be freed at the end of the "
"`say_hello` function.\n"
"* `main` can retain ownership if it passes `name` as a reference (`&name`) "
"and if `say_hello` accepts a reference as a parameter.\n"
"* Alternatively, `main` can pass a clone of `name` in the first call (`name."
"clone()`).\n"
"* Rust makes it harder than C++ to inadvertently create copies by making "
"move semantics the default, and by forcing programmers to make clones "
"explicit."
msgstr ""
"* `say_hello`함수의 첫번째 호출시 `main`함수는 자신이 가진 `name`에 대한 소유"
"권을 포기하므로, 이후 `main`함수에서는 `name`을 사용할 수 없습니다. \n"
"* `name`에 할당되있는 힙 메모리는 `say_hello`함수의 끝에서 해제됩니다.\n"
"* `main`함수에서 `name`을 참조로 전달(빌림)하고(`&name`), `say_hello`에서 매"
"개변수를 참조형으로 수정한다면 `main`함수는 `name`의 소유권을 유지할 수 있습"
"니다. \n"
"* 또는 첫번째 호출 시 `main`함수에서 `name`을 복제하여 전달할 수도 있습니다."
"(`name.clone()`)\n"
"* 러스트는 이동을 기본으로 하고 복제를 명시적으로 선언"
"하도록 만듬으로, 의도치 않게 복사본을 만드는 것이 C++에서보다 어렵습니다. \n"
" "
#: src/ownership/copy-clone.md:1
msgid "# Copying and Cloning"
msgstr "# 복사와 복제"
#: src/ownership/copy-clone.md:3
msgid ""
"While move semantics are the default, certain types are copied by default:"
msgstr "이동이 기본 설정이지만, 특정 타입은 복사됩니다:"
#: src/ownership/copy-clone.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let x = 42;\n"
" let y = x;\n"
" println!(\"x: {x}\");\n"
" println!(\"y: {y}\");\n"
"}\n"
"```"
msgstr ""
#: src/ownership/copy-clone.md:14
msgid "These types implement the `Copy` trait."
msgstr "이러한 타입들은 `Copy` 트레이트를 구현합니다. "
#: src/ownership/copy-clone.md:16
msgid "You can opt-in your own types to use copy semantics:"
msgstr ""
"직접 만든 타입들도 `Copy`트레이트를 구현하여 복사를 할 수 있습니다:"
#: src/ownership/copy-clone.md:18
msgid ""
"```rust,editable\n"
"#[derive(Copy, Clone, Debug)]\n"
"struct Point(i32, i32);"
msgstr ""
#: src/ownership/copy-clone.md:22
msgid ""
"fn main() {\n"
" let p1 = Point(3, 4);\n"
" let p2 = p1;\n"
" println!(\"p1: {p1:?}\");\n"
" println!(\"p2: {p2:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/ownership/copy-clone.md:30
msgid ""
"* After the assignment, both `p1` and `p2` own their own data.\n"
"* We can also use `p1.clone()` to explicitly copy the data."
msgstr ""
"* 할당 후, `p1`와 `p2`는 자신의 데이터를 소유합니다.\n"
"* 명시적으로 `p1.clone()`를 사용하여 데이터를 복사할 수 있습니다."
#: src/ownership/copy-clone.md:35
msgid "Copying and cloning are not the same thing:"
msgstr "복사(copying)와 복제(cloning)는 같지 않습니다: "
#: src/ownership/copy-clone.md:37
msgid ""
"* Copying refers to bitwise copies of memory regions and does not work on "
"arbitrary objects.\n"
"* Copying does not allow for custom logic (unlike copy constructors in C+"
"+).\n"
"* Cloning is a more general operation and also allows for custom behavior by "
"implementing the `Clone` trait.\n"
"* Copying does not work on types that implement the `Drop` trait."
msgstr ""
"* 복사는 메모리의 내용을 그대로 한 벌 더 만드는 것을 의미하며, 아무 객체에서나 다 "
"지원하지는 않습니다. \n"
"* 복사는 커스터마이즈 할 수 없습니다. (C++에서 복사 생성자를 통해 복사 동작을 "
"임의로 구현할 수 있는 것과 비교가 됩니다.)\n"
"* 복제는 보다 일반적인 작업이며, `Clone`트레이트를 구현하여 복제시 동작을 "
"커스터마이즈 할 수 있습니다.\n"
"* `Drop` 트레이트를 구현한 타입은 복사되지 않습니다."
#: src/ownership/copy-clone.md:42 src/ownership/lifetimes-function-calls.md:29
msgid "In the above example, try the following:"
msgstr "위의 예시에서 다음을 시도해 보시기 바랍니다:"
#: src/ownership/copy-clone.md:44
msgid ""
"* Add a `String` field to `struct Point`. It will not compile because "
"`String` is not a `Copy` type.\n"
"* Remove `Copy` from the `derive` attribute. The compiler error is now in "
"the `println!` for `p1`.\n"
"* Show that it works if you clone `p1` instead."
msgstr ""
"* `Point`구조체에 `String`필드를 추가하세요. 컴파일 되지 않을 것입니다. "
"왜냐하면 `String`은 `Copy`트레이트를 구현하고 있지 않기 때문입니다.\n"
"* `derive` 속성에서 `Copy`를 제거해 보세요. `p1`을 `println!` 할 때 "
"컴파일 에러가 발생할 것입니다.\n"
"* `p1`을 복제하면 잘 동작함을 확인해 보세요."
#: src/ownership/copy-clone.md:48
msgid ""
"If students ask about `derive`, it is sufficient to say that this is a way "
"to generate code in Rust\n"
"at compile time. In this case the default implementations of `Copy` and "
"`Clone` traits are generated.\n"
" \n"
"</details>"
msgstr ""
"만약 학생들이 `derive`에 대해 묻는다면, 컴파일 시 러스트에서 코드를 생성하는"
"방법이라고 말하는 것으로 충분합니다.\n"
"위 경우 `Copy`와 `Clone` 트레이트에 대한 기본 구현이 생성됩니다.\n"
" \n"
"</details>"
#: src/ownership/borrowing.md:1
msgid "# Borrowing"
msgstr "# 빌림(Borrowing)"
#: src/ownership/borrowing.md:3
msgid ""
"Instead of transferring ownership when calling a function, you can let a\n"
"function _borrow_ the value:"
msgstr ""
"함수 호출시 값의 소유권을 이동하는 대신의 함수가 값을 _빌려올 수_ 있습니다:"
#: src/ownership/borrowing.md:6 src/ownership/lifetimes-function-calls.md:5
msgid ""
"```rust,editable\n"
"#[derive(Debug)]\n"
"struct Point(i32, i32);"
msgstr ""
#: src/ownership/borrowing.md:10
msgid ""
"fn add(p1: &Point, p2: &Point) -> Point {\n"
" Point(p1.0 + p2.0, p1.1 + p2.1)\n"
"}"
msgstr ""
#: src/ownership/borrowing.md:14
msgid ""
"fn main() {\n"
" let p1 = Point(3, 4);\n"
" let p2 = Point(10, 20);\n"
" let p3 = add(&p1, &p2);\n"
" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/ownership/borrowing.md:22
msgid ""
"* The `add` function _borrows_ two points and returns a new point.\n"
"* The caller retains ownership of the inputs."
msgstr ""
"* `add` 함수는 두 `Point` 객체 값을 _빌려_와서 새로운 `Point` 객체를 반환합니"
"다.\n"
"* `p1`과 `p2`의 소유권은 여전히 호출자(`main`함수)에 있습니다."
#: src/ownership/borrowing.md:27
msgid ""
"Notes on stack returns:\n"
"* Demonstrate that the return from `add` is cheap because the compiler can "
"eliminate the copy operation. Change the above code to print stack addresses "
"and run it on the [Playground]. In the \"DEBUG\" optimization level, the "
"addresses should change, while the stay the same when changing to the "
"\"RELEASE\" setting:"
msgstr ""
"스택에 할당된 값을 리턴하는 것에 대한 참고: \n"
"* `add`에서 값을 반환하는 것은 매우 값이 싸다는 것을 설명하세요. 왜냐하면, "
"컴파일러가 복사 과정을 생략할 수 있기 때문입니다. 위 코드를 스택 주소를 "
"출력하도록 수정하고 [Playground]에서 수행해 보세요. \"디버그\" 최적화 레벨에서는 "
"주소가 바뀌지만, \"릴리즈\" 레벨에서는 바뀌지 않습니다."
#: src/ownership/borrowing.md:30
msgid ""
" ```rust,editable\n"
" #[derive(Debug)]\n"
" struct Point(i32, i32);"
msgstr ""
#: src/ownership/borrowing.md:34
msgid ""
" fn add(p1: &Point, p2: &Point) -> Point {\n"
" let p = Point(p1.0 + p2.0, p1.1 + p2.1);\n"
" println!(\"&p.0: {:p}\", &p.0);\n"
" p\n"
" }"
msgstr ""
#: src/ownership/borrowing.md:40
msgid ""
" fn main() {\n"
" let p1 = Point(3, 4);\n"
" let p2 = Point(10, 20);\n"
" let p3 = add(&p1, &p2);\n"
" println!(\"&p3.0: {:p}\", &p3.0);\n"
" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n"
" }\n"
" ```\n"
"* The Rust compiler can do return value optimization (RVO).\n"
"* In C++, copy elision has to be defined in the language specification "
"because constructors can have side effects. In Rust, this is not an issue at "
"all. If RVO did not happen, Rust will always performs a simple and efficient "
"`memcpy` copy."
msgstr ""
" fn main() {\n"
" let p1 = Point(3, 4);\n"
" let p2 = Point(10, 20);\n"
" let p3 = add(&p1, &p2);\n"
" println!(\"&p3.0: {:p}\", &p3.0);\n"
" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n"
" }\n"
" ```\n"
"* 러스트 컴파일러는 반환값 최적화(RVO)를 수행할 수 있습니다.\n"
"* C++에서 copy elision은 생성자의 부수효과 가능성이 있어 언어레벨의 정의가 "
"필요하지만 러스트에서는 문제가 되지 않습니다. 만약 RVO가 발생하지 않으면 러스"
"트는 항상 간단하고 효율적인 `memcpy`복사를 수행할 것입니다."
#: src/ownership/borrowing.md:53
msgid "[Playground]: https://play.rust-lang.org/"
msgstr ""
#: src/ownership/shared-unique-borrows.md:1
msgid "# Shared and Unique Borrows"
msgstr "# 공유와 고유 빌림"
#: src/ownership/shared-unique-borrows.md:3
msgid "Rust puts constraints on the ways you can borrow values:"
msgstr "러스트에서는 값을 빌릴 때 다음과 같은 제약조건이 있습니다:"
#: src/ownership/shared-unique-borrows.md:5
msgid ""
"* You can have one or more `&T` values at any given time, _or_\n"
"* You can have exactly one `&mut T` value."
msgstr ""
"* 한번에 하나 이상의 `&T` 값을 가지거나, _또는_\n"
"* 정확히 하나의 `&mut T` 값만을 가질 수 있습니다."
#: src/ownership/shared-unique-borrows.md:8
msgid ""
"```rust,editable,compile_fail\n"
"fn main() {\n"
" let mut a: i32 = 10;\n"
" let b: &i32 = &a;"
msgstr ""
#: src/ownership/shared-unique-borrows.md:13
msgid ""
" {\n"
" let c: &mut i32 = &mut a;\n"
" *c = 20;\n"
" }"
msgstr ""
#: src/ownership/shared-unique-borrows.md:18 src/std/rc.md:13
msgid ""
" println!(\"a: {a}\");\n"
" println!(\"b: {b}\");\n"
"}\n"
"```"
msgstr ""
#: src/ownership/shared-unique-borrows.md:25
msgid ""
"* The above code does not compile because `a` is borrowed as mutable "
"(through `c`) and as immutable (through `b`) at the same time.\n"
"* Move the `println!` statement for `b` before the scope that introduces `c` "
"to make the code compile.\n"
"* After that change, the compiler realizes that `b` is only ever used before "
"the new mutable borrow of `a` through `c`. This is a feature of the borrow "
"checker called \"non-lexical lifetimes\"."
msgstr ""
"* 위 코드 컴파일 되지 않습니다. 왜냐하면 `c`는 `a`를 가변 변수로 빌렸고, "
"이와 동시에 `b`는 `a`를 불변 변수로 빌렸기 때문입니다.\n"
"* `b`에 대한 `println!` 구분을 `c`가 있는 스코프 앞으로 이동하면 컴파일이 됩니다."
"* 이렇게 바꾸면, 컴파일러는 `c`가 `a`를 가변 변수로 빌리기 전에만 `b`가 사용된다는 "
"것을 확인할 수 있습니다. 빌림 검사기의 이러한 기능을 \"non-lexical lifetime\" 이라고 "
"합니다. (_역주_: 단순히 스코프만 보면 `b`의 수명은 `main`함수의 전체라고 생각할 수 있습니다. "
"때문에 `c`의 블럭 안에서는 `a`에 대한 가변 빌림과 불변 빌림이 동시에 존재하는 것 처럼 "
"보이며, 이는 위 제약 조건을 위반하는 것으로 생각할 수 있습니다. 그러나 컴파일러는 `b`"
"가 `c`블럭이 시작되기 전에만 사용된다는 점을 적극 활용해서 `b`의 수명을 `c`블럭의 시작 "
"전 까지로 줄입니다. 그러면 `b`와 `c`의 수명은 겹치지 않고, 따라서 제약 조건을 위반하지 "
"않습니다.)"
#: src/ownership/lifetimes.md:1
msgid "# Lifetimes"
msgstr "# 수명"
#: src/ownership/lifetimes.md:3
msgid "A borrowed value has a _lifetime_:"
msgstr "빌려온 값은 _수명_을 갖습니다:"
#: src/ownership/lifetimes.md:5
msgid ""
"* The lifetime can be elided: `add(p1: &Point, p2: &Point) -> Point`.\n"
"* Lifetimes can also be explicit: `&'a Point`, `&'document str`.\n"
"* Read `&'a Point` as \"a borrowed `Point` which is valid for at least the\n"
" lifetime `a`\".\n"
"* Lifetimes are always inferred by the compiler: you cannot assign a "
"lifetime\n"
" yourself.\n"
" * Lifetime annotations create constraints; the compiler verifies that "
"there is\n"
" a valid solution."
msgstr ""
"* 수명은 생략할 수 있습니다: `add(p1: &Point, p2: &Point) -> Point`.\n"
"* 물론 명시할 수도 있습니다: `&'a Point`, `&'document str`.\n"
"* `&'a Point` 는 `Point`의 수명이 최소한 `'a`라는 수명보다는 같거나 더 길다는 것을 의미합니다.\n"
"* 수명은 항상 컴파일러가 자동으로 추론합니다. 직접 수명을 지정할 수는 없습니다.\n"
" * 수명 표기(`'`)은 수명 추론시 제약조건이 됩니다. 컴파일러는 이 제약조건을 만족시키는 "
"유요한 수명을 추론할 수 있는지 검사를 합니다."
#: src/ownership/lifetimes-function-calls.md:1
msgid "# Lifetimes in Function Calls"
msgstr "# 함수 호출에서의 수명"
#: src/ownership/lifetimes-function-calls.md:3
msgid ""
"In addition to borrowing its arguments, a function can return a borrowed "
"value:"
msgstr "함수는 인수를 빌리는 것 외에도 빌린 값을 반환할 수 있습니다:"
#: src/ownership/lifetimes-function-calls.md:9
msgid ""
"fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n"
" if p1.0 < p2.0 { p1 } else { p2 }\n"
"}"
msgstr ""
#: src/ownership/lifetimes-function-calls.md:13
msgid ""
"fn main() {\n"
" let p1: Point = Point(10, 10);\n"
" let p2: Point = Point(20, 20);\n"
" let p3: &Point = left_most(&p1, &p2);\n"
" println!(\"left-most point: {:?}\", p3);\n"
"}\n"
"```"
msgstr ""
#: src/ownership/lifetimes-function-calls.md:21
msgid ""
"* `'a` is a generic parameter, it is inferred by the compiler.\n"
"* Lifetimes start with `'` and `'a` is a typical default name.\n"
"* Read `&'a Point` as \"a borrowed `Point` which is valid for at least the\n"
" lifetime `a`\".\n"
" * The _at least_ part is important when parameters are in different scopes."
msgstr ""
"* `'a`는 제너릭 매개변수로 컴파일러로에 의해 추론됩니다.\n"
"* 수명의 이름은 `'` 로 시작하며 보통 `'a`를 많이 씁니다.\n"
"* `&'a Point` 는 `Point`의 수명이 `'a` 수명과 최소한 같거나 더 길다는 것을 의미합니다.\n"
" * 매개변수들이 서로 다른 스코프에 있을 경우 _최소한_이라는 조건이 중요합니다."
#: src/ownership/lifetimes-function-calls.md:31
msgid ""
"* Move the declaration of `p2` and `p3` into a a new scope (`{ ... }`), "
"resulting in the following code:\n"
" ```rust,ignore\n"
" #[derive(Debug)]\n"
" struct Point(i32, i32);"
msgstr ""
"* `p2`와 `p3`를 새로운 범위(`{...}`)로 아래 코드와 같이 이동해 봅니다:\n"
" ```rust,ignore\n"
" #[derive(Debug)]\n"
" struct Point(i32, i32);"
#: src/ownership/lifetimes-function-calls.md:36
msgid ""
" fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n"
" if p1.0 < p2.0 { p1 } else { p2 }\n"
" }"
msgstr ""
#: src/ownership/lifetimes-function-calls.md:40
msgid ""
" fn main() {\n"
" let p1: Point = Point(10, 10);\n"
" let p3: &Point;\n"
" {\n"
" let p2: Point = Point(20, 20);\n"
" p3 = left_most(&p1, &p2);\n"
" }\n"
" println!(\"left-most point: {:?}\", p3);\n"
" }\n"
" ```\n"
" Note how this does not compile since `p3` outlives `p2`."
msgstr ""
" fn main() {\n"
" let p1: Point = Point(10, 10);\n"
" let p3: &Point;\n"
" {\n"
" let p2: Point = Point(20, 20);\n"
" p3 = left_most(&p1, &p2);\n"
" }\n"
" println!(\"left-most point: {:?}\", p3);\n"
" }\n"
" ```\n"
" `p3`의 수명이 `p2` 보다 길기 때문에 이 예제는 컴파일되지 않음을 확인하시기 "
"바랍니다."
#: src/ownership/lifetimes-function-calls.md:52
msgid ""
"* Reset the workspace and change the function signature to `fn left_most<'a, "
"'b>(p1: &'a Point, p2: &'a Point) -> &'b Point`. This will not compile "
"because the relationship between the lifetimes `'a` and `'b` is unclear.\n"
"* Another way to explain it:\n"
" * Two references to two values are borrowed by a function and the function "
"returns\n"
" another reference.\n"
" * It must have come from one of those two inputs (or from a global "
"variable).\n"
" * Which one is it? The compiler needs to to know, so at the call site the "
"returned reference is not used\n"
" for longer than a variable from where the reference came from."
msgstr ""
"* 작업공간을 초기화 한 후 함수 시그니처를 `fn left_most<'a, 'b>(p1: &'a "
"Point, p2: &'a Point) -> &'b Point`로 변경해 봅니다. 이 경우 `'a`와 `'b`사"
"이의 관계가 불분명하기 때문에 컴파일 되지 않습니다.\n"
"* 이 에러를 설명하는 또 다른 방법은 다음과 같습니다: \n"
" * 이 함수는 두 값을 빌려서, 새로운 참조를 반환합니다.\n"
" * 이 반환된 참조는 두 입력 중 하나로 부터 와야 합니다. (아니면 전역 변수로 부터)\n"
" * 두 입력 중 어떤 것일까요? 컴파일러는 이를 알아야 합니다. 그래야만 "
"함수 호출부에서 봤을 때, 반환된 참조의 수명이 원래 값을 수명보다 길지 않음을 확인할 "
"수 있기 때문입니다."
#: src/ownership/lifetimes-data-structures.md:1
msgid "# Lifetimes in Data Structures"
msgstr "# 구조체에서의 수명"
#: src/ownership/lifetimes-data-structures.md:3
msgid ""
"If a data type stores borrowed data, it must be annotated with a lifetime:"
msgstr ""
"어떤 타입이 빌려온 데이터를 저장하고 있다면, 반드시 수명을 표시해야 합니다:"
#: src/ownership/lifetimes-data-structures.md:5
msgid ""
"```rust,editable\n"
"#[derive(Debug)]\n"
"struct Highlight<'doc>(&'doc str);"
msgstr ""
#: src/ownership/lifetimes-data-structures.md:9
msgid ""
"fn erase(text: String) {\n"
" println!(\"Bye {text}!\");\n"
"}"
msgstr ""
#: src/ownership/lifetimes-data-structures.md:13
msgid ""
"fn main() {\n"
" let text = String::from(\"The quick brown fox jumps over the lazy dog."
"\");\n"
" let fox = Highlight(&text[4..19]);\n"
" let dog = Highlight(&text[35..43]);\n"
" // erase(text);\n"
" println!(\"{fox:?}\");\n"
" println!(\"{dog:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/ownership/lifetimes-data-structures.md:25
msgid ""
"* In the above example, the annotation on `Highlight` enforces that the data "
"underlying the contained `&str` lives at least as long as any instance of "
"`Highlight` that uses that data.\n"
"* If `text` is consumed before the end of the lifetime of `fox` (or `dog`), "
"the borrow checker throws an error.\n"
"* Types with borrowed data force users to hold on to the original data. This "
"can be useful for creating lightweight views, but it generally makes them "
"somewhat harder to use.\n"
"* When possible, make data structures own their data directly.\n"
"* Some structs with multiple references inside can have more than one "
"lifetime annotation. This can be necessary if there is a need to describe "
"lifetime relationships between the references themselves, in addition to the "
"lifetime of the struct itself. Those are very advanced use cases.\n"
"</details>"
msgstr ""
"* 위의 예제에서, `Highlight`의 어노테이션 (_역주_: `<'doc>`)은 그 안에 있는 "
"`Highlight`가 살아있는 동안에는 그 객체가 사용하는 `&str`도 살아있어야 한다는 "
"것을 의미합니다."
"* 만약 `text`가 `fox` (혹은 `dog`)의 수명이 다하기 전에 소모된다면 "
"(_역주_: 주석 처리된 `erase`함수가 호출되었다면 `text`는 그 함수 안으로 이동되고 "
"따라서 그 수명을 다하게 됩니다.) 빌림 검사기는 에러를 발생합니다."
"* 빌린 데이터를 가지고 있는 타입은 사용자로 하여금 원본 데이터를 유지하도록 "
"강제합니다. 이런 타입은 경량 뷰(lightweight view)를 만드는데 유용하지만, 이 제약 "
"조건 때문에 이런 타입을 사용하는 것이 쉽지만은 않습니다."
"* 따라서, 가능하다면, 구조체가 자신의 데이터를 직접 소유하도록 하는 것이 좋습니다."
"* 한 구조체안에 여러 참조가 있으면서, 이 참조들의 수명이 서로 다르게 지정되는 경우도 "
"있습니다. 이는 참조와 그 구조체 간의 관계 뿐만이 아니라, 그 참조들 사이의 수명 관계를 "
"설명해야 할 경우에 필요합니다. 매우 고급 기술입니다.</details>"
#: src/exercises/day-1/afternoon.md:1
msgid "# Day 1: Afternoon Exercises"
msgstr "# 1일차 오후 연습문제"
#: src/exercises/day-1/afternoon.md:3
msgid "We will look at two things:"
msgstr "이번 연습문제는 아래 두가지입니다:"
#: src/exercises/day-1/afternoon.md:5
msgid "* A small book library,"
msgstr "* 작은 도서관"
#: src/exercises/day-1/afternoon.md:7
msgid "* Iterators and ownership (hard)."
msgstr "* 반복자와 소유권 (어려움)"
#: src/exercises/day-1/afternoon.md:13 src/exercises/day-2/afternoon.md:9
#: src/exercises/day-3/afternoon.md:9
msgid "[solutions]: solutions-afternoon.md"
msgstr ""
#: src/exercises/day-1/book-library.md:1
msgid "# Designing a Library"
msgstr "# 도서관 설계"
#: src/exercises/day-1/book-library.md:3
msgid ""
"We will learn much more about structs and the `Vec<T>` type tomorrow. For "
"now,\n"
"you just need to know part of its API:"
msgstr ""
"우리는 내일 구조체와 `Vec<T>`에 대해 더 많은 것을 배울 것입니다. \n"
"일단 오늘은 API의 일부만 알면 됩니다:"
#: src/exercises/day-1/book-library.md:6
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let mut vec = vec![10, 20];\n"
" vec.push(30);\n"
" println!(\"middle value: {}\", vec[vec.len() / 2]);\n"
" for item in vec.iter() {\n"
" println!(\"item: {item}\");\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-1/book-library.md:17
msgid ""
"Use this to create a library application. Copy the code below to\n"
"<https://play.rust-lang.org/> and update the types to make it compile:"
msgstr ""
"도서관 프로그램을 만들기 위해 아래 코드를 <https://play.rust-lang.org/>에 복"
"사해서 구현하시면 됩니다."
#: src/exercises/day-1/book-library.md:24
msgid ""
"struct Library {\n"
" books: Vec<Book>,\n"
"}"
msgstr ""
#: src/exercises/day-1/book-library.md:28
#: src/exercises/day-1/solutions-afternoon.md:27
msgid ""
"struct Book {\n"
" title: String,\n"
" year: u16,\n"
"}"
msgstr ""
#: src/exercises/day-1/book-library.md:33
#: src/exercises/day-1/solutions-afternoon.md:32
msgid ""
"impl Book {\n"
" // This is a constructor, used below.\n"
" fn new(title: &str, year: u16) -> Book {\n"
" Book {\n"
" title: String::from(title),\n"
" year,\n"
" }\n"
" }\n"
"}"
msgstr ""
"impl Book {\n"
" // 아래는 Book 구조체의 생성자입니다.\n"
" fn new(title: &str, year: u16) -> Book {\n"
" Book {\n"
" title: String::from(title),\n"
" year,\n"
" }\n"
" }\n"
"}"
#: src/exercises/day-1/book-library.md:43
msgid ""
"// This makes it possible to print Book values with {}.\n"
"impl std::fmt::Display for Book {\n"
" fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n"
" write!(f, \"{} ({})\", self.title, self.year)\n"
" }\n"
"}"
msgstr ""
"// 이 구현메서드는 {} 포맷으로 출력할 수 있게 도와줍니다.\n"
"impl std::fmt::Display for Book {\n"
" fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n"
" write!(f, \"{} ({})\", self.title, self.year)\n"
" }\n"
"}"
#: src/exercises/day-1/book-library.md:50
msgid ""
"impl Library {\n"
" fn new() -> Library {\n"
" unimplemented!()\n"
" }"
msgstr ""
#: src/exercises/day-1/book-library.md:55
msgid ""
" //fn len(self) -> usize {\n"
" // unimplemented!()\n"
" //}"
msgstr ""
#: src/exercises/day-1/book-library.md:59
msgid ""
" //fn is_empty(self) -> bool {\n"
" // unimplemented!()\n"
" //}"
msgstr ""
#: src/exercises/day-1/book-library.md:63
msgid ""
" //fn add_book(self, book: Book) {\n"
" // unimplemented!()\n"
" //}"
msgstr ""
#: src/exercises/day-1/book-library.md:67
msgid ""
" //fn print_books(self) {\n"
" // unimplemented!()\n"
" //}"
msgstr ""
#: src/exercises/day-1/book-library.md:71
msgid ""
" //fn oldest_book(self) -> Option<&Book> {\n"
" // unimplemented!()\n"
" //}\n"
"}"
msgstr ""
#: src/exercises/day-1/book-library.md:76
msgid ""
"// This shows the desired behavior. Uncomment the code below and\n"
"// implement the missing methods. You will need to update the\n"
"// method signatures, including the \"self\" parameter! You may\n"
"// also need to update the variable bindings within main.\n"
"fn main() {\n"
" let library = Library::new();"
msgstr ""
"// 아래 소스 주석을 제거하고 누락된 메서드를 구현하세요\n"
"// 미구현 메서드도 존재하므로 메서드 시그니처를 업데이트 하세요(self 포함)\n"
"fn main() {\n"
" let library = Library::new();"
#: src/exercises/day-1/book-library.md:83
msgid ""
" //println!(\"Our library is empty: {}\", library.is_empty());\n"
" //\n"
" //library.add_book(Book::new(\"Lord of the Rings\", 1954));\n"
" //library.add_book(Book::new(\"Alice's Adventures in Wonderland\", "
"1865));\n"
" //\n"
" //library.print_books();\n"
" //\n"
" //match library.oldest_book() {\n"
" // Some(book) => println!(\"My oldest book is {book}\"),\n"
" // None => println!(\"My library is empty!\"),\n"
" //}\n"
" //\n"
" //println!(\"Our library has {} books\", library.len());\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-1/book-library.md:99
msgid ""
"<details>\n"
" \n"
"[Solution](solutions-afternoon.md#designing-a-library)"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:1
msgid "# Iterators and Ownership"
msgstr "# 반복자와 소유권"
#: src/exercises/day-1/iterators-and-ownership.md:3
msgid ""
"The ownership model of Rust affects many APIs. An example of this is the\n"
"[`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html) and\n"
"[`IntoIterator`](https://doc.rust-lang.org/std/iter/trait.IntoIterator."
"html)\n"
"traits."
msgstr ""
"러스트의 소유권 모델은 많은 API에 반영이 되어 있습니다. \n"
"예를들어 [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator."
"html) 와 [`IntoIterator`](https://doc.rust-lang.org/std/iter/trait."
"IntoIterator.html) 같은 트레이트가 있습니다."
#: src/exercises/day-1/iterators-and-ownership.md:8
msgid "## `Iterator`"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:10
msgid ""
"Traits are like interfaces: they describe behavior (methods) for a type. "
"The\n"
"`Iterator` trait simply says that you can call `next` until you get `None` "
"back:"
msgstr ""
"트레이트는 타입에 대한 행동(메서드)를 설명한다는 점에서 인터페이스와 유사합"
"니다. `Iterator`는 단순히 `None`이 나올때까지 `next`를 호출하는 것이 가능하다는 "
"것을 나타내는 트레이트입니다."
#: src/exercises/day-1/iterators-and-ownership.md:13
msgid ""
"```rust\n"
"pub trait Iterator {\n"
" type Item;\n"
" fn next(&mut self) -> Option<Self::Item>;\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:20
msgid "You use this trait like this:"
msgstr "`Iterator` 트레이트는 이렇게 사용합니다:"
#: src/exercises/day-1/iterators-and-ownership.md:22
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let v: Vec<i8> = vec![10, 20, 30];\n"
" let mut iter = v.iter();"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:27
msgid ""
" println!(\"v[0]: {:?}\", iter.next());\n"
" println!(\"v[1]: {:?}\", iter.next());\n"
" println!(\"v[2]: {:?}\", iter.next());\n"
" println!(\"No more items: {:?}\", iter.next());\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:34
msgid "What is the type returned by the iterator? Test your answer here:"
msgstr ""
"반복자가 반환하는 값들은 타입이 뭘까요? 여기서 답을 테스트 해 보세요:"
#: src/exercises/day-1/iterators-and-ownership.md:36
msgid ""
"```rust,editable,compile_fail\n"
"fn main() {\n"
" let v: Vec<i8> = vec![10, 20, 30];\n"
" let mut iter = v.iter();"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:41
#: src/exercises/day-1/iterators-and-ownership.md:78
msgid ""
" let v0: Option<..> = iter.next();\n"
" println!(\"v0: {v0:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:46
msgid "Why is this type used?"
msgstr "왜 이런 타입이 사용되는 것일까요?"
#: src/exercises/day-1/iterators-and-ownership.md:48
msgid "## `IntoIterator`"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:50
msgid ""
"The `Iterator` trait tells you how to _iterate_ once you have created an\n"
"iterator. The related trait `IntoIterator` tells you how to create the "
"iterator:"
msgstr ""
"`Iterator` 트레이트는 생성된 반복자를 _사용_하는 방법을 알려줍니다. 반면 "
"`IntoIterator` 트레이트는 반복자를 생성하는 방법을 알려줍니다:"
#: src/exercises/day-1/iterators-and-ownership.md:53
msgid ""
"```rust\n"
"pub trait IntoIterator {\n"
" type Item;\n"
" type IntoIter: Iterator<Item = Self::Item>;"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:58
msgid ""
" fn into_iter(self) -> Self::IntoIter;\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:62
msgid ""
"The syntax here means that every implementation of `IntoIterator` must\n"
"declare two types:"
msgstr "`IntoIterator`의 모든 구현은 반드시 다음의 두 타입을 선언해야합니다:"
#: src/exercises/day-1/iterators-and-ownership.md:65
msgid ""
"* `Item`: the type we iterate over, such as `i8`,\n"
"* `IntoIter`: the `Iterator` type returned by the `into_iter` method."
msgstr ""
"* `Item`: `i8`과 같이 반복되는 값의 타입\n"
"* `IntoIter`: `into_iter` 메서드에서 반환되는 `Iterator`타입."
#: src/exercises/day-1/iterators-and-ownership.md:68
msgid ""
"Note that `IntoIter` and `Item` are linked: the iterator must have the same\n"
"`Item` type, which means that it returns `Option<Item>`"
msgstr ""
"`IntoIter`에서 `Item`가 연결되어 있음을 주목하세요. `IntoIter` 반복자는 `Item` "
"타입의 데이터를 가리켜야 합니다. 즉, 반복자는 `Option<Item>`을 리턴합니다."
#: src/exercises/day-1/iterators-and-ownership.md:71
msgid "Like before, what is the type returned by the iterator?"
msgstr ""
"이전과 마찬가지로, 반복자가 반환하는 타입은 무엇입니까?"
#: src/exercises/day-1/iterators-and-ownership.md:73
msgid ""
"```rust,editable,compile_fail\n"
"fn main() {\n"
" let v: Vec<String> = vec![String::from(\"foo\"), String::"
"from(\"bar\")];\n"
" let mut iter = v.into_iter();"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:83
msgid "## `for` Loops"
msgstr "## 배열과 `for` 반복문"
#: src/exercises/day-1/iterators-and-ownership.md:85
msgid ""
"Now that we know both `Iterator` and `IntoIterator`, we can build `for` "
"loops.\n"
"They call `into_iter()` on an expression and iterates over the resulting\n"
"iterator:"
msgstr ""
"자, 이제 우리는 `Iterator`와 `IntoIterator`를 알았으므로 `for` 루프를 만들 "
"수 있습니다. \n"
"`for` 루프는 `into_iter()`를 호출하여 반복자를 만든 다음 그 반복자를 이용하여 "
"요소들을 반복해서 접근합니다:"
#: src/exercises/day-1/iterators-and-ownership.md:89
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let v: Vec<String> = vec![String::from(\"foo\"), String::from(\"bar\")];"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:93
msgid ""
" for word in &v {\n"
" println!(\"word: {word}\");\n"
" }"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:97
msgid ""
" for word in v {\n"
" println!(\"word: {word}\");\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-1/iterators-and-ownership.md:103
msgid "What is the type of `word` in each loop?"
msgstr "매 루프에서 `word`의 타입은 무엇입니까? "
#: src/exercises/day-1/iterators-and-ownership.md:105
msgid ""
"Experiment with the code above and then consult the documentation for "
"[`impl\n"
"IntoIterator for\n"
"&Vec<T>`](https://doc.rust-lang.org/std/vec/struct.Vec.html#impl-"
"IntoIterator-for-%26%27a%20Vec%3CT%2C%20A%3E)\n"
"and [`impl IntoIterator for\n"
"Vec<T>`](https://doc.rust-lang.org/std/vec/struct.Vec.html#impl-IntoIterator-"
"for-Vec%3CT%2C%20A%3E)\n"
"to check your answers."
msgstr ""
"위 코드에서 실험 해 본 후 다음 문서를 참조해서 답변을 확인하시기 바랍니다.\n"
"* [`impl IntoIterator for &Vec<T>`](https://doc.rust-lang.org/std/vec/struct."
"Vec.html#impl-IntoIterator-for-%26%27a%20Vec%3CT%2C%20A%3E)\n"
"* [`impl IntoIterator for Vec<T>`](https://doc.rust-lang.org/std/vec/struct."
"Vec.html#impl-IntoIterator-for-Vec%3CT%2C%20A%3E)"
#: src/welcome-day-2.md:1
msgid "# Welcome to Day 2"
msgstr "# 2일차 개요"
#: src/welcome-day-2.md:3
msgid "Now that we have seen a fair amount of Rust, we will continue with:"
msgstr "상당한 분량의 러스트에 대해 보았고, 이어서 오늘 강의를 진행하겠습니다:"
#: src/welcome-day-2.md:5
msgid "* Structs, enums, methods."
msgstr "* 구조체, 열거형, 메서드"
#: src/welcome-day-2.md:7
msgid "* Pattern matching: destructuring enums, structs, and arrays."
msgstr "* 패턴 매칭: 열거형, 구조체 그리고 배열 분해"
#: src/welcome-day-2.md:9
msgid ""
"* Control flow constructs: `if`, `if let`, `while`, `while let`, `break`, "
"and\n"
" `continue`."
msgstr ""
"* 흐름 제어: `if`, `if let`, `while`, `while let`, `break`, 그리고 "
"`continue`."
#: src/welcome-day-2.md:12
msgid ""
"* The Standard Library: `String`, `Option` and `Result`, `Vec`, `HashMap`, "
"`Rc`\n"
" and `Arc`."
msgstr ""
"* 표준 라이브러리:: `String`, `Option` 과 `Result`, `Vec`, `HashMap`, `Rc` "
"그리고 `Arc`."
#: src/welcome-day-2.md:15
msgid "* Modules: visibility, paths, and filesystem hierarchy."
msgstr "* 모듈: 가시성, 경로 및 파일 시스템 계층."
#: src/structs.md:1
msgid "# Structs"
msgstr "# 구조체"
#: src/structs.md:3
msgid "Like C and C++, Rust has support for custom structs:"
msgstr "C/C++ 와 마찬가지로 러스트는 커스텀 구조체를 지원합니다:"
#: src/structs.md:5
msgid ""
"```rust,editable\n"
"struct Person {\n"
" name: String,\n"
" age: u8,\n"
"}"
msgstr ""
#: src/structs.md:11
msgid ""
"fn main() {\n"
" let mut peter = Person {\n"
" name: String::from(\"Peter\"),\n"
" age: 27,\n"
" };\n"
" println!(\"{} is {} years old\", peter.name, peter.age);\n"
" \n"
" peter.age = 28;\n"
" println!(\"{} is {} years old\", peter.name, peter.age);\n"
" \n"
" let jackie = Person {\n"
" name: String::from(\"Jackie\"),\n"
" ..peter\n"
" };\n"
" println!(\"{} is {} years old\", jackie.name, jackie.age);\n"
"}\n"
"```"
msgstr ""
#: src/structs.md:29
msgid ""
"<details>\n"
"Key Points: "
msgstr ""
"<details>\n"
"키 포인트: "
#: src/structs.md:32
msgid ""
"* Structs work like in C or C++.\n"
" * Like in C++, and unlike in C, no typedef is needed to define a type.\n"
" * Unlike in C++, there is no inheritance between structs.\n"
"* Methods are defined in an `impl` block, which we will see in following "
"slides.\n"
"* This may be a good time to let people know there are different types of "
"structs. \n"
" * Zero-sized structs `e.g., struct Foo;` might be used when implementing a "
"trait on some type but don’t have any data that you want to store in the "
"value itself. \n"
" * The next slide will introduce Tuple structs."
msgstr ""
"* 구조체는 C/C++ 와 유사합니다.\n"
" * C++ 와 같지만 C와는 달리 타입을 정의하기 위해 'typedef'가 필요하지 않습니"
"다.\n"
" * C++ 와 달리 구조체 간 상속은 없습니다.\n"
"* 메서드는 `impl`블록을 정의 합니다. 다음 슬라이드에서 확인 할 수 있습니다.\n"
"* 사람들에게 다른 종류의 구조체가 있음을 알게 하기에 좋은 시간일 것입니다.\n"
"* 0 크기 구조체(예: `struct Foo;`)는 데이터를 가지고 있지 않지만 특정 타입"
"의 트레이트를 구현할떄 유용합니다.\n"
"* 다음 슬라이드에서는 튜플 (구조체)를 소개합니다."
#: src/structs/tuple-structs.md:1
msgid "# Tuple Structs"
msgstr "# 튜플"
#: src/structs/tuple-structs.md:3
msgid "If the field names are unimportant, you can use a tuple struct:"
msgstr "각 필드 이름이 중요하지 않다면 튜플 구조체를 사용할 수 있습니다:"
#: src/structs/tuple-structs.md:5
msgid ""
"```rust,editable\n"
"struct Point(i32, i32);"
msgstr ""
#: src/structs/tuple-structs.md:8
msgid ""
"fn main() {\n"
" let p = Point(17, 23);\n"
" println!(\"({}, {})\", p.0, p.1);\n"
"}\n"
"```"
msgstr ""
#: src/structs/tuple-structs.md:14
msgid "This is often used for single-field wrappers (called newtypes):"
msgstr ""
"튜플 구조체는 종종 단일 필드의 래퍼(wrapper, 러스트에서 뉴타입(newtype)이라고 부름)"
"로 사용됩니다."
#: src/structs/tuple-structs.md:16
msgid ""
"```rust,editable,compile_fail\n"
"struct PoundOfForce(f64);\n"
"struct Newtons(f64);"
msgstr ""
#: src/structs/tuple-structs.md:20
msgid ""
"fn compute_thruster_force() -> PoundOfForce {\n"
" todo!(\"Ask a rocket scientist at NASA\")\n"
"}"
msgstr ""
#: src/structs/tuple-structs.md:24
msgid ""
"fn set_thruster_force(force: Newtons) {\n"
" // ...\n"
"}"
msgstr ""
#: src/structs/tuple-structs.md:28
msgid ""
"fn main() {\n"
" let force = compute_thruster_force();\n"
" set_thruster_force(force);\n"
"}"
msgstr ""
#: src/structs/tuple-structs.md:33 src/generics/trait-objects.md:86
msgid "```"
msgstr ""
#: src/structs/tuple-structs.md:37
msgid ""
"Newtypes are a great way to encode additional information about the value in "
"a primitive type, for example:\n"
" * The number is measured in some units: `Newtons` in the example above.\n"
" * The value passed some validation when it was created, so you no longer "
"have to validate it again at every use: 'PhoneNumber(String)` or "
"`OddNumber(u32)`.\n"
" \n"
"</details>"
msgstr ""
"뉴타입은 다음과 같은 원시타입 값에 대한 추가정보를 표시하는 데 유용합니다:\n"
" * 단위 표시를 위한 숫자: 위 예제에서는 뉴턴 단위 표기를 위해 사용합니다.\n"
" * 값이 생성될 때 이미 유효성 검사를 통과 했으므로 추가적인 검사가 필요없는 경우:"
" `PhoneNumber(String)`또는 `OddNumber(u32)`"
"</details>"
#: src/structs/field-shorthand.md:1
msgid "# Field Shorthand Syntax"
msgstr "# 필드 할당 단축 문법(Field Shorthand Syntax)"
#: src/structs/field-shorthand.md:3
msgid ""
"If you already have variables with the right names, then you can create the\n"
"struct using a shorthand:"
msgstr ""
"구조체 필드와 동일한 이름의 변수가 있다면 아래와 같이 _짧은 문법_ 으로 구조체"
"를 생성할 수 있습니다:"
#: src/structs/field-shorthand.md:6 src/methods.md:6
msgid ""
"```rust,editable\n"
"#[derive(Debug)]\n"
"struct Person {\n"
" name: String,\n"
" age: u8,\n"
"}"
msgstr ""
#: src/structs/field-shorthand.md:13
msgid ""
"impl Person {\n"
" fn new(name: String, age: u8) -> Person {\n"
" Person { name, age }\n"
" }\n"
"}"
msgstr ""
#: src/structs/field-shorthand.md:19
msgid ""
"fn main() {\n"
" let peter = Person::new(String::from(\"Peter\"), 27);\n"
" println!(\"{peter:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/structs/field-shorthand.md:27
msgid ""
"The `new` function could be written using `Self` as a type, as it is "
"interchangeable with the struct type name"
msgstr ""
"`new`함수를 다음처럼 구조체 이름 대신 `Self`를 사용하여 작성해도 됩니다."
#: src/structs/field-shorthand.md:29
msgid ""
"```rust,ignore\n"
"impl Person {\n"
" fn new(name: String, age: u8) -> Self {\n"
" Self { name, age }\n"
" }\n"
"}\n"
"```\n"
" \n"
"</details>"
msgstr ""
#: src/enums.md:1
msgid "# Enums"
msgstr "# 열거형"
#: src/enums.md:3
msgid ""
"The `enum` keyword allows the creation of a type which has a few\n"
"different variants:"
msgstr "`enum` 키워드는 몇가지 유형(variant)으로 표현되는 타입을 생성합니다:"
#: src/enums.md:6
msgid ""
"```rust,editable\n"
"fn generate_random_number() -> i32 {\n"
" 4 // Chosen by fair dice roll. Guaranteed to be random.\n"
"}"
msgstr ""
#: src/enums.md:11
msgid ""
"#[derive(Debug)]\n"
"enum CoinFlip {\n"
" Heads,\n"
" Tails,\n"
"}"
msgstr ""
#: src/enums.md:17
msgid ""
"fn flip_coin() -> CoinFlip {\n"
" let random_number = generate_random_number();\n"
" if random_number % 2 == 0 {\n"
" return CoinFlip::Heads;\n"
" } else {\n"
" return CoinFlip::Tails;\n"
" }\n"
"}"
msgstr ""
#: src/enums.md:26
msgid ""
"fn main() {\n"
" println!(\"You got: {:?}\", flip_coin());\n"
"}\n"
"```"
msgstr ""
#: src/enums.md:31
msgid ""
"<details>\n"
" \n"
"Key Points:"
msgstr ""
"<details>\n"
" \n"
"키 포인트:"
#: src/enums.md:35
msgid ""
"* Enumerations allow you to collect a set of values under one type\n"
"* This page offers an enum type `CoinFlip` with two variants `Heads` and "
"`Tail`. You might note the namespace when using variants.\n"
"* This might be a good time to compare Structs and Enums:\n"
" * In both, you can have a simple version without fields (unit struct) or "
"one with different types of fields (variant payloads). \n"
" * In both, associated functions are defined within an `impl` block.\n"
" * You could even implement the different variants of an enum with separate "
"structs but then they wouldn’t be the same type as they would if they were "
"all defined in an enum. \n"
"</details>"
msgstr ""
"* 열거형은 값들의 집합을 하나의 타입으로 표현할 수 있게 합니다.\n"
"* 위의 `CoinFlip` 열거형 타입은 `Heads`와 `Tail` 두가지 variant를 가집니다."
" 열거형 타입의 variant는 네임스페이스를 붙여서 사용합니다.\n"
"* 구조체와 열거형을 비교해 볼까요?\n"
" * 구조체나 열거형 모두, 필드가 하나도 없는 단순한 형태도 가능 하고, 여러 타입의"
" 필드를 가질 수도 있습니다.\n"
" * 둘 다 연관함수를 `impl`블록으로 정의 할 수 있습니다.\n"
" * 열거형 타입의 각 variant를 별도의 구조체로 정의할 수도 있지만, 그러면"
" 열거형을 사용했을 때처럼 하나의 타입으로 취급할 수 없습니다.\n"
"</details>"
#: src/enums/variant-payloads.md:1
msgid "# Variant Payloads"
msgstr "# 데이터를 포함하는 열거형(Variant Payloads)"
#: src/enums/variant-payloads.md:3
msgid ""
"You can define richer enums where the variants carry data. You can then use "
"the\n"
"`match` statement to extract the data from each variant:"
msgstr ""
"좀더 복잡한 열거형의 경우 variant에 데이터(payload)를 포함시키도 합니다."
"각 variant에 담긴 데이터는 `match`문을 이용해 추출합니다."
#: src/enums/variant-payloads.md:6
msgid ""
"```rust,editable\n"
"enum WebEvent {\n"
" PageLoad, // Variant without payload\n"
" KeyPress(char), // Tuple struct variant\n"
" Click { x: i64, y: i64 }, // Full struct variant\n"
"}"
msgstr ""
#: src/enums/variant-payloads.md:13
msgid ""
"#[rustfmt::skip]\n"
"fn inspect(event: WebEvent) {\n"
" match event {\n"
" WebEvent::PageLoad => println!(\"page loaded\"),\n"
" WebEvent::KeyPress(c) => println!(\"pressed '{c}'\"),\n"
" WebEvent::Click { x, y } => println!(\"clicked at x={x}, y={y}\"),\n"
" }\n"
"}"
msgstr ""
#: src/enums/variant-payloads.md:22
msgid ""
"fn main() {\n"
" let load = WebEvent::PageLoad;\n"
" let press = WebEvent::KeyPress('x');\n"
" let click = WebEvent::Click { x: 20, y: 80 };"
msgstr ""
#: src/enums/variant-payloads.md:27
msgid ""
" inspect(load);\n"
" inspect(press);\n"
" inspect(click);\n"
"}\n"
"```"
msgstr ""
#: src/enums/variant-payloads.md:35
msgid ""
"* In the above example, accessing the `char` in `KeyPress`, or `x` and `y` "
"in `Click` only works within a `match` statement.\n"
"* `match` inspects a hidden discriminant field in the `enum`.\n"
"* `WebEvent::Click { ... }` is not exactly the same as `WebEvent::"
"Click(Click)` with a top level `struct Click { ... }`. The inlined version "
"cannot implement traits, for example."
msgstr ""
"* 위의 예제에서 `KeyPress`의 `char`, `Cilck`의 `x`와 `y`의 접근은 `match`구"
"문 안에서만 동작 합니다.\n"
"* `match`는 주어진 열거형 값이 실제로 어떤 variant인지 판단하기 위해, 그 variant의"
" 종류가 기록된, 숨겨진 필드(식별자)의 값을 검사합니다.\n"
"* `WebEvent::Click { ... }`은 최상위 레벨 구조체 `struct Click {...}`를 따로 정의하고"
" `WebEvent::Click(Click)`처럼 튜플 형태로 정의한 것과 정확히 같진 않습니다. 예를 들어"
" `WelbEvent::Click { ... }` 로 정의한 경우, 구조체 형태와 유사하지만 트레이트를 구현 할 수 없습니다."
#: src/enums/sizes.md:1
msgid "# Enum Sizes"
msgstr "# 열거형 타입의 크기"
#: src/enums/sizes.md:3
msgid ""
"Rust enums are packed tightly, taking constraints due to alignment into "
"account:"
msgstr "러스트의 열거형은 정렬(alignment)로 인한 제약을 고려하여 크기를 빽빽하게 잡습니다."
#: src/enums/sizes.md:5
msgid ""
"```rust,editable\n"
"use std::mem::{align_of, size_of};"
msgstr ""
#: src/enums/sizes.md:8
msgid ""
"macro_rules! dbg_size {\n"
" ($t:ty) => {\n"
" println!(\"{}: size {} bytes, align: {} bytes\",\n"
" stringify!($t), size_of::<$t>(), align_of::<$t>());\n"
" };\n"
"}"
msgstr ""
#: src/enums/sizes.md:15
msgid ""
"enum Foo {\n"
" A,\n"
" B,\n"
"}"
msgstr ""
#: src/enums/sizes.md:20
msgid ""
"#[repr(u32)]\n"
"enum Bar {\n"
" A, // 0\n"
" B = 10000,\n"
" C, // 10001\n"
"}"
msgstr ""
#: src/enums/sizes.md:27
msgid ""
"fn main() {\n"
" dbg_size!(Foo);\n"
" dbg_size!(Bar);\n"
" dbg_size!(bool);\n"
" dbg_size!(Option<bool>);\n"
" dbg_size!(&i32);\n"
" dbg_size!(Option<&i32>);\n"
"}\n"
"```"
msgstr ""
#: src/enums/sizes.md:37
msgid ""
"* See the [Rust Reference](https://doc.rust-lang.org/reference/type-layout."
"html)."
msgstr ""
"* 자세한 사항은 [공식문서](https://doc.rust-lang.org/reference/type-layout.html)를 확인하세요."
#: src/enums/sizes.md:39
msgid ""
"<details>\n"
" \n"
"Key Points: \n"
" * Internally Rust is using a field (discriminant) to keep track of the enum "
"variant.\n"
" * `Bar` enum demonstrates that there is a way to control the discriminant "
"value and type. If `repr` is removed, the discriminant type takes 2 bytes, "
"becuase 10001 fits 2 bytes.\n"
" * As a niche optimization an enum discriminant is merged with the pointer "
"so that `Option<&Foo>` is the same size as `&Foo`.\n"
" * `Option<bool>` is another example of tight packing.\n"
" * For [some types](https://doc.rust-lang.org/std/option/#representation), "
"Rust guarantees that `size_of::<T>()` equals `size_of::<Option<T>>()`.\n"
" * Zero-sized types allow for efficient implementation of `HashSet` using "
"`HashMap` with `()` as the value."
msgstr ""
"<details>\n"
" \n"
"키 포인트: \n"
"* 러스트는 내부적으로 열거형의 각 variant를 구분하기 위해 별도의 필드(식별자)를 사용"
"합니다.\n"
"* `Bar` 타입을 보면 식별자의 값을 직접 지정하거나 그 타입을 변경할 수 있음을 알 수 있습니다."
"`repr`을 제거하면 10001을 나타내는데 2바이트가 필요하기 때문에 식별자 타입이 2바이트를 차지합니다.\n"
"* 니치 최적화(niche optimization)로서 열거형(enum)의 식별자는 포인터에 결합됩니다."
"그래서 `Option<&Foo>` 타입은 `&Foo`와 같은 사이즈가 됩니다.\n"
"* `Option<bool>역시 이에 대한 또 다른 예입니다.\n"
"* [일부 타입](https://doc.rust-lang.org/std/option/#representation)의 경우 러"
"스트는 `size_of::<T>()`와 `size_of::<Option<T>>()`가 동일함을 보장합니다. \n"
"* 0크기 타입 덕분에 `HashMap`의 값을 `()`로 지정하는 식으로 `HashSet`을 효율적으로 구현할 수 있습니다."
#: src/methods.md:3
msgid ""
"Rust allows you to associate functions with your new types. You do this with "
"an\n"
"`impl` block:"
msgstr ""
"러스트에서 선언된 타입에 대해 `impl`블록에 함수를 선언하여 메서드를 연결 할 "
"수 있습니다:"
#: src/methods.md:13
msgid ""
"impl Person {\n"
" fn say_hello(&self) {\n"
" println!(\"Hello, my name is {}\", self.name);\n"
" }\n"
"}"
msgstr ""
#: src/methods.md:19
msgid ""
"fn main() {\n"
" let peter = Person {\n"
" name: String::from(\"Peter\"),\n"
" age: 27,\n"
" };\n"
" peter.say_hello();\n"
"}\n"
"```"
msgstr ""
#: src/methods.md:30
msgid ""
"Key Points:\n"
"* It can be helpful to introduce methods by comparing them to functions.\n"
" * Methods are called on an instance of a type (such as a struct or enum), "
"the first parameter represents the instance as `self`.\n"
" * Developers may choose to use methods to take advantage of method "
"receiver syntax and to help keep them more organized. By using methods we "
"can keep all the implementation code in one predictable place.\n"
"* Point out the use of the keyword `self`, a method receiver. \n"
" * Show that it is an abbreviated term for `self:&Self` and perhaps show "
"how the struct name could also be used. \n"
" * Explain that Self is a type alias for the type the `impl` block is in "
"and can be used elsewhere in the block.\n"
" * Note how self is used like other structs and dot notation can be used to "
"refer to individual fields.\n"
" * This might be a good time to demonstrate how the `&self` differs from "
"`self` by modifying the code and trying to run say_hello twice. \n"
"* We describe the distinction between method receivers next.\n"
" \n"
"</details>"
msgstr ""
"키 포인트: \n"
"* 메서드를 함수와 비교하여 소개하는 것도 도움이 될 수 있습니다.\n"
" * 메서드는 구조체나 열거형과 같은 타입의 인스턴스에서 호출 되며, 첫번째 "
"매개변수(파라메터)는 인스턴스를 `self`로 표기합니다.\n"
" * 개발자는 메서드 receiver 문법을 사용하고 더 체계적으로 만들기 위해 메서"
"드를 사용할 수 있습니다. 메서드를 사용하면 구현된 코드를 예측 가능한 곳에 "
"둘 수 있습니다.\n"
"* 메서드 receiver인 `self`키워드 사용을 언급해 주시기 바랍니다.\n"
" * `self`가 `self:&Self`의 줄인 버전임을 알려주시고, 구조체의 이름이 어떻"
"게 사용 될 수 있는지 보여주시기 바랍니다.\n"
" * Self는 `impl`블록이 속한 타입의 별칭이며 블록 어디에서도 사용될 수 있음"
"을 설명합니다.\n"
" * self는 다른 구조체와 마찬가지로 점 표기(self.xx)를 이용하여 개별 필드에 "
"접근 할 수 있습니다./n * 코드를 수정하고 say_hello 함수를 두 번 실행함으로"
"써 `&self`와 `self`가 어떻게 다른지 보여주는 좋은 시간이 될 수 있습니다.* 다"
"음 슬라이드에서 receiver의 구분을 설명합니다. \n"
"</details>"
#: src/methods/receiver.md:1
msgid "# Method Receiver"
msgstr "# 메서드 리시버(Receiver)"
#: src/methods/receiver.md:3
msgid ""
"The `&self` above indicates that the method borrows the object immutably. "
"There\n"
"are other possible receivers for a method:"
msgstr ""
"`&self`는 메서드가 객체를 불변하게 빌려옴을 나타냅니다. 그 외에 메서드가 받아"
"올 수 있는 인자는 다음과 같습니다:"
#: src/methods/receiver.md:6
msgid ""
"* `&self`: borrows the object from the caller using a shared and immutable\n"
" reference. The object can be used again afterwards.\n"
"* `&mut self`: borrows the object from the caller using a unique and "
"mutable\n"
" reference. The object can be used again afterwards.\n"
"* `self`: takes ownership of the object and moves it away from the caller. "
"The\n"
" method becomes the owner of the object. The object will be dropped "
"(deallocated)\n"
" when the method returns, unless its ownership is explicitly\n"
" transmitted.\n"
"* `mut self`: same as above, but while the method owns the object, it can\n"
" mutate it too. Complete ownership does not automatically mean mutability.\n"
"* No receiver: this becomes a static method on the struct. Typically used "
"to\n"
" create constructors which are called `new` by convention."
msgstr ""
"* `&self`: 호출자로부터 불변참조객체를 빌려옴을 나타냅니다. 객체는 나중에 다"
"시 사용 될 수 있습니다.\n"
"* `&mut self`: 호출자로부터 유일한 가변참조객체를 빌려옴을 나타냅니다.객체는 "
"나중에 다시 사용 될 수 있습니다.\n"
"* `self`: 호출자의 객체가 이동되어 메서드가 객체의 소유권을 가져옵니다. 따라"
"서 명시적으로 소유권을 반환하지 않으면 (메서드 종료 후)객체는 삭제(해제)됩니"
"다.\n"
"* `mut self`: 위와 동일하지만 메서드가 소유권을 가지고 있는 동안에도 객체를수"
"정할 수 있습니다. 완전한 소유권이 (자동으로) 변동성을 의미하는 것은 아닙니"
"다.\n"
"* 인자 없음: 구조체의 정적 메서드가 됩니다. 관습적으로 `new`라고 지정되는 생"
"성자를 만들때 사용합니다. "
#: src/methods/receiver.md:19
msgid ""
"Beyond variants on `self`, there are also\n"
"[special wrapper types](https://doc.rust-lang.org/reference/special-types-"
"and-traits.html)\n"
"allowed to be receiver types, such as `Box<Self>`."
msgstr ""
"`self`에 대한 variants 외에도 `Box<Self>`와 같이 리시버 타입으로 허용되는 "
"[special wrapper types](https://doc.rust-lang.org/reference/special-types-"
"and-traits.html)도 있습니다."
#: src/methods/receiver.md:23
msgid ""
"<details>\n"
" \n"
"Consider emphasizing on \"shared and immutable\" and \"unique and mutable\". "
"These constraints always come\n"
"together in Rust due to borrow checker rules, and `self` is no exception. It "
"won't be possible to\n"
"reference a struct from multiple locations and call a mutating (`&mut self`) "
"method on it.\n"
" \n"
"</details>"
msgstr ""
"<details>\n"
" \n"
" \"공유되고 불변한\" 것과 \"유일하고 가변한\" 특성을 강조하시기 바랍니다. 이"
"러한 특성은 러스트의 빌림 검사기(borrow checker) 규착으로 인해 발생하며 "
"`self`도 예외는 아닙니다. 여러 위치에서 구조를 참조하고 수정 (`&mut self`)하"
"는 것은 불가합니다. \n"
"</details>"
#: src/methods/example.md:1 src/concurrency/shared_state/example.md:1
msgid "# Example"
msgstr "# 예제"
#: src/methods/example.md:3
msgid ""
"```rust,editable\n"
"#[derive(Debug)]\n"
"struct Race {\n"
" name: String,\n"
" laps: Vec<i32>,\n"
"}"
msgstr ""
#: src/methods/example.md:10
msgid ""
"impl Race {\n"
" fn new(name: &str) -> Race { // No receiver, a static method\n"
" Race { name: String::from(name), laps: Vec::new() }\n"
" }"
msgstr ""
"impl Race {\n"
" fn new(name: &str) -> Race { // 정적 메서드(static method)는 self가 없"
"습니다.\n"
" Race { name: String::from(name), laps: Vec::new() }\n"
" }"
#: src/methods/example.md:15
msgid ""
" fn add_lap(&mut self, lap: i32) { // Exclusive borrowed read-write "
"access to self\n"
" self.laps.push(lap);\n"
" }"
msgstr ""
" fn add_lap(&mut self, lap: i32) { // self에 대한 배타적인 빌림 읽기-쓰"
"기\n"
" self.laps.push(lap);\n"
" }"
#: src/methods/example.md:19
msgid ""
" fn print_laps(&self) { // Shared and read-only borrowed access to self\n"
" println!(\"Recorded {} laps for {}:\", self.laps.len(), self.name);\n"
" for (idx, lap) in self.laps.iter().enumerate() {\n"
" println!(\"Lap {idx}: {lap} sec\");\n"
" }\n"
" }"
msgstr ""
" fn print_laps(&self) { // self에 대한 읽기 전용 빌림 & 공유 \n"
" println!(\"Recorded {} laps for {}:\", self.laps.len(), self.name);\n"
" for (idx, lap) in self.laps.iter().enumerate() {\n"
" println!(\"Lap {idx}: {lap} sec\");\n"
" }\n"
" }"
#: src/methods/example.md:26
msgid ""
" fn finish(self) { // Exclusive ownership of self\n"
" let total = self.laps.iter().sum::<i32>();\n"
" println!(\"Race {} is finished, total lap time: {}\", self.name, "
"total);\n"
" }\n"
"}"
msgstr ""
" fn finish(self) { // 배타적 self 소유권\n"
" let total = self.laps.iter().sum::<i32>();\n"
" println!(\"Race {} is finished, total lap time: {}\", self.name, "
"total);\n"
" }\n"
"}"
#: src/methods/example.md:32
msgid ""
"fn main() {\n"
" let mut race = Race::new(\"Monaco Grand Prix\");\n"
" race.add_lap(70);\n"
" race.add_lap(68);\n"
" race.print_laps();\n"
" race.add_lap(71);\n"
" race.print_laps();\n"
" race.finish();\n"
" // race.add_lap(42);\n"
"}\n"
"```"
msgstr ""
#: src/methods/example.md:44
msgid ""
"<details>\n"
" \n"
"Key Points:\n"
"* All four methods here use a different method receiver.\n"
" * You can point out how that changes what the function can do with the "
"variable values and if/how it can be used again in `main`.\n"
" * You can showcase the error that appears when trying to call `finish` "
"twice.\n"
"* Note, that although the method receivers are different, the non-static "
"functions are called the same way in the main body. Rust enables automatic "
"referencing and dereferencing when calling methods. Rust automatically adds "
"in the `&`, `*`, `muts` so that that object matches the method signature.\n"
"* You might point out that `print_laps` is using a vector that is iterated "
"over. We describe vectors in more detail in the afternoon. "
msgstr ""
"<details>\n"
" \n"
"키 포인트:\n"
"* 4가지의 메서드 receiver에 대해 설명합니다.\n"
" * 변수 값을 사용하여 함수가 수행할 수 있는 작업을 변경하는 것과 `main`에"
"서 다시 사용하는지 여부를 지정할 수 있습니다.\n"
" * `finish`를 두번 호출하여 오류가 발생하는 것을 보일 수 있습니다.\n"
" * 비록 메서드 receiver는 다르지만 main 함수에서 비 정적 함수를 부르는 방법"
"은 같습니다. 러스트는 메서드를 호출할 때 자동으로 참조/역참조(따라가기)를 수"
"행합니다. 러스트는 매서드 시그니처의 객체를 매칭할 때 `&`, `*`, `muts`를 자"
"동으로 일치시킵니다.\n"
" * `print_laps`함수가 반복되는 벡터를 사용합을 지적할 수 있습니다. 오후 강"
"의에서 벡터에 대해 더 자세히 설명할 것입니다."
#: src/pattern-matching.md:1
msgid "# Pattern Matching"
msgstr "# 패턴 매칭"
#: src/pattern-matching.md:3
msgid ""
"The `match` keyword let you match a value against one or more _patterns_. "
"The\n"
"comparisons are done from top to bottom and the first match wins."
msgstr ""
"`match`키워드는 C/C++의 `switch`와 유사하게 하나 이상의 패턴과 일치 시킬 수 "
"있습니다."
#: src/pattern-matching.md:6
msgid "The patterns can be simple values, similarly to `switch` in C and C++:"
msgstr "비교동작은 위에서 아래로 진행되며 처음 일치하는 패턴이 실행됩니다. "
#: src/pattern-matching.md:8
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let input = 'x';"
msgstr ""
#: src/pattern-matching.md:12
msgid ""
" match input {\n"
" 'q' => println!(\"Quitting\"),\n"
" 'a' | 's' | 'w' | 'd' => println!(\"Moving around\"),\n"
" '0'..='9' => println!(\"Number input\"),\n"
" _ => println!(\"Something else\"),\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/pattern-matching.md:21
msgid "The `_` pattern is a wildcard pattern which matches any value."
msgstr "`_`패턴은 어떤 패턴과도 매칭되는 와일드 카드입니다.(default)"
#: src/pattern-matching.md:23
msgid ""
"<details>\n"
" \n"
"Key Points:\n"
"* You might point out how some specific characters are being used when in a "
"patten\n"
" * `|` as an `or`\n"
" * `..` can expand as much as it needs to be\n"
" * `1..=5` represents an inclusive range\n"
" * `_` is a wild card\n"
"* It can be useful to show how binding works, by for instance replacing a "
"wildcard character with a variable, or removing the quotes around `q`.\n"
"* You can demonstrate matching on a reference.\n"
"* This might be a good time to bring up the concept of irrefutable patterns, "
"as the term can show up in error messages.\n"
" \n"
"</details>"
msgstr ""
"<details>\n"
" \n"
"키 포인트:\n"
"* 패턴에서 사용되는 특수 문자들입니다: * `|`: 또는(or) 기호입니다.\n"
" * `..`: 필요한 만큼 확장합니다.(나머지)\n"
" * `1..=5`: range를 나타냅니다.(1~5)\n"
" * `_`: 는 switch 문의 `default`처럼 와일드 카드 입니다.\n"
"* 와일드카드 문자를 변수로 바꾸거나 `q`의 따옴표를 제거하는 식의 수정으로바인"
"딩이 어떻게 작동하는지 보여주는 것도 유용할 수 있습니다.\n"
"* 참조에서도 매칭을 시연할 수 있습니다.\n"
"* 에러메시지에 종종 이러한 용어가 나타날 수 있어서 패턴의 개념을 정확히 알 필"
"요가 있습니다.\n"
" \n"
"</details>"
#: src/pattern-matching/destructuring-enums.md:1
msgid "# Destructuring Enums"
msgstr "# 열거형 분해(역구조화)"
#: src/pattern-matching/destructuring-enums.md:3
msgid ""
"Patterns can also be used to bind variables to parts of your values. This is "
"how\n"
"you inspect the structure of your types. Let us start with a simple `enum` "
"type:"
msgstr ""
"구조체의 바인딩된 값을 패턴으로 사용할 수 있습니다. 간단한 `enum` 타입의 예시"
"입니다:"
#: src/pattern-matching/destructuring-enums.md:6
msgid ""
"```rust,editable\n"
"enum Result {\n"
" Ok(i32),\n"
" Err(String),\n"
"}"
msgstr ""
#: src/pattern-matching/destructuring-enums.md:12
msgid ""
"fn divide_in_two(n: i32) -> Result {\n"
" if n % 2 == 0 {\n"
" Result::Ok(n / 2)\n"
" } else {\n"
" Result::Err(format!(\"cannot divide {} into two equal parts\", n))\n"
" }\n"
"}"
msgstr ""
#: src/pattern-matching/destructuring-enums.md:20
msgid ""
"fn main() {\n"
" let n = 100;\n"
" match divide_in_two(n) {\n"
" Result::Ok(half) => println!(\"{n} divided in two is {half}\"),\n"
" Result::Err(msg) => println!(\"sorry, an error happened: {msg}\"),\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/pattern-matching/destructuring-enums.md:29
msgid ""
"Here we have used the arms to _destructure_ the `Result` value. In the "
"first\n"
"arm, `half` is bound to the value inside the `Ok` variant. In the second "
"arm,\n"
"`msg` is bound to the error message."
msgstr ""
"위의 `match`구문을 `divide_in_two`함수에서 반환되는 `Result` 값을 arm(패턴 "
"단위)으로 분해합니다. \n"
"* 첫번째 arm의 `half`는 `Ok` variant에 바인딩된 값입니다.`(n/2)`\n"
"* 두번째 amr의 `msg`는 `Err` variant에 바인딩 된 에러 메시지 입니다."
#: src/pattern-matching/destructuring-enums.md:35
msgid ""
"Key points:\n"
"* The `if`/`else` expression is returning an enum that is later unpacked "
"with a `match`.\n"
"* You can try adding a third variant to the enum definition and displaying "
"the errors when running the code. Point out the places where your code is "
"now inexhaustive and how the compiler trys to give you hints."
msgstr ""
"키 포인트:\n"
"* `if`/`else` 표현식은 이후 `match`에 사용할 수 있는 열거형을 반환합니다.\n"
"* 열거형에 세번째 variant를 추가하고 코드를 실행하여 오류를 표시 할 수 있습니"
"다.컴파일러가 오류를 친절히 설명하기 위해 노력하고 있음을 이야기 해 주시기 바"
"랍니다."
#: src/pattern-matching/destructuring-structs.md:1
msgid "# Destructuring Structs"
msgstr "# 구조체 분해(역구조화)"
#: src/pattern-matching/destructuring-structs.md:3
msgid "You can also destructure `structs`:"
msgstr "`구조체`역시 분해할 수 있습니다:"
#: src/pattern-matching/destructuring-structs.md:5
msgid ""
"```rust,editable\n"
"struct Foo {\n"
" x: (u32, u32),\n"
" y: u32,\n"
"}"
msgstr ""
#: src/pattern-matching/destructuring-structs.md:11
msgid ""
"#[rustfmt::skip]\n"
"fn main() {\n"
" let foo = Foo { x: (1, 2), y: 3 };\n"
" match foo {\n"
" Foo { x: (1, b), y } => println!(\"x.0 = 1, b = {b}, y = {y}\"),\n"
" Foo { y: 2, x: i } => println!(\"y = 2, i = {i:?}\"),\n"
" Foo { y, .. } => println!(\"y = {y}, other fields were "
"ignored\"),\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/pattern-matching/destructuring-arrays.md:1
msgid "# Destructuring Arrays"
msgstr "# 배열 분해(역구조화)"
#: src/pattern-matching/destructuring-arrays.md:3
msgid ""
"You can destructure arrays, tuples, and slices by matching on their elements:"
msgstr "배역 역시 분해가 가능하고, 슬라이스를 적용할 수 있습니다."
#: src/pattern-matching/destructuring-arrays.md:5
msgid ""
"```rust,editable\n"
"#[rustfmt::skip]\n"
"fn main() {\n"
" let triple = [0, -2, 3];\n"
" println!(\"Tell me about {triple:?}\");\n"
" match triple {\n"
" [0, y, z] => println!(\"First is 0, y = {y}, and z = {z}\"),\n"
" [1, ..] => println!(\"First is 1 and the rest were ignored\"),\n"
" _ => println!(\"All elements were ignored\"),\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/pattern-matching/match-guards.md:1
msgid "# Match Guards"
msgstr "# 검사식(Match Guards)"
#: src/pattern-matching/match-guards.md:3
msgid ""
"When matching, you can add a _guard_ to a pattern. This is an arbitrary "
"Boolean\n"
"expression which will be executed if the pattern matches:"
msgstr ""
"match를 사용할때 각 패턴에 대해서 불리언으로 반환되는 검사식(guard)를 추가할 "
"수 있습니다. "
#: src/pattern-matching/match-guards.md:6
msgid ""
"```rust,editable\n"
"#[rustfmt::skip]\n"
"fn main() {\n"
" let pair = (2, -2);\n"
" println!(\"Tell me about {pair:?}\");\n"
" match pair {\n"
" (x, y) if x == y => println!(\"These are twins\"),\n"
" (x, y) if x + y == 0 => println!(\"Antimatter, kaboom!\"),\n"
" (x, _) if x % 2 == 1 => println!(\"The first one is odd\"),\n"
" _ => println!(\"No correlation...\"),\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/pattern-matching/match-guards.md:22
msgid ""
"Key Points:\n"
"* Match guards as a separate syntax feature are important and necessary.\n"
"* They are not the same as separate `if` expression inside of the match arm. "
"An `if` expression inside of the branch block (after `=>`) happens after the "
"match arm is selected. Failing the `if` condition inside of that block won't "
"result in other arms\n"
"of the original `match` expression being considered. \n"
"* You can use the variables defined in the pattern in your if expression.\n"
"* The condition defined in the guard applies to every expression in a "
"pattern with an `|`.\n"
"</details>"
msgstr ""
"키 포인트: \n"
"* 검사식은 별도의 문법으로서도 중요하고 필요합니다."
"* 검사식은 (보기와 달리) 단지 match arm 내부의 분리된 'if' 표현식이 아닙니다."
" match arm 이 선택된 후 `=>`이후의 `if` 표현식이 발생합니다. 따라서 if 조건이"
" 실패하면 (match는 성공했으므로) 다른 arm은 고려되지 않습니다.\n"
"* 패턴에 정의된 변수를 if 표현식에 사용할 수 있습니다.\n"
"* 검사식에 정의된 조건은 `|`(or) 가 있는 패턴의 모든 표현식에 적용됩니다.\n"
"</details>"
#: src/exercises/day-2/morning.md:1
msgid "# Day 2: Morning Exercises"
msgstr "# 2일차 오전 연습문제"
#: src/exercises/day-2/morning.md:3
msgid "We will look at implementing methods in two contexts:"
msgstr "이번 연습문제들은 두가지 맥락에서 메서드 구현방법을 다룹니다:"
#: src/exercises/day-2/morning.md:5
msgid "* Simple struct which tracks health statistics."
msgstr "* 건강 상태 통계를 추적하는 프로그램의 간단한 구조체."
#: src/exercises/day-2/morning.md:7
msgid "* Multiple structs and enums for a drawing library."
msgstr "* 드로잉 라이브러리를 위한 다중 구조체 및 열거헝."
#: src/exercises/day-2/health-statistics.md:1
msgid "# Health Statistics"
msgstr ""
"# 건강상태 모니터링 시스템\n"
"당신은 건강 상태를 모니터링하는 시스템을 구현하는 일을 하고 있습니다.\n"
" 그 일환으로 당신은 사용자의 건강 상태 통계를 추적해야합니다. \n"
"당신의 목표는 User구조체의 impl블록의 빈 함수를 구현하는 것입니다. \n"
"* _gettext 이슈로 아래 문구 교체가 안되 병기됨_"
#: src/exercises/day-2/health-statistics.md:3
msgid ""
"You're working on implementing a health-monitoring system. As part of that, "
"you\n"
"need to keep track of users' health statistics."
msgstr ""
"당신은 건강 상태를 모니터링하는 시스템을 구현하는 일을 하고 있습니다.\n"
"그 일환으로 당신은 사용자의 건강 상태 통계를 추적해야합니다."
#: src/exercises/day-2/health-statistics.md:6
msgid ""
"You'll start with some stubbed functions in an `impl` block as well as a "
"`User`\n"
"struct definition. Your goal is to implement the stubbed out methods on the\n"
"`User` `struct` defined in the `impl` block."
msgstr "당신의 목표는 User구조체의 impl블록의 빈 함수를 구현하는 것입니다."
#: src/exercises/day-2/health-statistics.md:10
msgid ""
"Copy the code below to <https://play.rust-lang.org/> and fill in the "
"missing\n"
"methods:"
msgstr ""
"아래 코드를 <https://play.rust-lang.org/>에 복사해서 빠진 메서드를 구현하면 "
"됩니다: "
#: src/exercises/day-2/health-statistics.md:17
msgid ""
"struct User {\n"
" name: String,\n"
" age: u32,\n"
" weight: f32,\n"
"}"
msgstr ""
#: src/exercises/day-2/health-statistics.md:23
msgid ""
"impl User {\n"
" pub fn new(name: String, age: u32, weight: f32) -> Self {\n"
" unimplemented!()\n"
" }"
msgstr ""
#: src/exercises/day-2/health-statistics.md:28
msgid ""
" pub fn name(&self) -> &str {\n"
" unimplemented!()\n"
" }"
msgstr ""
#: src/exercises/day-2/health-statistics.md:32
msgid ""
" pub fn age(&self) -> u32 {\n"
" unimplemented!()\n"
" }"
msgstr ""
#: src/exercises/day-2/health-statistics.md:36
msgid ""
" pub fn weight(&self) -> f32 {\n"
" unimplemented!()\n"
" }"
msgstr ""
#: src/exercises/day-2/health-statistics.md:40
msgid ""
" pub fn set_age(&mut self, new_age: u32) {\n"
" unimplemented!()\n"
" }"
msgstr ""
#: src/exercises/day-2/health-statistics.md:44
msgid ""
" pub fn set_weight(&mut self, new_weight: f32) {\n"
" unimplemented!()\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-2/health-statistics.md:49
msgid ""
"fn main() {\n"
" let bob = User::new(String::from(\"Bob\"), 32, 155.2);\n"
" println!(\"I'm {} and my age is {}\", bob.name(), bob.age());\n"
"}"
msgstr ""
#: src/exercises/day-2/health-statistics.md:54
msgid ""
"#[test]\n"
"fn test_weight() {\n"
" let bob = User::new(String::from(\"Bob\"), 32, 155.2);\n"
" assert_eq!(bob.weight(), 155.2);\n"
"}"
msgstr ""
#: src/exercises/day-2/health-statistics.md:60
msgid ""
"#[test]\n"
"fn test_set_age() {\n"
" let mut bob = User::new(String::from(\"Bob\"), 32, 155.2);\n"
" assert_eq!(bob.age(), 32);\n"
" bob.set_age(33);\n"
" assert_eq!(bob.age(), 33);\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-2/points-polygons.md:1
msgid "# Polygon Struct"
msgstr "# 다각형 구조"
#: src/exercises/day-2/points-polygons.md:3
msgid ""
"We will create a `Polygon` struct which contain some points. Copy the code "
"below\n"
"to <https://play.rust-lang.org/> and fill in the missing methods to make "
"the\n"
"tests pass:"
msgstr ""
"우리는 몇개의 꼭지점을 가진 다각형을 표현하는 구조체를 만들 것입니다. \n"
"아래 코드를 <https://play.rust-lang.org/>에 복사해서 테스트가 통과하도록 빠"
"진 메서드를 구현하시면 됩니다: "
#: src/exercises/day-2/points-polygons.md:7 src/exercises/day-2/luhn.md:23
#: src/exercises/day-2/strings-iterators.md:12
msgid ""
"```rust\n"
"// TODO: remove this when you're done with your implementation.\n"
"#![allow(unused_variables, dead_code)]"
msgstr ""
#: src/exercises/day-2/points-polygons.md:11
msgid ""
"pub struct Point {\n"
" // add fields\n"
"}"
msgstr ""
#: src/exercises/day-2/points-polygons.md:15
msgid ""
"impl Point {\n"
" // add methods\n"
"}"
msgstr ""
#: src/exercises/day-2/points-polygons.md:19
msgid ""
"pub struct Polygon {\n"
" // add fields\n"
"}"
msgstr ""
#: src/exercises/day-2/points-polygons.md:23
msgid ""
"impl Polygon {\n"
" // add methods\n"
"}"
msgstr ""
#: src/exercises/day-2/points-polygons.md:27
msgid ""
"pub struct Circle {\n"
" // add fields\n"
"}"
msgstr ""
#: src/exercises/day-2/points-polygons.md:31
msgid ""
"impl Circle {\n"
" // add methods\n"
"}"
msgstr ""
#: src/exercises/day-2/points-polygons.md:35
msgid ""
"pub enum Shape {\n"
" Polygon(Polygon),\n"
" Circle(Circle),\n"
"}"
msgstr ""
#: src/exercises/day-2/points-polygons.md:40 src/testing/test-modules.md:15
msgid ""
"#[cfg(test)]\n"
"mod tests {\n"
" use super::*;"
msgstr ""
#: src/exercises/day-2/points-polygons.md:44
#: src/exercises/day-2/solutions-morning.md:165
msgid ""
" fn round_two_digits(x: f64) -> f64 {\n"
" (x * 100.0).round() / 100.0\n"
" }"
msgstr ""
#: src/exercises/day-2/points-polygons.md:48
#: src/exercises/day-2/solutions-morning.md:169
msgid ""
" #[test]\n"
" fn test_point_magnitude() {\n"
" let p1 = Point::new(12, 13);\n"
" assert_eq!(round_two_digits(p1.magnitude()), 17.69);\n"
" }"
msgstr ""
#: src/exercises/day-2/points-polygons.md:54
#: src/exercises/day-2/solutions-morning.md:175
msgid ""
" #[test]\n"
" fn test_point_dist() {\n"
" let p1 = Point::new(10, 10);\n"
" let p2 = Point::new(14, 13);\n"
" assert_eq!(round_two_digits(p1.dist(p2)), 5.00);\n"
" }"
msgstr ""
#: src/exercises/day-2/points-polygons.md:61
#: src/exercises/day-2/solutions-morning.md:182
msgid ""
" #[test]\n"
" fn test_point_add() {\n"
" let p1 = Point::new(16, 16);\n"
" let p2 = p1 + Point::new(-4, 3);\n"
" assert_eq!(p2, Point::new(12, 19));\n"
" }"
msgstr ""
#: src/exercises/day-2/points-polygons.md:68
#: src/exercises/day-2/solutions-morning.md:189
msgid ""
" #[test]\n"
" fn test_polygon_left_most_point() {\n"
" let p1 = Point::new(12, 13);\n"
" let p2 = Point::new(16, 16);"
msgstr ""
#: src/exercises/day-2/points-polygons.md:73
#: src/exercises/day-2/solutions-morning.md:194
msgid ""
" let mut poly = Polygon::new();\n"
" poly.add_point(p1);\n"
" poly.add_point(p2);\n"
" assert_eq!(poly.left_most_point(), Some(p1));\n"
" }"
msgstr ""
#: src/exercises/day-2/points-polygons.md:79
#: src/exercises/day-2/solutions-morning.md:200
msgid ""
" #[test]\n"
" fn test_polygon_iter() {\n"
" let p1 = Point::new(12, 13);\n"
" let p2 = Point::new(16, 16);"
msgstr ""
#: src/exercises/day-2/points-polygons.md:84
#: src/exercises/day-2/solutions-morning.md:205
msgid ""
" let mut poly = Polygon::new();\n"
" poly.add_point(p1);\n"
" poly.add_point(p2);"
msgstr ""
#: src/exercises/day-2/points-polygons.md:88
#: src/exercises/day-2/solutions-morning.md:209
msgid ""
" let points = poly.iter().cloned().collect::<Vec<_>>();\n"
" assert_eq!(points, vec![Point::new(12, 13), Point::new(16, 16)]);\n"
" }"
msgstr ""
#: src/exercises/day-2/points-polygons.md:92
msgid ""
" #[test]\n"
" fn test_shape_perimeters() {\n"
" let mut poly = Polygon::new();\n"
" poly.add_point(Point::new(12, 13));\n"
" poly.add_point(Point::new(17, 11));\n"
" poly.add_point(Point::new(16, 16));\n"
" let shapes = vec![\n"
" Shape::from(poly),\n"
" Shape::from(Circle::new(Point::new(10, 20), 5)),\n"
" ];\n"
" let perimeters = shapes\n"
" .iter()\n"
" .map(Shape::perimeter)\n"
" .map(round_two_digits)\n"
" .collect::<Vec<_>>();\n"
" assert_eq!(perimeters, vec![15.48, 31.42]);\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-2/points-polygons.md:111 src/exercises/day-2/luhn.md:68
#: src/exercises/day-2/solutions-morning.md:233
msgid ""
"#[allow(dead_code)]\n"
"fn main() {}\n"
"```"
msgstr ""
#: src/exercises/day-2/points-polygons.md:117
msgid ""
"Since the method signatures are missing from the problem statements, the key "
"part\n"
"of the exercise is to specify those correctly."
msgstr ""
"위 문제의 일부 누락된 메서드 시그니처를 고치는 것이 문제의 핵심 부분입니다."
#: src/exercises/day-2/points-polygons.md:120
msgid ""
"Other interesting parts of the exercise:\n"
" \n"
"* Derive a `Copy` trait for some structs, as in tests the methods sometimes "
"don't borrow their arguments.\n"
"* Discover that `Add` trait must be implemented for two objects to be "
"addable via \"+\". "
msgstr ""
"연습문제의 다른 흥미로운 부분:\n"
" \n"
"* 테스트 메서드가 때때로 인수를 빌리지 않는 것처럼 일부 구조체에 `Copy`"
"트레이트를 사용합니다.\n"
"* \"+\"를 사용할 수 있도록 두 객체에 대해 `Add` 트레이트를 구현해야 합니다."
#: src/control-flow.md:1
msgid "# Control Flow"
msgstr "# 흐름 제어"
#: src/control-flow.md:3
msgid ""
"As we have seen, `if` is an expression in Rust. It is used to conditionally\n"
"evaluate one of two blocks, but the blocks can have a value which then "
"becomes\n"
"the value of the `if` expression. Other control flow expressions work "
"similarly\n"
"in Rust."
msgstr ""
"앞에서 살펴본 바와 같이 러스트의 표현식으로써 `if`는 두 블록 중 하나를 조건"
"에 따라 평가(반환)하며, 블록은 `if` 표현식의 값이 되는 값을 가질 수 있습니"
"다. 다른 흐름제어 표현식도 러스트에서 유사하게 작동합니다. "
#: src/control-flow/blocks.md:1
msgid "# Blocks"
msgstr "# 블록"
#: src/control-flow/blocks.md:3
msgid ""
"A block in Rust has a value and a type: the value is the last expression of "
"the\n"
"block:"
msgstr "러스트에서 블록은 값과 타입을 갖습니다: 블록의 표현식이 값이 됩니다."
#: src/control-flow/blocks.md:6
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let x = {\n"
" let y = 10;\n"
" println!(\"y: {y}\");\n"
" let z = {\n"
" let w = {\n"
" 3 + 4\n"
" };\n"
" println!(\"w: {w}\");\n"
" y * w\n"
" };\n"
" println!(\"z: {z}\");\n"
" z - y\n"
" };\n"
" println!(\"x: {x}\");\n"
"}\n"
"```"
msgstr ""
#: src/control-flow/blocks.md:25
msgid ""
"The same rule is used for functions: the value of the function body is the\n"
"return value:"
msgstr ""
"함수에도 동일한 규칙이 적용됩니다: 함수 바디의 (마지막) 값이 반환 값이 됩니"
"다."
#: src/control-flow/blocks.md:28
msgid ""
"```rust,editable\n"
"fn double(x: i32) -> i32 {\n"
" x + x\n"
"}"
msgstr ""
#: src/control-flow/blocks.md:33
msgid ""
"fn main() {\n"
" println!(\"doubled: {}\", double(7));\n"
"}\n"
"```"
msgstr ""
#: src/control-flow/blocks.md:38
msgid ""
"However if the last expression ends with `;`, then the resulting value and "
"type is `()`."
msgstr ""
"(위 코드에서 main함수의 경우) 마지막 표현식이 `;`로 끝나기 때문에 반환되는 값"
"과 타입은 `()`입니다."
#: src/control-flow/if-expressions.md:1
msgid "# `if` expressions"
msgstr "# `if` 표현식"
#: src/control-flow/if-expressions.md:3
msgid "You use `if` very similarly to how you would in other languages:"
msgstr "`if`문은 다른 언어와 동일하게 사용할수 있습니다(조건의 ()는 없습니다):"
#: src/control-flow/if-expressions.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let mut x = 10;\n"
" if x % 2 == 0 {\n"
" x = x / 2;\n"
" } else {\n"
" x = 3 * x + 1;\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/control-flow/if-expressions.md:16
msgid ""
"In addition, you can use it as an expression. This does the same as above:"
msgstr ""
"게다가 `if`는 표현식(할당가능)으로 사용 될수도 있습니다.\n"
"아래 코드는 위와 동일한 결과 입니다."
#: src/control-flow/if-expressions.md:18
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let mut x = 10;\n"
" x = if x % 2 == 0 {\n"
" x / 2\n"
" } else {\n"
" 3 * x + 1\n"
" };\n"
"}\n"
"```"
msgstr ""
#: src/control-flow/if-expressions.md:31
msgid ""
"Because `if` is an expression and must have a particular type, both of its "
"branch blocks must have the same type. Consider showing what happens if you "
"add `;` after `x / 2` in the second example.\n"
" \n"
"</details>"
msgstr ""
"`if`는 표현식이고 특정 유형을 가져야 하므로 분기 블록은 모두 같은 타입을 가져"
"야 합니다.두번째 예시의 `x / 2` 뒤에 `;`를 추가하여 어떻게 되는지 확인해 보시"
"기 바랍니다. \n"
"</details>"
#: src/control-flow/if-let-expressions.md:1
msgid "# `if let` expressions"
msgstr "# `if let` 표현식"
#: src/control-flow/if-let-expressions.md:3
msgid "If you want to match a value against a pattern, you can use `if let`:"
msgstr "`if let`문을 사용하면 값을 패턴매칭에 사용할 수 있습니다:"
#: src/control-flow/if-let-expressions.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let arg = std::env::args().next();\n"
" if let Some(value) = arg {\n"
" println!(\"Program name: {value}\");\n"
" } else {\n"
" println!(\"Missing name?\");\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/control-flow/if-let-expressions.md:16
#: src/control-flow/while-let-expressions.md:21
#: src/control-flow/match-expressions.md:22
msgid ""
"See [pattern matching](../pattern-matching.md) for more details on patterns "
"in\n"
"Rust."
msgstr "러스트의 [패턴매칭](../pattern-matching.md)을 참조하세요"
#: src/control-flow/if-let-expressions.md:21
msgid ""
"* `if let` can be more concise than `match`, e.g., when only one case is "
"interesting. In contrast, `match` requires all branches to be covered.\n"
" * For the similar use case consider demonstrating a newly stabilized "
"[`let else`](https://github.com/rust-lang/rust/pull/93628) feature.\n"
"* A common usage is handling `Some` values when working with `Option`.\n"
"* Unlike `match`, `if let` does not support guard clauses for pattern "
"matching."
msgstr ""
"* `if let`은 `match`보다 더 간결할 수 있습니다. 예를 들어 특정한 경우만 고려"
"하고 싶더라도 `match`는 모든 분기를 포함해야 합니다.\n"
" * 비슷한 사용례로 새롭게 \"stable\" 릴리즈 된 [`let else`](https://github."
"com/rust-lang/rust/pull/93628) 기능을 시연하는 것도 고려해 보시기 바랍니다.\n"
"* 일반적으로 `Option`으로 작업할 때 `Some` 값을 처리하는 식으로 사용됩니다.\n"
"* `match`와 다르게 `if let` 은 패턴매칭을 위한 검사식(guard)를 지원하지 않습"
"니다."
#: src/control-flow/while-expressions.md:1
msgid "# `while` expressions"
msgstr "# `while` 표현식"
#: src/control-flow/while-expressions.md:3
msgid "The `while` keyword works very similar to other languages:"
msgstr "`while` 역시 다른 언어와 동일한 사용법을 갖습니다:"
#: src/control-flow/while-expressions.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let mut x = 10;\n"
" while x != 1 {\n"
" x = if x % 2 == 0 {\n"
" x / 2\n"
" } else {\n"
" 3 * x + 1\n"
" };\n"
" }\n"
" println!(\"Final x: {x}\");\n"
"}\n"
"```"
msgstr ""
#: src/control-flow/while-let-expressions.md:1
msgid "# `while let` expressions"
msgstr "# `while let` 표현식"
#: src/control-flow/while-let-expressions.md:3
msgid ""
"Like with `if`, there is a `while let` variant which repeatedly tests a "
"value\n"
"against a pattern:"
msgstr "`if`와 동일하게 `while let`구문 역시 패턴매칭에 사용 할 수 있습니다."
#: src/control-flow/while-let-expressions.md:6
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let v = vec![10, 20, 30];\n"
" let mut iter = v.into_iter();"
msgstr ""
#: src/control-flow/while-let-expressions.md:11
msgid ""
" while let Some(x) = iter.next() {\n"
" println!(\"x: {x}\");\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/control-flow/while-let-expressions.md:17
msgid ""
"Here the iterator returned by `v.iter()` will return a `Option<i32>` on "
"every\n"
"call to `next()`. It returns `Some(x)` until it is done, after which it "
"will\n"
"return `None`. The `while let` lets us keep iterating through all items."
msgstr ""
"`v.iter()`가 반환한 반복자는 `next()`가 호출될 때마다 `Option<i32>`를 반환합"
"니다.\n"
"이는 `None`이 호출되기 전까지 `Some(x)`를 반환한다는 의미로 결과적으로 "
"`while let`은 반복자의 모든 아이템을 반복하도록 하게 해줍니다."
#: src/control-flow/for-expressions.md:1
msgid "# `for` expressions"
msgstr "# `for` 표현식"
#: src/control-flow/for-expressions.md:3
msgid ""
"The `for` expression is closely related to the `while let` expression. It "
"will\n"
"automatically call `into_iter()` on the expression and then iterate over it:"
msgstr ""
"`for`표현식은 `while let` 표현식과 매우 유사합니다. `for`표현식은 자동으로 "
"`into_iter()`를 호출한 다음 이를 반복합니다."
#: src/control-flow/for-expressions.md:6
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let v = vec![10, 20, 30];"
msgstr ""
#: src/control-flow/for-expressions.md:10
msgid ""
" for x in v {\n"
" println!(\"x: {x}\");\n"
" }\n"
" \n"
" for i in (0..10).step_by(2) {\n"
" println!(\"i: {i}\");\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/control-flow/for-expressions.md:20
msgid "You can use `break` and `continue` here as usual."
msgstr "역시 다른언어와 마찬가지로 `break` 와 `continue`를 사용할 수 있습니다."
#: src/control-flow/for-expressions.md:22
msgid ""
"<details>\n"
" \n"
"* Index iteration is not a special syntax in Rust for just that case.\n"
"* `(0..10)` is a range that implements an `Iterator` trait. \n"
"* `step_by` is a method that returns another `Iterator` that skips every "
"other element. \n"
" \n"
"</details>"
msgstr ""
"<details>\n"
" \n"
"* 인덱스 반복의 경우는 러스트의 특별한 방식은 아닙니다. \n"
"* `(0..10)`은 `Iterator` 트레이트를 구현하는 range 입니다. \n"
"* `step_by`는 다른 요소들을 건너뛰는 또다른 `Iterator`의 메서드입니다.\n"
" \n"
"</details>"
#: src/control-flow/loop-expressions.md:1
msgid "# `loop` expressions"
msgstr "# `loop` 표현식"
#: src/control-flow/loop-expressions.md:3
msgid ""
"Finally, there is a `loop` keyword which creates an endless loop. Here you "
"must\n"
"either `break` or `return` to stop the loop:"
msgstr ""
"마지막으로 `loop`키워드는 무한한 루프를 생성합니다. 따라서 반드시 `break` 또"
"는 `return`를 사용해서 루프를 정지해야 합니다:"
#: src/control-flow/loop-expressions.md:6
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let mut x = 10;\n"
" loop {\n"
" x = if x % 2 == 0 {\n"
" x / 2\n"
" } else {\n"
" 3 * x + 1\n"
" };\n"
" if x == 1 {\n"
" break;\n"
" }\n"
" }\n"
" println!(\"Final x: {x}\");\n"
"}\n"
"```"
msgstr ""
#: src/control-flow/match-expressions.md:1
msgid "# `match` expressions"
msgstr "# `match` 표현식"
#: src/control-flow/match-expressions.md:3
msgid ""
"The `match` keyword is used to match a value against one or more patterns. "
"In\n"
"that sense, it works like a series of `if let` expressions:"
msgstr ""
"마치 `if let`를 여러개 적용한 것과 같이 `match`키워드는 하나 이상의 패턴을 찾"
"는데 사용됩니다."
#: src/control-flow/match-expressions.md:6
msgid ""
"```rust,editable\n"
"fn main() {\n"
" match std::env::args().next().as_deref() {\n"
" Some(\"cat\") => println!(\"Will do cat things\"),\n"
" Some(\"ls\") => println!(\"Will ls some files\"),\n"
" Some(\"mv\") => println!(\"Let's move some files\"),\n"
" Some(\"rm\") => println!(\"Uh, dangerous!\"),\n"
" None => println!(\"Hmm, no program name?\"),\n"
" _ => println!(\"Unknown program name!\"),\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/control-flow/match-expressions.md:19
msgid ""
"Like `if let`, each match arm must have the same type. The type is the last\n"
"expression of the block, if any. In the example above, the type is `()`."
msgstr ""
"`if let`처럼 각 매치 암(match arm)의 마지막 표현식이 타입이 되며 모든 암은 동"
"일한 타입이어야 합니다. 위의 예제에서 타입은 `()`(반환값 없음)입니다.\n"
"* _역주: 예시에서 각 arm의 리턴 타입은 리턴없음(`()`)"
#: src/control-flow/break-continue.md:1
msgid "# `break` and `continue`"
msgstr "# `break`와 `continue`"
#: src/control-flow/break-continue.md:3
msgid ""
"If you want to exit a loop early, use `break`, if you want to immediately "
"start\n"
"the next iteration use `continue`. Both `continue` and `break` can "
"optionally\n"
"take a label argument which is used to break out of nested loops:"
msgstr ""
"만약 루프를 중간에 멈추고 십다면 `break`를, 바로 다음 반복으로 넘어가기 위해"
"서는 `continue`를 사용합니다. 두 키워드 모두 중첩 루프에서 label로 표기한 인"
"수를 취하여 제어 할 수 있습니다."
#: src/control-flow/break-continue.md:7
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let v = vec![10, 20, 30];\n"
" let mut iter = v.into_iter();\n"
" 'outer: while let Some(x) = iter.next() {\n"
" println!(\"x: {x}\");\n"
" let mut i = 0;\n"
" while i < x {\n"
" println!(\"x: {x}, i: {i}\");\n"
" i += 1;\n"
" if i == 3 {\n"
" break 'outer;\n"
" }\n"
" }\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/control-flow/break-continue.md:25
msgid ""
"In this case we break the outer loop after 3 iterations of the inner loop."
msgstr ""
"위 예제는 중접루프를 3회 반복한 후 바깥루프('outer' 레이블)을 정지합니다.(종"
"료)"
#: src/std.md:1
msgid "# Standard Library"
msgstr "# 표준 라이브러리"
#: src/std.md:3
msgid ""
"Rust comes with a standard library which helps establish a set of common "
"types\n"
"used by Rust library and programs. This way, two libraries can work "
"together\n"
"smoothly because they both use the same `String` type."
msgstr ""
"러스트는 러스트 라이브러리와 프로그램에서 사용되는 공통 타입을 설정하는 데 도"
"움을 주는 표준 라이브러리와 함께 제공 됩니다. 이렇게 하면 두 라이브러리 모두 "
"같은 `String` 타입을 사용하기 때문에 원활하게 함께 작동할 수 있습니다."
#: src/std.md:7
msgid "The common vocabulary types include:"
msgstr "일반적인 타입은 아래와 같습니다:"
#: src/std.md:9
msgid ""
"* [`Option` and `Result`](std/option-result.md) types: used for optional "
"values\n"
" and [error handling](error-handling.md)."
msgstr ""
"* [Option and Result 타입](std/option-result.md) : 선택적 옵션 값과 [error "
"handling](error-handling.md)에 사용됩니다."
#: src/std.md:12
msgid ""
"* [`String`](std/string.md): the default string type used for owned data."
msgstr ""
"* [`String`](std/string.md): 소유 데이터에서 사용되는 기본적인 문자열 타입"
"입니다."
#: src/std.md:14
msgid "* [`Vec`](std/vec.md): a standard extensible vector."
msgstr "* [`Vec`](std/vec.md): 확장가능한 표준 벡터 타입입니다."
#: src/std.md:16
msgid ""
"* [`HashMap`](std/hashmap.md): a hash map type with a configurable hashing\n"
" algorithm."
msgstr ""
"* [`HashMap`](std/hashmap.md): 구성 가능한 해시 알고리즘을 가지는 해쉬 맵 "
"타입입니다"
#: src/std.md:19
msgid "* [`Box`](std/box.md): an owned pointer for heap-allocated data."
msgstr "* [`Box`](std/box.md): 힙 데이터에 대한 소유 포인터입니다:"
#: src/std.md:21
msgid ""
"* [`Rc`](std/rc.md): a shared reference-counted pointer for heap-allocated "
"data."
msgstr ""
"* [`Rc`](std/rc.md): 힙에 할당된 데이터에 대한 참조 카운팅 공유 포인터입니"
#: src/std.md:23
msgid ""
"<details>\n"
" \n"
" * In fact, Rust contains several layers of the Standard Library: `core`, "
"`alloc` and `std`. \n"
" * `core` includes the most basic types and functions that don't depend on "
"`libc`, allocator or\n"
" even the presence of an operating system. \n"
" * `alloc` includes types which require a global heap allocator, such as "
"`Vec`, `Box` and `Arc`.\n"
" * Embedded Rust applications often only use `core`, and sometimes `alloc`."
msgstr ""
"<details>\n"
" \n"
" * 사실, 러스트의 표준라이브러리는 여러 계층(layer)를 포함합니다: `core`, "
"`alloc`, `std`. \n"
" * `core`는 `libc`, 할당자(allocator), 심지어 os에도 의존하지 않는 가장 기"
"본적인 함수와 타입을 포함합니다.\n"
" * `alloc`은 `Vec`, `Box`, `Arc`와 같이 전역 힙 할당이 필요한 타입을 포함합"
"니다.\n"
" * 임베디드 러스트 응용프로그램은 종종 `core`만 사용하고 때로는 `alloc`도 사"
"용합니다."
#: src/std/string.md:1
msgid "# String"
msgstr "# String"
#: src/std/string.md:3
msgid ""
"[`String`][1] is the standard heap-allocated growable UTF-8 string buffer:"
msgstr "[`String`][1]은 힙에 할당된 확장가능한 표준 UTF-8 문자열 버퍼입니다."
#: src/std/string.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let mut s1 = String::new();\n"
" s1.push_str(\"Hello\");\n"
" println!(\"s1: len = {}, capacity = {}\", s1.len(), s1.capacity());"
msgstr ""
#: src/std/string.md:11
msgid ""
" let mut s2 = String::with_capacity(s1.len() + 1);\n"
" s2.push_str(&s1);\n"
" s2.push('!');\n"
" println!(\"s2: len = {}, capacity = {}\", s2.len(), s2.capacity());"
msgstr ""
#: src/std/string.md:16
msgid ""
" let s3 = String::from(\"🇨🇭\");\n"
" println!(\"s3: len = {}, number of chars = {}\", s3.len(),\n"
" s3.chars().count());\n"
"}\n"
"```"
msgstr ""
#: src/std/string.md:22
msgid ""
"`String` implements [`Deref<Target = str>`][2], which means that you can "
"call all\n"
"`str` methods on a `String`."
msgstr ""
"`String`은 [`Deref<Target = str>`][2]을 구현합니다.\n"
"이는 , `String`에서 모든 `str`관련 메서드를 호출 할 수 있다는 의미 입니다."
#: src/std/string.md:25
msgid ""
"[1]: https://doc.rust-lang.org/std/string/struct.String.html\n"
"[2]: https://doc.rust-lang.org/std/string/struct.String.html#deref-methods-"
"str"
msgstr ""
#: src/std/string.md:30
msgid ""
"* `len` returns the size of the `String` in bytes, not its length in "
"characters.\n"
"* `chars` returns an iterator over the actual characters.\n"
"* `String` implements `Deref<Target = str>` which transparently gives it "
"access to `str`'s methods."
msgstr ""
"* `len`은 `String`의 글자 길이가 아닌 바이트 사이즈를 반환합니다.\n"
"* `chars`은 실제 문자들에 대한 반복자를 반환합니다.\n"
"* `String`은 `Deref<Target = str>`의 구현으로 `str`의 메서드에 투명하게 액세"
"스 할 수 있습니다."
#: src/std/option-result.md:1
msgid "# `Option` and `Result`"
msgstr "# `Option`과 `Result`"
#: src/std/option-result.md:3
msgid "The types represent optional data:"
msgstr "이 타입은 선택가능한 데이터를 표시합니다: "
#: src/std/option-result.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let numbers = vec![10, 20, 30];\n"
" let first: Option<&i8> = numbers.first();\n"
" println!(\"first: {first:?}\");"
msgstr ""
#: src/std/option-result.md:11
msgid ""
" let idx: Result<usize, usize> = numbers.binary_search(&10);\n"
" println!(\"idx: {idx:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/std/option-result.md:18
msgid ""
"* `Option` and `Result` are widely used not just in the standard library.\n"
"* `Option<&T>` has zero space overhead compared to `&T`.\n"
"* `Result` is the standard type to implement error handling as we will see "
"on Day 3.\n"
"* `binary_search` returns `Result<usize, usize>`.\n"
" * If found, `Result::Ok` holds the index where the element is found.\n"
" * Otherwise, `Result::Err` contains the index where such an element should "
"be inserted."
msgstr ""
"* `Option`와 `Result`는 표준 라이브러리에서만 널리 사용되는 것이 아닙니다.\n"
"* `Option<&T>` 는 `&T`에 비해 공간 오버헤드가 없습니다.\n"
"* `Result` 3일차에 다루겠지만, 표준 오류 처리를 구현하기 위한 표준 유형입니"
"다.\n"
"* `binary_search`는 `Result<usize, usize>`를 반환합니다.\n"
" * 요소가 발견된다면, `Result::Ok`는 발견된 요소의 인덱스를 보유합니다.\n"
" * 아니면, `Result::Err`에는 요소가 삽입되야 하는 인덱스가 포함되어 있습니"
"다.(보통은 마지막 인덱스 입니다)"
#: src/std/vec.md:1
msgid "# `Vec`"
msgstr "# `Vec`"
#: src/std/vec.md:3
msgid "[`Vec`][1] is the standard resizable heap-allocated buffer:"
msgstr "[`Vec`][1] 는 힙에 할당된 표준 가변크기 버퍼입니다."
#: src/std/vec.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let mut v1 = Vec::new();\n"
" v1.push(42);\n"
" println!(\"v1: len = {}, capacity = {}\", v1.len(), v1.capacity());"
msgstr ""
#: src/std/vec.md:11
msgid ""
" let mut v2 = Vec::with_capacity(v1.len() + 1);\n"
" v2.extend(v1.iter());\n"
" v2.push(9999);\n"
" println!(\"v2: len = {}, capacity = {}\", v2.len(), v2.capacity());\n"
" \n"
" let mut numbers = vec![1, 2, 3];\n"
" numbers.push(42);\n"
"}\n"
"```"
msgstr ""
#: src/std/vec.md:21
msgid ""
"`Vec` implements [`Deref<Target = [T]>`][2], which means that you can call "
"slice\n"
"methods on a `Vec`."
msgstr ""
"`Vec`은 [`Deref<Target = [T]>`][2]를 구현합니다. \n"
"이는 `Vec`에서 슬라이스 메서드(배열 관련 메서드)를 호출 할 수 있다는 의미입니"
"다."
#: src/std/vec.md:24
msgid ""
"[1]: https://doc.rust-lang.org/std/vec/struct.Vec.html\n"
"[2]: https://doc.rust-lang.org/std/vec/struct.Vec.html#deref-methods-[T]"
msgstr ""
#: src/std/vec.md:27
msgid ""
"<details>\n"
" \n"
"Notice how `Vec<T>` is a generic type too, but you don't have to specify `T` "
"explicitly.\n"
"As always with Rust type inference, the `T` was established during the first "
"`push` call."
msgstr ""
"<details>\n"
" \n"
"`Vec<T>` 역시 제너릭 타입임을 주목하시기 바랍니다. 하지만 러스트는 첫 `push`"
"를 통해 타입을 추론할 수 있으므로 `T`를 항상 명시할 필요는 없습니다."
#: src/std/vec.md:32
msgid ""
"`vec![...]` is a canonical macro to use instead of `Vec::new()` and it "
"supports\n"
"adding initial elements to the vector."
msgstr ""
"`vec![...]`는 표준 매크로로 `Vec::new()`를 대체하고, 벡터에 추가 초기요소를 "
"추가할 수 있습니다."
#: src/std/hashmap.md:1
msgid "# `HashMap`"
msgstr "# `HashMap`"
#: src/std/hashmap.md:3
msgid "Standard hash map with protection against HashDoS attacks:"
msgstr ""
"HashDoS[^역주1] 공격으로부터 보호되는 표준 해시 맵입니다.\n"
"* _역주: HashDoS: Hash table을 사용하는 웹서버에 파라미터가 많은 POST를 호"
"출하여 Hash table 충돌을 유도하여 CPU 부하를 발생시키는 공격 방법."
#: src/std/hashmap.md:5
msgid ""
"```rust,editable\n"
"use std::collections::HashMap;"
msgstr ""
#: src/std/hashmap.md:8
msgid ""
"fn main() {\n"
" let mut page_counts = HashMap::new();\n"
" page_counts.insert(\"Adventures of Huckleberry Finn\".to_string(), "
"207);\n"
" page_counts.insert(\"Grimms' Fairy Tales\".to_string(), 751);\n"
" page_counts.insert(\"Pride and Prejudice\".to_string(), 303);"
msgstr ""
#: src/std/hashmap.md:14
msgid ""
" if !page_counts.contains_key(\"Les Misérables\") {\n"
" println!(\"We've know about {} books, but not Les Misérables.\",\n"
" page_counts.len());\n"
" }"
msgstr ""
#: src/std/hashmap.md:19
msgid ""
" for book in [\"Pride and Prejudice\", \"Alice's Adventure in "
"Wonderland\"] {\n"
" match page_counts.get(book) {\n"
" Some(count) => println!(\"{book}: {count} pages\"),\n"
" None => println!(\"{book} is unknown.\")\n"
" }\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/std/box.md:1
msgid "# `Box`"
msgstr "# `Box`"
#: src/std/box.md:3
msgid "[`Box`][1] is an owned pointer to data on the heap:"
msgstr "[`Box`][1]는 힙 데이터에 대한 소유 포인터입니다:"
#: src/std/box.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let five = Box::new(5);\n"
" println!(\"five: {}\", *five);\n"
"}\n"
"```"
msgstr ""
#: src/std/box.md:13
msgid ""
"```bob\n"
" Stack Heap\n"
".- - - - - - -. .- - - - - - -.\n"
": : : :\n"
": five : : :\n"
": +-----+ : : +-----+ :\n"
": | o---|---+-----+-->| 5 | :\n"
": +-----+ : : +-----+ :\n"
": : : :\n"
": : : :\n"
"`- - - - - - -' `- - - - - - -'\n"
"```"
msgstr ""
#: src/std/box.md:26
msgid ""
"`Box<T>` implements `Deref<Target = T>`, which means that you can [call "
"methods\n"
"from `T` directly on a `Box<T>`][2]."
msgstr ""
"`Box<T>`은 [`Deref<Target = T>`][2]를 구현합니다. \n"
"이는 [`Box<T>`에서 T 관련 메서드를 직접 호출][2] 할 수 있다는 의미입니다."
#: src/std/box.md:29
msgid ""
"[1]: https://doc.rust-lang.org/std/boxed/struct.Box.html\n"
"[2]: https://doc.rust-lang.org/std/ops/trait.Deref.html#more-on-deref-"
"coercion"
msgstr ""
#: src/std/box.md:34
msgid ""
"* `Box` is like `std::unique_ptr` in C++.\n"
"* In the above example, you can even leave out the `*` in the `println!` "
"statement thanks to `Deref`."
msgstr ""
"* `Box`는 C++의 `std::unique_ptr`와 유사합니다.\n"
"* 위의 예제에서 `Deref` 덕분에 `println!`구문에서 `*`를 생략할 수 도 있습니"
"다."
#: src/std/box-recursive.md:1
msgid "# Box with Recursive Data Structures"
msgstr "# 재귀자료 구조에서의 `Box`"
#: src/std/box-recursive.md:3
msgid ""
"Recursive data types or data types with dynamic sizes need to use a `Box`:"
msgstr "재귀 데이터나 동적크기의 데이터 타입은 `Box`타입을 사용해야 합니다."
#: src/std/box-recursive.md:5 src/std/box-niche.md:3
msgid ""
"```rust,editable\n"
"#[derive(Debug)]\n"
"enum List<T> {\n"
" Cons(T, Box<List<T>>),\n"
" Nil,\n"
"}"
msgstr ""
#: src/std/box-recursive.md:12 src/std/box-niche.md:10
msgid ""
"fn main() {\n"
" let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::"
"new(List::Nil))));\n"
" println!(\"{list:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/std/box-recursive.md:18
msgid ""
"```bob\n"
" Stack Heap\n"
".- - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - - - - "
"- -.\n"
": : : :\n"
": "
"list : : :\n"
": +--------+-------+ : : +--------+--------+ +--------+------"
"+ :\n"
": | Tag | Cons | : : .->| Tag | Cons | .->| Tag | Nil "
"| :\n"
": | 0 | 1 | : : | | 0 | 2 | | | ////// | //// "
"| :\n"
": | 1 | o-----+----+-----+-' | 1 | o------+-' | ////// | //// "
"| :\n"
": +--------+-------+ : : +--------+--------+ +--------+------"
"+ :\n"
": : : :\n"
": : : :\n"
"`- - - - - - - - - - - - -' '- - - - - - - - - - - - - - - - - - - - - - "
"- -'\n"
"```"
msgstr ""
#: src/std/box-recursive.md:33
msgid ""
"<details>\n"
" \n"
"If the `Box` was not used here and we attempted to embed a `List` directly "
"into the `List`,\n"
"the compiler would not compute a fixed size of the struct in memory, it "
"would look infinite.\n"
" \n"
"`Box` solves this problem as it has the same size as a regular pointer and "
"just points at the next\n"
"element of the `List` in the heap. \n"
" \n"
"</details>"
msgstr ""
"<details>\n"
" \n"
"만일 `Box`를 사용하지 않고 `List`에 직접 `List`를 포함하려고 시도한다면, 컴파"
"일러는 메모리에 있는 구조체의 고정 크기를 계산하지 않으므로 무한대로 갈 것입"
"니다.\n"
" \n"
"`Box`는 일반 포인터와 크기가 같고 힙에 있는 `List`의 다음 요소만 가리키기 때"
"문에 이러한 문제가 없습니다. \n"
" \n"
"</details>"
#: src/std/box-niche.md:1
msgid "# Niche Optimization"
msgstr "# 니치(틈새) 최적화(Niche Optimization)"
#: src/std/box-niche.md:16
msgid ""
"A `Box` cannot be empty, so the pointer is always valid and non-`null`. "
"This\n"
"allows the compiler to optimize the memory layout:"
msgstr ""
"`Box`는 비어있을 수 없습니다. 따라서 포인터는 항상 유효하고 `null`이 아닙니"
"다.\n"
"이는 컴파일러가 메모리 레이아웃을 최적화 할 수 있게 해줍니다."
#: src/std/box-niche.md:19
msgid ""
"```bob\n"
" Stack Heap\n"
".- - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - - - - "
"- -.\n"
": : : :\n"
": "
"list : : :\n"
": +--------+-------+ : : +--------+--------+ +--------+------"
"+ :\n"
": | 0 | 1 | : : .->| 0 | 2 | .->| ////// | //// "
"| :\n"
": | \"1/Tag\"| o-----+----+-----+-' | \"1/Tag\"| o-----+-' | \"1/Tag\"| "
"null | :\n"
": +--------+-------+ : : +--------+--------+ +--------+------"
"+ :\n"
": : : :\n"
": : : :\n"
"`- - - - - - - - - - - - -' '- - - - - - - - - - - - - - - - - - - - - - "
"- -'\n"
"```"
msgstr ""
#: src/std/rc.md:1
msgid "# `Rc`"
msgstr "# `Rc`"
#: src/std/rc.md:3
msgid ""
"[`Rc`][1] is a reference-counted shared pointer. Use this when you need to "
"refer\n"
"to the same data from multiple places:"
msgstr ""
"[`Rc`][1]는 참조 카운팅 공유 포인터입니다. \n"
"여러 위치의 동일한 데이터를 참조해야할 경우 사용합니다:"
#: src/std/rc.md:6
msgid ""
"```rust,editable\n"
"use std::rc::Rc;"
msgstr ""
#: src/std/rc.md:9
msgid ""
"fn main() {\n"
" let mut a = Rc::new(10);\n"
" let mut b = a.clone();"
msgstr ""
#: src/std/rc.md:18
msgid ""
"If you need to mutate the data inside an `Rc`, you will need to wrap the "
"data in\n"
"a type such as [`Cell` or `RefCell`][2]. See [`Arc`][3] if you are in a "
"multi-threaded\n"
"context."
msgstr ""
"`Rc`내부의 데이터를 변경해야 하는 경우, 데이터를 [`Cell` 또는 `RefCell`][2]"
"로 래핑해야합니다.\n"
"멀티스레드인 경우 [`Arc`][3]를 참조하시기 바랍니다."
#: src/std/rc.md:22
msgid ""
"[1]: https://doc.rust-lang.org/std/rc/struct.Rc.html\n"
"[2]: https://doc.rust-lang.org/std/cell/index.html\n"
"[3]: ../concurrency/shared_state/arc.md"
msgstr ""
#: src/std/rc.md:28
msgid ""
"* Like C++'s `std::shared_ptr`.\n"
"* `clone` is cheap: creates a pointer to the same allocation and increases "
"the reference count.\n"
"* `make_mut` actually clones the inner value if necessary (\"clone-on-"
"write\") and returns a mutable reference."
msgstr ""
"* C++의 `std::shared_ptr`와 유사합니다.\n"
"* `clone`은 저렴합니다: 동일한 할당에 대한 포인터를 생성하고 참조 카운트를 늘"
"림니다.\n"
"* `make_mut`는 실제로 필요한 경우에 내부 값을 복제하고( (\"clone-on-"
"write\") ) 가변 참조를 반환합니다."
#: src/modules.md:1
msgid "# Modules"
msgstr "# 모듈"
#: src/modules.md:3
msgid "We have seen how `impl` blocks let us namespace functions to a type."
msgstr "`impl`블록은 네임스페이스함수를 타입으로 제공합니다."
#: src/modules.md:5
msgid "Similarly, `mod` lets us namespace types and functions:"
msgstr "`mod` 역시 네임스페이스 타입과 함수를 제공합니다: "
#: src/modules.md:7
msgid ""
"```rust,editable\n"
"mod foo {\n"
" pub fn do_something() {\n"
" println!(\"In the foo module\");\n"
" }\n"
"}"
msgstr ""
#: src/modules.md:14
msgid ""
"mod bar {\n"
" pub fn do_something() {\n"
" println!(\"In the bar module\");\n"
" }\n"
"}"
msgstr ""
#: src/modules.md:20
msgid ""
"fn main() {\n"
" foo::do_something();\n"
" bar::do_something();\n"
"}\n"
"```"
msgstr ""
#: src/modules/visibility.md:1
msgid "# Visibility"
msgstr "# 접근자(Visibility)"
#: src/modules/visibility.md:3
msgid "Modules are a privacy boundary:"
msgstr "모듈의 기본 접근자는 private 입니다:"
#: src/modules/visibility.md:5
msgid ""
"* Module items are private by default (hides implementation details).\n"
"* Parent and sibling items are always visible."
msgstr ""
"* 모듈의 항목은 기본적으로 private 입니다.(구현에서 숨겨짐)\n"
"* 부모와 이웃 항목에서는 접근 가능합니다."
#: src/modules/visibility.md:8
msgid ""
"```rust,editable\n"
"mod outer {\n"
" fn private() {\n"
" println!(\"outer::private\");\n"
" }"
msgstr ""
#: src/modules/visibility.md:14
msgid ""
" pub fn public() {\n"
" println!(\"outer::public\");\n"
" }"
msgstr ""
#: src/modules/visibility.md:18
msgid ""
" mod inner {\n"
" fn private() {\n"
" println!(\"outer::inner::private\");\n"
" }"
msgstr ""
#: src/modules/visibility.md:23
msgid ""
" pub fn public() {\n"
" println!(\"outer::inner::public\");\n"
" super::private();\n"
" }\n"
" }\n"
"}"
msgstr ""
#: src/modules/visibility.md:30
msgid ""
"fn main() {\n"
" outer::public();\n"
"}\n"
"```"
msgstr ""
#: src/modules/paths.md:1
msgid "# Paths"
msgstr "# 경로"
#: src/modules/paths.md:3
msgid "Paths are resolved as follows:"
msgstr "경로는 아래와 같이 구분합니다:"
#: src/modules/paths.md:5
msgid ""
"1. As a relative path:\n"
" * `foo` or `self::foo` refers to `foo` in the current module,\n"
" * `super::foo` refers to `foo` in the parent module."
msgstr ""
"1. 상대경로\n"
" * `foo` 또는 `self::foo`는 `foo`모듈 안에서 현재 모듈을 가리킵니다.\n"
" * `super::foo`는 `foo`모듈의 부모 모듈을 가리킵니다."
#: src/modules/paths.md:9
msgid ""
"2. As an absolute path:\n"
" * `crate::foo` refers to `foo` in the root of the current crate,\n"
" * `bar::foo` refers to `foo` in the `bar` crate."
msgstr ""
"2. 절대 경로\n"
" * `crate::foo`는 현재 크레이트 루트의 있는 `foo`를 가리킵니다.\n"
" * `bar::foo`는 `bar`크레이트 안에 있는 `foo`를 가리킵니다."
#: src/modules/filesystem.md:1
msgid "# Filesystem Hierarchy"
msgstr "# 파일시스템 계층"
#: src/modules/filesystem.md:3
msgid "The module content can be omitted:"
msgstr "모듈의 내용은 생략될 수 있습니다:"
#: src/modules/filesystem.md:5
msgid ""
"```rust,editable,compile_fail\n"
"mod garden;\n"
"```"
msgstr ""
#: src/modules/filesystem.md:9
msgid "The `garden` module content is found at:"
msgstr "`garden` 모듈의 내용은 아래 위치에서 확인 할 수 있습니다."
#: src/modules/filesystem.md:11
msgid ""
"* `src/garden.rs` (modern Rust 2018 style)\n"
"* `src/garden/mod.rs` (older Rust 2015 style)"
msgstr ""
#: src/modules/filesystem.md:14
msgid "Similarly, a `garden::vegetables` module can be found at:"
msgstr "유사하게 `garden::vegetables` 모듈은 아래 위치에서 확인할 수 있습니다."
#: src/modules/filesystem.md:16
msgid ""
"* `src/garden/vegetables.rs` (modern Rust 2018 style)\n"
"* `src/garden/vegetables/mod.rs` (older Rust 2015 style)"
msgstr ""
#: src/modules/filesystem.md:19
msgid "The `crate` root is in:"
msgstr "`crate(크레이트)`의 루트는 아래 경로 입니다:"
#: src/modules/filesystem.md:21
msgid ""
"* `src/lib.rs` (for a library crate)\n"
"* `src/main.rs` (for a binary crate)"
msgstr ""
#: src/exercises/day-2/afternoon.md:1
msgid "# Day 2: Afternoon Exercises"
msgstr "# 2일차 오후 연습문제"
#: src/exercises/day-2/afternoon.md:3
msgid "The exercises for this afternoon will focus on strings and iterators."
msgstr "이번 연습문제는 문자열과 반복자에 초점을 맞출 것입니다."
#: src/exercises/day-2/luhn.md:1
msgid "# Luhn Algorithm"
msgstr "# 룬 알고리즘"
#: src/exercises/day-2/luhn.md:3
msgid ""
"The [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm) is used "
"to\n"
"validate credit card numbers. The algorithm takes a string as input and does "
"the\n"
"following to validate the credit card number:"
msgstr ""
"[룬 알고리즘](https://ko.wikipedia.org/wiki/"
"%EB%A3%AC_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98)은 신용카드 번호 검증에 사용되"
"는 알고리즘 입니다. \n"
"이 알고리즘은 신용카드 번호를 `문자열`로 입력받고, 아래의 순서에 따라 신용카"
"드 번호의 유효성을 확인합니다:"
#: src/exercises/day-2/luhn.md:7
msgid "* Ignore all spaces. Reject number with less than two digits."
msgstr "* 모든 공백을 무시합니다, 2자리 미만 숫자는 무시합니다."
#: src/exercises/day-2/luhn.md:9
msgid ""
"* Moving from right to left, double every second digit: for the number "
"`1234`,\n"
" we double `3` and `1`."
msgstr ""
"* 오른쪽에서 왼쪽으로 이동하며 2번째 자리마다 숫자를 2배 증가시킵니다. 1234"
"에서 3과 1을 두배로 만듭니다.(2464)"
#: src/exercises/day-2/luhn.md:12
msgid ""
"* After doubling a digit, sum the digits. So doubling `7` becomes `14` "
"which\n"
" becomes `5`."
msgstr ""
"* 두배로 만든 숫자가 2자리가 넘으면 각 자리를 더합니다: 7의 두배는 14이므로 5"
"가 됩니다."
#: src/exercises/day-2/luhn.md:15
msgid "* Sum all the undoubled and doubled digits."
msgstr "* 모든 자리의 숫자를 합합니다."
#: src/exercises/day-2/luhn.md:17
msgid "* The credit card number is valid if the sum ends with `0`."
msgstr "* 합계의 끝자리가 `0`인 경우 유효한 신용카드 번호 입니다."
#: src/exercises/day-2/luhn.md:19
msgid ""
"Copy the following code to <https://play.rust-lang.org/> and implement the\n"
"function:"
msgstr ""
"아래 코드를 <https://play.rust-lang.org/>에 복사하고 함수를 구현해 보시기 바"
"랍니다."
#: src/exercises/day-2/luhn.md:27
msgid ""
"pub fn luhn(cc_number: &str) -> bool {\n"
" unimplemented!()\n"
"}"
msgstr ""
#: src/exercises/day-2/luhn.md:31
msgid ""
"#[test]\n"
"fn test_non_digit_cc_number() {\n"
" assert!(!luhn(\"foo\"));\n"
"}"
msgstr ""
#: src/exercises/day-2/luhn.md:36 src/exercises/day-2/solutions-afternoon.md:64
msgid ""
"#[test]\n"
"fn test_empty_cc_number() {\n"
" assert!(!luhn(\"\"));\n"
" assert!(!luhn(\" \"));\n"
" assert!(!luhn(\" \"));\n"
" assert!(!luhn(\" \"));\n"
"}"
msgstr ""
#: src/exercises/day-2/luhn.md:44 src/exercises/day-2/solutions-afternoon.md:72
msgid ""
"#[test]\n"
"fn test_single_digit_cc_number() {\n"
" assert!(!luhn(\"0\"));\n"
"}"
msgstr ""
#: src/exercises/day-2/luhn.md:49 src/exercises/day-2/solutions-afternoon.md:77
msgid ""
"#[test]\n"
"fn test_two_digit_cc_number() {\n"
" assert!(luhn(\" 0 0 \"));\n"
"}"
msgstr ""
#: src/exercises/day-2/luhn.md:54 src/exercises/day-2/solutions-afternoon.md:82
msgid ""
"#[test]\n"
"fn test_valid_cc_number() {\n"
" assert!(luhn(\"4263 9826 4026 9299\"));\n"
" assert!(luhn(\"4539 3195 0343 6467\"));\n"
" assert!(luhn(\"7992 7398 713\"));\n"
"}"
msgstr ""
#: src/exercises/day-2/luhn.md:61
msgid ""
"#[test]\n"
"fn test_invalid_cc_number() {\n"
" assert!(!luhn(\"4223 9826 4026 9299\"));\n"
" assert!(!luhn(\"4539 3195 0343 6476\"));\n"
" assert!(!luhn(\"8273 1232 7352 0569\"));\n"
"}"
msgstr ""
#: src/exercises/day-2/strings-iterators.md:1
msgid "# Strings and Iterators"
msgstr "# 문자열과 반복자"
#: src/exercises/day-2/strings-iterators.md:3
msgid ""
"In this exercise, you are implementing a routing component of a web server. "
"The\n"
"server is configured with a number of _path prefixes_ which are matched "
"against\n"
"_request paths_. The path prefixes can contain a wildcard character which\n"
"matches a full segment. See the unit tests below."
msgstr ""
"이번 훈련은 웹 서버의 라우팅 컴포넌트를 구현합니다. \n"
"서버는 _요청경로(request path)와_ 일치하는 여러개의 _경로 접두사(path "
"prefixes)로_ 구성되어 있습니다. 경로 접두사에는 와일드카드문자를 포함할 수 있"
"습니다. 아래 테스트 코드를 참조하세요"
#: src/exercises/day-2/strings-iterators.md:8
msgid ""
"Copy the following code to <https://play.rust-lang.org/> and make the tests\n"
"pass. Try avoiding allocating a `Vec` for your intermediate results:"
msgstr ""
"아래 코드를 <https://play.rust-lang.org/>에 복사하고 테스트를 통과해 보시기 "
"바랍니다. 중간 결과값을 `Vec`에 할당하지 않도록 주의 하시기 바랍니다."
#: src/exercises/day-2/strings-iterators.md:16
msgid ""
"pub fn prefix_matches(prefix: &str, request_path: &str) -> bool {\n"
" unimplemented!()\n"
"}"
msgstr ""
#: src/exercises/day-2/strings-iterators.md:20
msgid ""
"#[test]\n"
"fn test_matches_without_wildcard() {\n"
" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers\"));\n"
" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/"
"abc-123\"));\n"
" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/abc/"
"books\"));"
msgstr ""
#: src/exercises/day-2/strings-iterators.md:26
#: src/exercises/day-2/solutions-afternoon.md:146
msgid ""
" assert!(!prefix_matches(\"/v1/publishers\", \"/v1\"));\n"
" assert!(!prefix_matches(\"/v1/publishers\", \"/v1/publishersBooks\"));\n"
" assert!(!prefix_matches(\"/v1/publishers\", \"/v1/parent/"
"publishers\"));\n"
"}"
msgstr ""
#: src/exercises/day-2/strings-iterators.md:31
#: src/exercises/day-2/solutions-afternoon.md:151
msgid ""
"#[test]\n"
"fn test_matches_with_wildcard() {\n"
" assert!(prefix_matches(\n"
" \"/v1/publishers/*/books\",\n"
" \"/v1/publishers/foo/books\"\n"
" ));\n"
" assert!(prefix_matches(\n"
" \"/v1/publishers/*/books\",\n"
" \"/v1/publishers/bar/books\"\n"
" ));\n"
" assert!(prefix_matches(\n"
" \"/v1/publishers/*/books\",\n"
" \"/v1/publishers/foo/books/book1\"\n"
" ));"
msgstr ""
#: src/exercises/day-2/strings-iterators.md:46
msgid ""
" assert!(!prefix_matches(\"/v1/publishers/*/books\", \"/v1/"
"publishers\"));\n"
" assert!(!prefix_matches(\n"
" \"/v1/publishers/*/books\",\n"
" \"/v1/publishers/foo/booksByAuthor\"\n"
" ));\n"
"}\n"
"```"
msgstr ""
#: src/welcome-day-3.md:1
msgid "# Welcome to Day 3"
msgstr "# 3일차 개요"
#: src/welcome-day-3.md:3
msgid "Today, we will cover some more advanced topics of Rust:"
msgstr "오늘은 러스트의 몇가지 고급 주제를 다룹니다:"
#: src/welcome-day-3.md:5
msgid ""
"* Traits: deriving traits, default methods, and important standard library\n"
" traits."
msgstr ""
"* 트레이트: 트레이트 파생(derive), 기본 메서드, 주요 표준라이브러리 트레이트"
#: src/welcome-day-3.md:8
msgid ""
"* Generics: generic data types, generic methods, monomorphization, and "
"trait\n"
" objects."
msgstr ""
"* 제너릭: 제너릭 데이터 타입, 제너릭 메서드, 단형화(monomorphization), 그리"
"고 트레이트 객체"
#: src/welcome-day-3.md:11
msgid "* Error handling: panics, `Result`, and the try operator `?`."
msgstr "* 오류처리(에러 핸들링): 패닉, Result, ?연산자(시행 연산자)"
#: src/welcome-day-3.md:13
msgid "* Testing: unit tests, documentation tests, and integration tests."
msgstr "* 테스트: 단위 테스트, 문서 테스트 및 통합 테스트"
#: src/welcome-day-3.md:15
msgid ""
"* Unsafe Rust: raw pointers, static variables, unsafe functions, and extern\n"
" functions."
msgstr ""
"* 안전하지 않은 러스트: 원시(raw) 포인터, 정적 변수, 안전하지 않은 함수, 외"
"부 함수"
#: src/traits.md:1
msgid "# Traits"
msgstr "# 트레이트(Trait)"
#: src/traits.md:3
msgid ""
"Rust lets you abstract over types with traits. They're similar to interfaces:"
msgstr ""
"러스트는 인터페이스 처럼 트레이트가 있는 타입을 추상화 할 수 있습니다: "
#: src/traits.md:5
msgid ""
"```rust,editable\n"
"trait Greet {\n"
" fn say_hello(&self);\n"
"}"
msgstr ""
#: src/traits.md:10
msgid ""
"struct Dog {\n"
" name: String,\n"
"}"
msgstr ""
#: src/traits.md:14
msgid "struct Cat; // No name, cats won't respond to it anyway."
msgstr ""
"struct Cat; // 이름속성이 없습니다. 고양이는 어쨌든 반응하지 않습니다:)"
#: src/traits.md:16
msgid ""
"impl Greet for Dog {\n"
" fn say_hello(&self) {\n"
" println!(\"Wuf, my name is {}!\", self.name);\n"
" }\n"
"}"
msgstr ""
#: src/traits.md:22
msgid ""
"impl Greet for Cat {\n"
" fn say_hello(&self) {\n"
" println!(\"Miau!\");\n"
" }\n"
"}"
msgstr ""
#: src/traits.md:28
msgid ""
"fn main() {\n"
" let pets: Vec<Box<dyn Greet>> = vec![\n"
" Box::new(Dog { name: String::from(\"Fido\") }),\n"
" Box::new(Cat),\n"
" ];\n"
" for pet in pets {\n"
" pet.say_hello();\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/traits.md:41
msgid ""
"* Traits may specify pre-implemented (default) methods and methods that "
"users are required to implement themselves. Methods with default "
"implementations can rely on required methods.\n"
"* Types that implement a given trait may be of different sizes. This makes "
"it impossible to have things like `Vec<Greet>` in the example above.\n"
"* `dyn Greet` is a way to tell the compiler about a dynamically sized type "
"that implements `Greet`.\n"
"* In the example, `pets` holds Fat Pointers to objects that implement "
"`Greet`. The Fat Pointer consist of two components, a pointer to the actual "
"object and a pointer to the virtual method table for the `Greet` "
"implementation of that particular object."
msgstr ""
"* 트레이트는 사용자가 직접 구현해야하는 메서드와 사전 구현된(기본) 메서드를 "
"지정할 수 있습니다. 기본 구현된 메서드는 (다른)필수 메서드를 의존할 수 있습니"
"다.\n"
"* 주어진 트레이트를 구현하는 타입은 크기가 다를 수 있습니다. 이는 위의 예시에"
"서 `Vec<Greet>`와 같은 것을 가질 수 없게 합니다.\n"
"* `dyn Greet`는 컴파일러에게 `Greet`을 구현하는 동적 사이즈 타입을 알려주는 "
"표기입니다."
#: src/traits.md:46
msgid ""
"Compare these outputs in the above example:\n"
"```rust,ignore\n"
" println!(\"{} {}\", std::mem::size_of::<Dog>(), std::mem::size_of::"
"<Cat>());\n"
" println!(\"{} {}\", std::mem::size_of::<&Dog>(), std::mem::size_of::"
"<&Cat>());\n"
" println!(\"{}\", std::mem::size_of::<&dyn Greet>());\n"
" println!(\"{}\", std::mem::size_of::<Box<dyn Greet>>());\n"
"```"
msgstr ""
"위의 예제에 아래를 추가하여 출력을 비교해 보시기 바랍니다:\n"
"```rust,ignore\n"
" println!(\"{} {}\", std::mem::size_of::<Dog>(), std::mem::size_of::"
"<Cat>());\n"
" println!(\"{} {}\", std::mem::size_of::<&Dog>(), std::mem::size_of::"
"<&Cat>());\n"
" println!(\"{}\", std::mem::size_of::<&dyn Greet>());\n"
" println!(\"{}\", std::mem::size_of::<Box<dyn Greet>>());\n"
"```"
#: src/traits/deriving-traits.md:1
msgid "# Deriving Traits"
msgstr "# 트레이트 상속하기(Deriving Traits)"
#: src/traits/deriving-traits.md:3
msgid "You can let the compiler derive a number of traits:"
msgstr ""
"컴파일러가 여러가지 트레이트를 상속(derive)하도록 할 수 있습니다:\n"
"* _역주: derive 메타주석 이야기 입니다._"
#: src/traits/deriving-traits.md:5
msgid ""
"```rust,editable\n"
"#[derive(Debug, Clone, PartialEq, Eq, Default)]\n"
"struct Player {\n"
" name: String,\n"
" strength: u8,\n"
" hit_points: u8,\n"
"}"
msgstr ""
#: src/traits/deriving-traits.md:13
msgid ""
"fn main() {\n"
" let p1 = Player::default();\n"
" let p2 = p1.clone();\n"
" println!(\"Is {:?}\\nequal to {:?}?\\nThe answer is {}!\", &p1, &p2,\n"
" if p1 == p2 { \"yes\" } else { \"no\" });\n"
"}\n"
"```"
msgstr ""
#: src/traits/default-methods.md:1
msgid "# Default Methods"
msgstr "# 기본 메서드"
#: src/traits/default-methods.md:3
msgid "Traits can implement behavior in terms of other trait methods:"
msgstr ""
"트레이트는 다른 트레이트 메서드에서의 동작을 구현할 수 있습니다.\n"
"* 역주: \n"
" * Equals 트레이트에서 equal은 선언만 되어있고 not_equal에서 이를 호출하"
"고 있습니다. (추상 메서드)\n"
" * impl에서 equal 메서드를 정의하고 있어서 Centimeter에서의 equal 메서드"
"를 구현되어 있습니다.(추상 메서드 구현)"
#: src/traits/default-methods.md:5
msgid ""
"```rust,editable\n"
"trait Equals {\n"
" fn equal(&self, other: &Self) -> bool;\n"
" fn not_equal(&self, other: &Self) -> bool {\n"
" !self.equal(other)\n"
" }\n"
"}"
msgstr ""
#: src/traits/default-methods.md:13
msgid ""
"#[derive(Debug)]\n"
"struct Centimeter(i16);"
msgstr ""
#: src/traits/default-methods.md:16
msgid ""
"impl Equals for Centimeter {\n"
" fn equal(&self, other: &Centimeter) -> bool {\n"
" self.0 == other.0\n"
" }\n"
"}"
msgstr ""
#: src/traits/default-methods.md:22
msgid ""
"fn main() {\n"
" let a = Centimeter(10);\n"
" let b = Centimeter(20);\n"
" println!(\"{a:?} equals {b:?}: {}\", a.equal(&b));\n"
" println!(\"{a:?} not_equals {b:?}: {}\", a.not_equal(&b));\n"
"}\n"
"```"
msgstr ""
#: src/traits/important-traits.md:1
msgid "# Important Traits"
msgstr "# 중요 트레이트"
#: src/traits/important-traits.md:3
msgid ""
"We will now look at some of the most common traits of the Rust standard "
"library:"
msgstr "러스트 표준 라이브러리의 자주 사용하는 몇가지 트레이트 예시입니다:"
#: src/traits/important-traits.md:5
msgid ""
"* `Iterator` and `IntoIterator` used in `for` loops,\n"
"* `From` and `Into` used to convert values,\n"
"* `Read` and `Write` used for IO,\n"
"* `Add`, `Mul`, ... used for operator overloading, and\n"
"* `Drop` used for defining destructors."
msgstr ""
"* `Iterator`와 `IntoIterator` 트레이트는 `for` 루프에서 사용됩니다.\n"
"* `From`과 `Into` 트레이트는 타입변환시 사용됩니다.\n"
"* `Read`와 `Write` 트레이트는 I/O에 사용됩니다.\n"
"* `Add`, `Mul` 등의 트레이트들은 연산자 오버로딩(overloading)에 사용됩니다.\n"
"* `Drop` 트레이트는 소멸자 정의에 사용됩니다."
#: src/traits/iterator.md:1
msgid "# Iterators"
msgstr "# Iterators"
#: src/traits/iterator.md:3
msgid "You can implement the `Iterator` trait on your own types:"
msgstr "`Iterator`를 커스텀 타입에 구현할 수 있습니다: "
#: src/traits/iterator.md:5
msgid ""
"```rust,editable\n"
"struct Fibonacci {\n"
" curr: u32,\n"
" next: u32,\n"
"}"
msgstr ""
#: src/traits/iterator.md:11
msgid ""
"impl Iterator for Fibonacci {\n"
" type Item = u32;"
msgstr ""
#: src/traits/iterator.md:14
msgid ""
" fn next(&mut self) -> Option<Self::Item> {\n"
" let new_next = self.curr + self.next;\n"
" self.curr = self.next;\n"
" self.next = new_next;\n"
" Some(self.curr)\n"
" }\n"
"}"
msgstr ""
#: src/traits/iterator.md:22
msgid ""
"fn main() {\n"
" let fib = Fibonacci { curr: 0, next: 1 };\n"
" for (i, n) in fib.enumerate().take(5) {\n"
" println!(\"fib({i}): {n}\");\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/traits/iterator.md:32
msgid ""
"* `IntoIterator` is the trait that makes for loops work. It is implemented "
"by collection types such as\n"
" `Vec<T>` and references to them such as `&Vec<T>` and `&[T]`. Ranges also "
"implement it.\n"
"* The `Iterator` trait implements many common functional programming "
"operations over collections \n"
" (e.g. `map`, `filter`, `reduce`, etc). This is the trait where you can "
"find all the documentation\n"
" about them. In Rust these functions should produce the code as efficient "
"as equivalent imperative\n"
" implementations.\n"
" \n"
"</details>"
msgstr ""
"* `IntoIterator`는 루프가 작동하도록 만드는 트레이트입니다.\n"
" `Vec<T>`와 같은 컬렉션 타입과 그에 대한 참조 타입(`&Vec<T>`, `&[T]`)으로 구"
"현됩니다.\n"
" Range 역시 이를 구현합니다.\n"
"* `Iterator` 트레이트는 컬렉션에 대해 일반적인 함수형 프로그래밍 동작 "
"(`map`, `filter`, `reduce` 등)을 구현합니다. \n"
" 관련 문서에서도 해당 기능들을 확인 할 수 있습니다.\n"
" 러스트에서 이러한 함수들은 명령형으로 구현된 코드와 동등하게 동작합니다.\n"
" \n"
"</details>"
#: src/traits/from-iterator.md:1
msgid "# FromIterator"
msgstr "# FromIterator"
#: src/traits/from-iterator.md:3
msgid "`FromIterator` lets you build a collection from an `Iterator`."
msgstr "`FromIterator` 는 `Iterator`로부터 컬렉션을 만들 수 있습니다."
#: src/traits/from-iterator.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let primes = vec![2, 3, 5, 7];\n"
" let prime_squares = primes.into_iter().map(|prime| prime * prime)."
"collect::<Vec<_>>();\n"
"}\n"
"```"
msgstr ""
#: src/traits/from-iterator.md:14
msgid ""
"`Iterator` implements\n"
"`fn collect<B>(self) -> B\n"
"where\n"
" B: FromIterator<Self::Item>,\n"
" Self: Sized`"
msgstr ""
"`Iterator`는 아래와 같이 구현됩니다.\n"
"```\n"
"fn collect<B>(self) -> B\n"
"where\n"
" B: FromIterator<Self::Item>,\n"
" Self: Sized\n"
"```"
#: src/traits/from-iterator.md:20
msgid ""
"There are also implementations which let you do cool things like convert an\n"
"`Iterator<Item = Result<V, E>>` into a `Result<Vec<V>, E>`."
msgstr ""
"이는 또한 `Iterator<Item = Result<V, E>>`을 `Result<Vec<V>, E>`로 변경하는 멋"
"진 작업도 구현합니다."
#: src/traits/from-into.md:1
msgid "# `From` and `Into`"
msgstr "# `From`과 `Into`"
#: src/traits/from-into.md:3
msgid "Types implement `From` and `Into` to facilitate type conversions:"
msgstr "타입은 용이한 형변환을 위해 `From`과 `Into`를 구현합니다:"
#: src/traits/from-into.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let s = String::from(\"hello\");\n"
" let addr = std::net::Ipv4Addr::from([127, 0, 0, 1]);\n"
" let one = i16::from(true);\n"
" let bigger = i32::from(123i16);\n"
" println!(\"{s}, {addr}, {one}, {bigger}\");\n"
"}\n"
"```"
msgstr ""
#: src/traits/from-into.md:15
msgid "`Into` is automatically implemented when `From` is implemented:"
msgstr "`From`이 구현되면 `Into` 역시 자동으로 구현됩니다:"
#: src/traits/from-into.md:17
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let s: String = \"hello\".into();\n"
" let addr: std::net::Ipv4Addr = [127, 0, 0, 1].into();\n"
" let one: i16 = true.into();\n"
" let bigger: i32 = 123i16.into();\n"
" println!(\"{s}, {addr}, {one}, {bigger}\");\n"
"}\n"
"```"
msgstr ""
#: src/traits/from-into.md:27
msgid ""
"<details>\n"
" \n"
"* That's why it is common to only implement `From`, as your type will get "
"`Into` implementation too.\n"
"* When declaring a function argument input type like \"anything that can be "
"converted into a `String`\", the rule is opposite, you should use `Into`.\n"
" Your function will accept types that implement `From` and those that "
"_only_ implement `Into`.\n"
" \n"
"</details>"
msgstr ""
"<details>\n"
" \n"
"* 그렇기 때문에 사용자가 직접 타입을 구현하는 경우에도 `From` 만 구현하는 것"
"이 일반적입니다.\n"
"* \"`String`으로 변환할 수 있는 모든 것\"과 같은 함수의 인수 타입을 선언할 "
"때 규칙은 반대로 적용되므로 `Into`를 사용해야 합니다. 함수는 `From`을 구현한 "
"타입과 _오직_ `Into`만 구현한 타입을 사용할 수 있습니다.\n"
" \n"
"</details>"
#: src/traits/read-write.md:1
msgid "# `Read` and `Write`"
msgstr "# `Read`와 `Write`"
#: src/traits/read-write.md:3
msgid "Using `Read` and `BufRead`, you can abstract over `u8` sources:"
msgstr "`Read`와 `BufRead`를 사용하면 `u8` 소스로부터 읽을 수 있습니다:"
#: src/traits/read-write.md:5
msgid ""
"```rust,editable\n"
"use std::io::{BufRead, BufReader, Read, Result};"
msgstr ""
#: src/traits/read-write.md:8
msgid ""
"fn count_lines<R: Read>(reader: R) -> usize {\n"
" let buf_reader = BufReader::new(reader);\n"
" buf_reader.lines().count()\n"
"}"
msgstr ""
#: src/traits/read-write.md:13
msgid ""
"fn main() -> Result<()> {\n"
" let slice: &[u8] = b\"foo\\nbar\\nbaz\\n\";\n"
" println!(\"lines in slice: {}\", count_lines(slice));"
msgstr ""
#: src/traits/read-write.md:17
msgid ""
" let file = std::fs::File::open(std::env::current_exe()?)?;\n"
" println!(\"lines in file: {}\", count_lines(file));\n"
" Ok(())\n"
"}\n"
"```"
msgstr ""
#: src/traits/read-write.md:23
msgid "Similarly, `Write` lets you abstract over `u8` sinks:"
msgstr "유사하게 `Write`를 통해 `u8`소스로 출력할 수 있습니다:"
#: src/traits/read-write.md:25
msgid ""
"```rust,editable\n"
"use std::io::{Result, Write};"
msgstr ""
#: src/traits/read-write.md:28
msgid ""
"fn log<W: Write>(writer: &mut W, msg: &str) -> Result<()> {\n"
" writer.write_all(msg.as_bytes())?;\n"
" writer.write_all(\"\\n\".as_bytes())\n"
"}"
msgstr ""
#: src/traits/read-write.md:33
msgid ""
"fn main() -> Result<()> {\n"
" let mut buffer = Vec::new();\n"
" log(&mut buffer, \"Hello\")?;\n"
" log(&mut buffer, \"World\")?;\n"
" println!(\"Logged: {:?}\", buffer);\n"
" Ok(())\n"
"}\n"
"```"
msgstr ""
#: src/traits/operators.md:1
msgid "# `Add`, `Mul`, ..."
msgstr "# `Add`, `Mul`, ..."
#: src/traits/operators.md:3
msgid "Operator overloading is implemented via traits in `std::ops`:"
msgstr "연산자 오버로드는 `std::ops` 트레이트을 통해 구현됩니다:"
#: src/traits/operators.md:5
msgid ""
"```rust,editable\n"
"#[derive(Debug, Copy, Clone)]\n"
"struct Point { x: i32, y: i32 }"
msgstr ""
#: src/traits/operators.md:9 src/exercises/day-2/solutions-morning.md:46
msgid ""
"impl std::ops::Add for Point {\n"
" type Output = Self;"
msgstr ""
#: src/traits/operators.md:12
msgid ""
" fn add(self, other: Self) -> Self {\n"
" Self {x: self.x + other.x, y: self.y + other.y}\n"
" }\n"
"}"
msgstr ""
#: src/traits/operators.md:17
msgid ""
"fn main() {\n"
" let p1 = Point { x: 10, y: 20 };\n"
" let p2 = Point { x: 100, y: 200 };\n"
" println!(\"{:?} + {:?} = {:?}\", p1, p2, p1 + p2);\n"
"}\n"
"```"
msgstr ""
#: src/traits/operators.md:26 src/traits/drop.md:34
msgid "Discussion points:"
msgstr "논의점: "
#: src/traits/operators.md:28
msgid ""
"* You could implement `Add` for `&Point`. In which situations is that "
"useful? \n"
" * Answer: `Add:add` consumes `self`. If type `T` for which you are\n"
" overloading the operator is not `Copy`, you should consider "
"overloading\n"
" the operator for `&T` as well. This avoids unnecessary cloning on "
"the\n"
" call site.\n"
"* Why is `Output` an associated type? Could it be made a type parameter?\n"
" * Short answer: Type parameters are controlled by the caller, but\n"
" associated types (like `Output`) are controlled by the implementor "
"of a\n"
" trait."
msgstr ""
"* 언제 `&Point`에 `Add`를 구현하는 것이 좋습니까?\n"
" * 답변: `Add:add`은 'self'를 소모(consume)합니다. 만약 `Copy`트레이트 없는"
" 타입 `T`가 연산자 오버로딩 하는 경우 `&T`에 대한 연산자 오버로딩도 고려해야"
" 합니다. 이렇게 하면 호출부에서의 불필요한 복제를 방지할 수 있습니다.\n"
"* 왜 `Output`이 연관 타입(associated type)입니까? 타입 매개변수를 만들 수"
" 있습니까?\n"
" * 답변: 타입 매개변수는 호출자가 제어하지만 연관 타입(associated type)은"
" 트레이트의 구현자가 제어합니다."
#: src/traits/drop.md:1
msgid "# The `Drop` Trait"
msgstr "# `Drop` 트레이트"
#: src/traits/drop.md:3
msgid ""
"Values which implement `Drop` can specify code to run when they go out of "
"scope:"
msgstr ""
"`Drop`트레이트는 값이 스코프 밖으로 나갈때 실행하는 코드를 작성할 수 있습니"
"다:"
#: src/traits/drop.md:5
msgid ""
"```rust,editable\n"
"struct Droppable {\n"
" name: &'static str,\n"
"}"
msgstr ""
#: src/traits/drop.md:10
msgid ""
"impl Drop for Droppable {\n"
" fn drop(&mut self) {\n"
" println!(\"Dropping {}\", self.name);\n"
" }\n"
"}"
msgstr ""
#: src/traits/drop.md:16
msgid ""
"fn main() {\n"
" let a = Droppable { name: \"a\" };\n"
" {\n"
" let b = Droppable { name: \"b\" };\n"
" {\n"
" let c = Droppable { name: \"c\" };\n"
" let d = Droppable { name: \"d\" };\n"
" println!(\"Exiting block B\");\n"
" }\n"
" println!(\"Exiting block A\");\n"
" }\n"
" drop(a);\n"
" println!(\"Exiting main\");\n"
"}\n"
"```"
msgstr ""
#: src/traits/drop.md:36
msgid ""
"* Why does not `Drop::drop` take `self`?\n"
" * Short-answer: If it did, `std::mem::drop` would be called at the end "
"of\n"
" the block, resulting in another call to `Drop::drop`, and a stack\n"
" overflow!\n"
"* Try replacing `drop(a)` with `a.drop()`."
msgstr ""
"* `Drop::drop`은 왜 `self`를 가지지 않습니까?\n"
" * 짧은 대답: 만약 그렇게 된다면 `std::mem::drop`이 블록의 끝에서 호출되고,"
" 다시 `Drop::drop`을 호출하게되 스택 오버플로가 발생합니다.\n"
"* `drop(a)`를 `a.drop()`로 변경해 보시기 바랍니다."
#: src/generics.md:1
msgid "# Generics"
msgstr "# 제너릭"
#: src/generics.md:3
msgid ""
"Rust support generics, which lets you abstract an algorithm (such as "
"sorting)\n"
"over the types used in the algorithm."
msgstr ""
"러스트는 제너릭을 지원하여 정렬과 같은 알고리즘에 적용되는 타입을 추상화 할 "
"수 있습니다."
#: src/generics/data-types.md:1
msgid "# Generic Data Types"
msgstr "# 제너릭 데이터 타입"
#: src/generics/data-types.md:3
msgid "You can use generics to abstract over the concrete field type:"
msgstr "제너릭을 사용하여 구체적인 타입을 추상화할 수 있습니다:"
#: src/generics/data-types.md:5
msgid ""
"```rust,editable\n"
"#[derive(Debug)]\n"
"struct Point<T> {\n"
" x: T,\n"
" y: T,\n"
"}"
msgstr ""
#: src/generics/data-types.md:12
msgid ""
"fn main() {\n"
" let integer = Point { x: 5, y: 10 };\n"
" let float = Point { x: 1.0, y: 4.0 };\n"
" println!(\"{integer:?} and {float:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/generics/methods.md:1
msgid "# Generic Methods"
msgstr "# 제너릭 메서드"
#: src/generics/methods.md:3
msgid "You can declare a generic type on your `impl` block:"
msgstr "`impl` 블록에서도 제너릭 타입을 선언할 수 있습니다:"
#: src/generics/methods.md:5
msgid ""
"```rust,editable\n"
"#[derive(Debug)]\n"
"struct Point<T>(T, T);"
msgstr ""
#: src/generics/methods.md:9
msgid ""
"impl<T> Point<T> {\n"
" fn x(&self) -> &T {\n"
" &self.0 // + 10\n"
" }"
msgstr ""
#: src/generics/methods.md:14
msgid ""
" // fn set_x(&mut self, x: T)\n"
"}"
msgstr ""
#: src/generics/methods.md:17
msgid ""
"fn main() {\n"
" let p = Point(5, 10);\n"
" println!(\"p.x = {}\", p.x());\n"
"}\n"
"```"
msgstr ""
#: src/generics/methods.md:25
msgid ""
"* *Q:* Why `T` is specified twice in `impl<T> Point<T> {}`? Isn't that "
"redundant?\n"
" * This is because it is a generic implementation section for generic "
"type. They are independently generic.\n"
" * It means these methods are defined for any `T`.\n"
" * It is possible to write `impl Point<u32> { .. }`. \n"
" * `Point` is still generic and you can use `Point<f64>`, but methods "
"in this block will only be available for `Point<u32>`."
msgstr ""
"* *의문:* `impl<T> Point<T> {}`에서 `T`가 왜 두번 지정됩니까?\n"
" * 제너릭 타입에 대한 제너릭 구현 이기 때문입니다. 이들을 일반적으로 독립적"
"입니다.\n"
" * 이는 이러한 방법으로 모든 `T`에 대해 정의 된다는 것을 뜻합니다.\n"
" * `impl Point<u32> { .. }`와 같이 작성하는 것도 가능합니다.\n"
" * `Point`는 여전히 제너릭이며 `Point<f64>`를 사용할 수도 있지만 이 블"
"록의 메서드는 `Point<u32>`만 쓸 수 있습니다."
#: src/generics/trait-bounds.md:1
msgid "# Trait Bounds"
msgstr "# 제너릭 타입 제한(트레이트 경계, Trait Bounds)"
#: src/generics/trait-bounds.md:3
msgid ""
"When working with generics, you often want to limit the types. You can do "
"this\n"
"with `T: Trait` or `impl Trait`:"
msgstr ""
"`T:` 혹은 `impl` 트레이트를 사용하여 제너릭을 사용할 때 타입을 제한할 수 있습"
"니다:"
#: src/generics/trait-bounds.md:6
msgid ""
"```rust,editable\n"
"fn duplicate<T: Clone>(a: T) -> (T, T) {\n"
" (a.clone(), a.clone())\n"
"}"
msgstr ""
#: src/generics/trait-bounds.md:11
msgid "// struct NotClonable;"
msgstr ""
#: src/generics/trait-bounds.md:13
msgid ""
"fn main() {\n"
" let foo = String::from(\"foo\");\n"
" let pair = duplicate(foo);\n"
"}\n"
"```"
msgstr ""
#: src/generics/trait-bounds.md:21
msgid ""
"Consider showing a `where` clause syntax. Students can encounter it too when "
"reading code.\n"
" \n"
"```rust,ignore\n"
"fn duplicate<T>(a: T) -> (T, T)\n"
"where\n"
" T: Clone,\n"
"{\n"
" (a.clone(), a.clone())\n"
"}\n"
"```"
msgstr ""
"`where`문법을 사용하는 것도 고려 할 수 있습니다. 학생들도 이러한 코드 표현을 "
"마주할 수 있습니다.\n"
" \n"
"```rust,ignore\n"
"fn duplicate<T>(a: T) -> (T, T)\n"
"where\n"
" T: Clone,\n"
"{\n"
" (a.clone(), a.clone())\n"
"}\n"
"```"
#: src/generics/trait-bounds.md:32
msgid ""
"* It declutters the function signature if you have many parameters.\n"
"* It has additional features making it more powerful.\n"
" * If someone asks, the extra feature is that the type on the left of \":"
"\" can be arbitrary, like `Option<T>`.\n"
" \n"
"</details>"
msgstr ""
"* 매개변수가 많은 경우 함수 시그니처을 정리합니다.\n"
"* 좀 더 강력한 추가 기능을 제공합니다.\n"
" * 추가 기능은 `Option<T>`와 같이 \":\" 왼쪽에 있는 타입이 임의적일 수 있다"
"는 것입니다.\n"
" \n"
"</details>"
#: src/generics/impl-trait.md:1
msgid "# `impl Trait`"
msgstr "# 트레이트 구현하기(`impl Trait`)"
#: src/generics/impl-trait.md:3
msgid ""
"Similar to trait bounds, an `impl Trait` syntax can be used in function\n"
"arguments and return values:"
msgstr ""
"트레이트 바운드와 유사하게 `impl`트레이트 문법은 함수의 인자와 반환값에 적용 "
"가능합니다:"
#: src/generics/impl-trait.md:6 src/generics/trait-objects.md:5
#: src/generics/trait-objects.md:28
msgid ""
"```rust,editable\n"
"use std::fmt::Display;"
msgstr ""
#: src/generics/impl-trait.md:9
msgid ""
"fn get_x(name: impl Display) -> impl Display {\n"
" format!(\"Hello {name}\")\n"
"}"
msgstr ""
#: src/generics/impl-trait.md:13
msgid ""
"fn main() {\n"
" let x = get_x(\"foo\");\n"
" println!(\"{x}\");\n"
"}\n"
"```"
msgstr ""
#: src/generics/impl-trait.md:19
msgid ""
"* `impl Trait` cannot be used with the `::<>` turbo fish syntax.\n"
"* `impl Trait` allows you to work with types which you cannot name."
msgstr ""
"* `impl` 트레이트는 터보피쉬문법(`::<>`)에는 사용할 수 없습니다.\n"
"* `impl` 트레이트는 익명타입과 사용할 수 있습니다."
#: src/generics/impl-trait.md:24
msgid ""
"The meaning of `impl Trait` is a bit different in the different positions."
msgstr "`impl Trait`는 입장에 따라 의미가 조금씩 다릅니다."
#: src/generics/impl-trait.md:26
msgid ""
"* For a parameter, `impl Trait` is like an anonymous generic parameter with "
"a trait bound.\n"
"* For a return type, it means that the return type is some concrete type "
"that implements the trait,\n"
" without naming the type. This can be useful when you don't want to expose "
"the concrete type in a\n"
" public API."
msgstr ""
"* 매개변수(parameter) 입장에서는 트레이트 경계(bound)가 있는 익명 제너릭 매개"
"변수와 같습니다.\n"
"* 반환 타입 입장에서는 이름을 지정하지 않고 트레이트를 구현한 구체적인 타입임"
"을 의미합니다. 이는 공개된 API에서 구체적은 타입을 노출하지 않으려는 경우 유"
"용할 수 있습니다."
#: src/generics/impl-trait.md:31
msgid ""
"This example is great, because it uses `impl Display` twice. It helps to "
"explain that\n"
"nothing here enforces that it is _the same_ `impl Display` type. If we used "
"a single \n"
"`T: Display`, it would enforce the constraint that input `T` and return `T` "
"type are the same type.\n"
"It would not work for this particular function, as the type we expect as "
"input is likely not\n"
"what `format!` returns. If we wanted to do the same via `: Display` syntax, "
"we'd need two\n"
"independent generic parameters.\n"
" \n"
"</details>"
msgstr ""
"이 예시는 `impl Display`가 두번 사용 되었다는 점에서 훌륭합니다.\n"
"이는 두 사용처에서 동일한 `impl Display` 타입의 사용을 강제하지 않는 것을 설"
"명하는데 도움이 됩니다. 만일 `T: Display`를 사용한다면 입력과 반환 값이 동일 "
"한 `T` 타입이어야 한다는 제약이 생깁니다. 여기에서 입력되는 유형은 `format!`"
"으로 반환되는 타입과 동일하지 않을 가능성이 높기 때문에 `T: Display`의 지정"
"은 특정 기능에는 동작하지 않을 수 있습니다. 만약 `: Display` 형태로 사용하고 "
"싶다면 독립적인 제너릭 매개변수가 2개 필요합니다.\n"
" \n"
"</details>"
#: src/generics/closures.md:1
msgid "# Closures"
msgstr "# 클로저(Closures)"
#: src/generics/closures.md:3
msgid ""
"Closures or lambda expressions have types which cannot be named. However, "
"they\n"
"implement special [`Fn`](https://doc.rust-lang.org/std/ops/trait.Fn.html),\n"
"[`FnMut`](https://doc.rust-lang.org/std/ops/trait.FnMut.html), and\n"
"[`FnOnce`](https://doc.rust-lang.org/std/ops/trait.FnOnce.html) traits:"
msgstr ""
"클로저 혹은 람다표현식은 익명타입입니다. 이들은 \n"
"[`Fn`](https://doc.rust-lang.org/std/ops/trait.Fn.html),\n"
"[`FnMut`](https://doc.rust-lang.org/std/ops/trait.FnMut.html), \n"
"[`FnOnce`](https://doc.rust-lang.org/std/ops/trait.FnOnce.html) 라는 특별한 "
"트레이트를 구현합니다."
#: src/generics/closures.md:8
msgid ""
"```rust,editable\n"
"fn apply_with_log(func: impl FnOnce(i32) -> i32, input: i32) -> i32 {\n"
" println!(\"Calling function on {input}\");\n"
" func(input)\n"
"}"
msgstr ""
#: src/generics/closures.md:14
msgid ""
"fn main() {\n"
" let add_3 = |x| x + 3;\n"
" let mul_5 = |x| x * 5;"
msgstr ""
#: src/generics/closures.md:18
msgid ""
" println!(\"add_3: {}\", apply_with_log(add_3, 10));\n"
" println!(\"mul_5: {}\", apply_with_log(mul_5, 20));\n"
"}\n"
"```"
msgstr ""
#: src/generics/closures.md:25
msgid ""
"If you have an `FnOnce`, you may only call it once. It might consume "
"captured values."
msgstr "`FnOnce`는 한번만 호출되며 캡처된 값을 소모합니다."
#: src/generics/closures.md:27
msgid ""
"An `FnMut` might mutate captured values, so you can call it multiple times "
"but not concurrently."
msgstr ""
"`FnMut`는 캡처된 값을 변경할 수 있으므로 여러번 호출은 가능하지만 동시에 호"
"출 할 수는 없습니다."
#: src/generics/closures.md:29
msgid ""
"An `Fn` neither consumes nor mutates captured values, or perhaps captures "
"nothing at all, so it can\n"
"be called multiple times concurrently."
msgstr ""
"`Fn`은 캡처된 값을 소모도 변경도 할 수 없거나 어떤 것도 캡처하지 않으므로 동"
"시에 여러번 호출 할 수 있습니다."
#: src/generics/closures.md:32
msgid ""
"`FnMut` is a subtype of `FnOnce`. `Fn` is a subtype of `FnMut` and `FnOnce`. "
"I.e. you can use an\n"
"`FnMut` wherever an `FnOnce` is called for, and you can use an `Fn` wherever "
"an `FnMut` or `FnOnce`\n"
"is called for."
msgstr ""
"`FnMut` 는 `FnOnce`의 하위타입입니다. `Fn`은 `FnMut`과 `FnOnce`의 하위 타입입"
"니다.즉, `FnMut`는 `FnOnce`가 호출되는 곳이면 어디서나 사용 할 수 있고 `Fn`"
"은 `FnMut`와 `FnOnce`가 호출되는 곳이면 어디든 사용할 수 있습니다."
#: src/generics/closures.md:36
msgid "`move` closures only implement `FnOnce`."
msgstr "클로저에서 선언되는 `move`는 오직 `FnOnce`만 구현합니다."
#: src/generics/monomorphization.md:1
msgid "# Monomorphization"
msgstr "# 단형화(Monomorphization)"
#: src/generics/monomorphization.md:3
msgid "Generic code is turned into non-generic code based on the call sites:"
msgstr "제너릭 코드는 호출부에서 비 제너릭 코드로 전환됩니다:"
#: src/generics/monomorphization.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let integer = Some(5);\n"
" let float = Some(5.0);\n"
"}\n"
"```"
msgstr ""
#: src/generics/monomorphization.md:12
msgid "behaves as if you wrote"
msgstr "위 코드는 아래와 같이 동작합니다."
#: src/generics/monomorphization.md:14
msgid ""
"```rust,editable\n"
"enum Option_i32 {\n"
" Some(i32),\n"
" None,\n"
"}"
msgstr ""
#: src/generics/monomorphization.md:20
msgid ""
"enum Option_f64 {\n"
" Some(f64),\n"
" None,\n"
"}"
msgstr ""
#: src/generics/monomorphization.md:25
msgid ""
"fn main() {\n"
" let integer = Option_i32::Some(5);\n"
" let float = Option_f64::Some(5.0);\n"
"}\n"
"```"
msgstr ""
#: src/generics/monomorphization.md:31
msgid ""
"This is a zero-cost abstraction: you get exactly the same result as if you "
"had\n"
"hand-coded the data structures without the abstraction."
msgstr ""
"이것은 (런타임)코스트가 들지 않는 추상화입니다: 추상화 없이 직접 코딩한 것과 "
"정확히 같은 결과입니다."
#: src/generics/trait-objects.md:1
msgid "# Trait Objects"
msgstr "# 트레이트 객체"
#: src/generics/trait-objects.md:3
msgid "We've seen how a function can take arguments which implement a trait:"
msgstr "트레이트를 구현할 때 인수를 취하는 방법:"
#: src/generics/trait-objects.md:8
msgid ""
"fn print<T: Display>(x: T) {\n"
" println!(\"Your value: {}\", x);\n"
"}"
msgstr ""
#: src/generics/trait-objects.md:12
msgid ""
"fn main() {\n"
" print(123);\n"
" print(\"Hello\");\n"
"}\n"
"```"
msgstr ""
#: src/generics/trait-objects.md:18
msgid ""
"However, how can we store a collection of mixed types which implement "
"`Display`?"
msgstr "아래와 같이 여러가지 타입을 혼합하여 인수로 받려면 어떻게 해야 합니까?"
#: src/generics/trait-objects.md:20
msgid ""
"```rust,editable,compile_fail\n"
"fn main() {\n"
" let xs = vec![123, \"Hello\"];\n"
"}\n"
"```"
msgstr ""
#: src/generics/trait-objects.md:26
msgid "For this, we need _trait objects_:"
msgstr "이를 위해서 _트레이트 객체가_ 필요합니다:"
#: src/generics/trait-objects.md:31
msgid ""
"fn main() {\n"
" let xs: Vec<Box<dyn Display>> = vec![Box::new(123), Box::"
"new(\"Hello\")];\n"
" for x in xs {\n"
" println!(\"x: {x}\");\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/generics/trait-objects.md:39
msgid "Memory layout after allocating `xs`:"
msgstr "`xs`가 할당될때 메모리 레이아웃:"
#: src/generics/trait-objects.md:41
msgid ""
"```bob\n"
" Stack Heap\n"
".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - - - "
"- - -.\n"
": : : :\n"
": "
"xs : : :\n"
": +-----------+-------+ : : +-----+-----"
"+ :\n"
": | ptr | o---+---+-----+-->| o o | o o "
"| :\n"
": | len | 2 | : : +-|-|-+-|-|-"
"+ :\n"
": | capacity | 2 | : : | | | | +----+----+----+----+----"
"+ :\n"
": +-----------+-------+ : : | | | '-->| H | e | l | l | o "
"| :\n"
": : : | | | +----+----+----+----+----"
"+ :\n"
"`- - - - - - - - - - - - - -' : | | "
"| :\n"
" : | | | "
"+-------------------------+ :\n"
" : | | '---->| \"<str as Display>::"
"fmt\" | :\n"
" : | | "
"+-------------------------+ :\n"
" : | "
"| :\n"
" : | | +----+----+----+----"
"+ :\n"
" : | '-->| 7b | 00 | 00 | 00 "
"| :\n"
" : | +----+----+----+----"
"+ :\n"
" : "
"| :\n"
" : | +-------------------------"
"+ :\n"
" : '---->| \"<i32 as Display>::fmt\" "
"| :\n"
" : +-------------------------"
"+ :\n"
" : :\n"
" : :\n"
" '- - - - - - - - - - - - - - - - - - - - - "
"- - -'\n"
"```"
msgstr ""
#: src/generics/trait-objects.md:69
msgid ""
"Similarly, you need a trait object if you want to return different values\n"
"implementing a trait:"
msgstr ""
"마찬가지로 트레이트를 구현한 다른 값을 반환할 때도 트레이트 객체가 필요합니"
"다:"
#: src/generics/trait-objects.md:72
msgid ""
"```rust,editable\n"
"fn numbers(n: i32) -> Box<dyn Iterator<Item=i32>> {\n"
" if n > 0 {\n"
" Box::new(0..n)\n"
" } else {\n"
" Box::new((n..0).rev())\n"
" }\n"
"}"
msgstr ""
#: src/generics/trait-objects.md:81
msgid ""
"fn main() {\n"
" println!(\"{:?}\", numbers(-5).collect::<Vec<_>>());\n"
" println!(\"{:?}\", numbers(5).collect::<Vec<_>>());\n"
"}"
msgstr ""
#: src/exercises/day-3/morning.md:1
msgid "# Day 3: Morning Exercises"
msgstr "# 3일차 오전 연습문제"
#: src/exercises/day-3/morning.md:3
msgid "We will design a classical GUI library traits and trait objects."
msgstr ""
"이번 연습문제에서는 트레이트와 트레이트 객체를 통해 고전적인 GUI라이브러리를 "
"설계할 것입니다."
#: src/exercises/day-3/simple-gui.md:1
msgid "# A Simple GUI Library"
msgstr "# 간단한 GUI 라이브러리"
#: src/exercises/day-3/simple-gui.md:3
msgid ""
"Let us design a classical GUI library using our new knowledge of traits and\n"
"trait objects."
msgstr ""
"이번 연습문제에서는 트레이트와 트레이트 객체 지식을 활용하여 고전적인 GUI라"
"이브러리를 설계할 것입니다."
#: src/exercises/day-3/simple-gui.md:6
msgid "We will have a number of widgets in our library:"
msgstr "라이브러리에는 몇가지 위젯이 있습니다:"
#: src/exercises/day-3/simple-gui.md:8
msgid ""
"* `Window`: has a `title` and contains other widgets.\n"
"* `Button`: has a `label` and a callback function which is invoked when the\n"
" button is pressed.\n"
"* `Label`: has a `label`."
msgstr ""
"* `Window`: `title` 속성과 다른 위젯이 포함됩니다.\n"
"* `Button`: `label`위젯과 버튼이 눌렸을때 실행되는 콜백 함수가 있습니다.\n"
"* `Label`: `label` 위젯 입니다."
#: src/exercises/day-3/simple-gui.md:13
msgid "The widgets will implement a `Widget` trait, see below."
msgstr "위젯은 `Widget` 트레이트를 구현합니다. 아래 코드를 참조하세요"
#: src/exercises/day-3/simple-gui.md:15
msgid ""
"Copy the code below to <https://play.rust-lang.org/>, fill in the missing\n"
"`draw_into` methods so that you implement the `Widget` trait:"
msgstr ""
"아래 코드를 <https://play.rust-lang.org/>에 복사하고 누락된 `draw_into`메서드"
"를 채워 넣어 `Widget` 트레이트를 완성해봅시다:"
#: src/exercises/day-3/simple-gui.md:18
#: src/exercises/day-3/safe-ffi-wrapper.md:25
msgid ""
"```rust,should_panic\n"
"// TODO: remove this when you're done with your implementation.\n"
"#![allow(unused_imports, unused_variables, dead_code)]"
msgstr ""
#: src/exercises/day-3/simple-gui.md:22
msgid ""
"pub trait Widget {\n"
" /// Natural width of `self`.\n"
" fn width(&self) -> usize;"
msgstr ""
#: src/exercises/day-3/simple-gui.md:26
#: src/exercises/day-3/solutions-morning.md:27
msgid ""
" /// Draw the widget into a buffer.\n"
" fn draw_into(&self, buffer: &mut dyn std::fmt::Write);"
msgstr ""
#: src/exercises/day-3/simple-gui.md:29
#: src/exercises/day-3/solutions-morning.md:30
msgid ""
" /// Draw the widget on standard output.\n"
" fn draw(&self) {\n"
" let mut buffer = String::new();\n"
" self.draw_into(&mut buffer);\n"
" println!(\"{}\", &buffer);\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/simple-gui.md:37
#: src/exercises/day-3/solutions-morning.md:38
msgid ""
"pub struct Label {\n"
" label: String,\n"
"}"
msgstr ""
#: src/exercises/day-3/simple-gui.md:41
#: src/exercises/day-3/solutions-morning.md:42
msgid ""
"impl Label {\n"
" fn new(label: &str) -> Label {\n"
" Label {\n"
" label: label.to_owned(),\n"
" }\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/simple-gui.md:49
#: src/exercises/day-3/solutions-morning.md:50
msgid ""
"pub struct Button {\n"
" label: Label,\n"
" callback: Box<dyn FnMut()>,\n"
"}"
msgstr ""
#: src/exercises/day-3/simple-gui.md:54
#: src/exercises/day-3/solutions-morning.md:55
msgid ""
"impl Button {\n"
" fn new(label: &str, callback: Box<dyn FnMut()>) -> Button {\n"
" Button {\n"
" label: Label::new(label),\n"
" callback,\n"
" }\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/simple-gui.md:63
#: src/exercises/day-3/solutions-morning.md:64
msgid ""
"pub struct Window {\n"
" title: String,\n"
" widgets: Vec<Box<dyn Widget>>,\n"
"}"
msgstr ""
#: src/exercises/day-3/simple-gui.md:68
#: src/exercises/day-3/solutions-morning.md:69
msgid ""
"impl Window {\n"
" fn new(title: &str) -> Window {\n"
" Window {\n"
" title: title.to_owned(),\n"
" widgets: Vec::new(),\n"
" }\n"
" }"
msgstr ""
#: src/exercises/day-3/simple-gui.md:76
#: src/exercises/day-3/solutions-morning.md:77
msgid ""
" fn add_widget(&mut self, widget: Box<dyn Widget>) {\n"
" self.widgets.push(widget);\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/simple-gui.md:82
msgid ""
"impl Widget for Label {\n"
" fn width(&self) -> usize {\n"
" unimplemented!()\n"
" }"
msgstr ""
#: src/exercises/day-3/simple-gui.md:87 src/exercises/day-3/simple-gui.md:97
#: src/exercises/day-3/simple-gui.md:107
msgid ""
" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
" unimplemented!()\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/simple-gui.md:92
msgid ""
"impl Widget for Button {\n"
" fn width(&self) -> usize {\n"
" unimplemented!()\n"
" }"
msgstr ""
#: src/exercises/day-3/simple-gui.md:102
msgid ""
"impl Widget for Window {\n"
" fn width(&self) -> usize {\n"
" unimplemented!()\n"
" }"
msgstr ""
#: src/exercises/day-3/simple-gui.md:112
msgid ""
"fn main() {\n"
" let mut window = Window::new(\"Rust GUI Demo 1.23\");\n"
" window.add_widget(Box::new(Label::new(\"This is a small text GUI demo."
"\")));\n"
" window.add_widget(Box::new(Button::new(\n"
" \"Click me!\",\n"
" Box::new(|| println!(\"You clicked the button!\")),\n"
" )));\n"
" window.draw();\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-3/simple-gui.md:123
msgid "The output of the above program can be something simple like this:"
msgstr "위 프로그램의 출력은 아래와 같습니다:"
#: src/exercises/day-3/simple-gui.md:125
msgid ""
"```text\n"
"========\n"
"Rust GUI Demo 1.23\n"
"========"
msgstr ""
#: src/exercises/day-3/simple-gui.md:130
msgid "This is a small text GUI demo."
msgstr ""
#: src/exercises/day-3/simple-gui.md:132
msgid ""
"| Click me! |\n"
"```"
msgstr ""
#: src/exercises/day-3/simple-gui.md:135
msgid ""
"If you want to draw aligned text, you can use the\n"
"[fill/alignment](https://doc.rust-lang.org/std/fmt/index."
"html#fillalignment)\n"
"formatting operators. In particular, notice how you can pad with different\n"
"characters (here a `'/'`) and how you can control alignment:"
msgstr ""
"정렬된 글자를 그리기 위해서는 [fill/alignment](https://doc.rust-lang.org/std/"
"fmt/index.html#fillalignment)를 참조하시기 바랍니다. \n"
"특수 문자(여기서는 '/')로 패딩을 주는 방법과 정렬을 제어하는 방법을 확인하시"
"기 바랍니다."
#: src/exercises/day-3/simple-gui.md:140
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let width = 10;\n"
" println!(\"left aligned: |{:/<width$}|\", \"foo\");\n"
" println!(\"centered: |{:/^width$}|\", \"foo\");\n"
" println!(\"right aligned: |{:/>width$}|\", \"foo\");\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-3/simple-gui.md:149
msgid ""
"Using such alignment tricks, you can for example produce output like this:"
msgstr "위의 정렬 트릭을 사용하여 다음과 같은 출력을 생성할 수 있습니다."
#: src/exercises/day-3/simple-gui.md:151
msgid ""
"```text\n"
"+--------------------------------+\n"
"| Rust GUI Demo 1.23 |\n"
"+================================+\n"
"| This is a small text GUI demo. |\n"
"| +-----------+ |\n"
"| | Click me! | |\n"
"| +-----------+ |\n"
"+--------------------------------+\n"
"```"
msgstr ""
#: src/error-handling.md:1
msgid "# Error Handling"
msgstr "# 오류처리"
#: src/error-handling.md:3
msgid "Error handling in Rust is done using explicit control flow:"
msgstr "러스트의 오류 처리는 명시적인 흐름제어로 처리됩니다:"
#: src/error-handling.md:5
msgid ""
"* Functions that can have errors list this in their return type,\n"
"* There are no exceptions."
msgstr ""
"* 오류를 발생할 수 있는 함수는 반환 타입에 명시합니다. \n"
"* 예외는 없습니다."
#: src/error-handling/panics.md:1
msgid "# Panics"
msgstr "# 패닉"
#: src/error-handling/panics.md:3
msgid "Rust will trigger a panic if a fatal error happens at runtime:"
msgstr "러스트는 런타임에서 치명적인 오류를 만나면 패닉을 발생할 것입니다:"
#: src/error-handling/panics.md:5
msgid ""
"```rust,editable,should_panic\n"
"fn main() {\n"
" let v = vec![10, 20, 30];\n"
" println!(\"v[100]: {}\", v[100]);\n"
"}\n"
"```"
msgstr ""
#: src/error-handling/panics.md:12
msgid ""
"* Panics are for unrecoverable and unexpected errors.\n"
" * Panics are symptoms of bugs in the program.\n"
"* Use non-panicking APIs (such as `Vec::get`) if crashing is not acceptable."
msgstr ""
"* 패닉은 복구할 수 없고 예상치 못한 오류입니다.\n"
" * 패닉은 프로그램 버그의 증상입니다.\n"
"* 충돌(크래시)를 허용하지 않아야 하는 경우 패닉을 유발하지 않는(non-"
"panicking) API를 사용합니다.(`Vec::get` 등)"
#: src/error-handling/panic-unwind.md:1
msgid "# Catching the Stack Unwinding"
msgstr "# 스택 되감기"
#: src/error-handling/panic-unwind.md:3
msgid ""
"By default, a panic will cause the stack to unwind. The unwinding can be "
"caught:"
msgstr ""
"기본적으로, 패닉이 발생하면 스택은 해제됩니다. 스택 해제는 다음과 같이 캐치"
"가 가능합니다: "
#: src/error-handling/panic-unwind.md:5
msgid ""
"```rust\n"
"use std::panic;"
msgstr ""
#: src/error-handling/panic-unwind.md:8
msgid ""
"let result = panic::catch_unwind(|| {\n"
" println!(\"hello!\");\n"
"});\n"
"assert!(result.is_ok());"
msgstr ""
#: src/error-handling/panic-unwind.md:13
msgid ""
"let result = panic::catch_unwind(|| {\n"
" panic!(\"oh no!\");\n"
"});\n"
"assert!(result.is_err());\n"
"```"
msgstr ""
#: src/error-handling/panic-unwind.md:19
msgid ""
"* This can be useful in servers which should keep running even if a single\n"
" request crashes.\n"
"* This does not work if `panic = 'abort'` is set in your `Cargo.toml`."
msgstr ""
"* 이것은 단일 요청이 크래시 되더라도 계속 실행되야 하는 서버에 유용합니다.\n"
"* `Cargo.toml`설정파일에 `panic = abort`을 설정하면 동작하지 않습니다."
#: src/error-handling/result.md:1
msgid "# Structured Error Handling with `Result`"
msgstr "# 구조화된 오류처리"
#: src/error-handling/result.md:3
msgid ""
"We have already seen the `Result` enum. This is used pervasively when errors "
"are\n"
"expected as part of normal operation:"
msgstr "`Result` enum은 흔히 오류를 예상되는 경우 사용됩니다: "
#: src/error-handling/result.md:6
msgid ""
"```rust\n"
"use std::fs::File;\n"
"use std::io::Read;"
msgstr ""
#: src/error-handling/result.md:10
msgid ""
"fn main() {\n"
" let file = File::open(\"diary.txt\");\n"
" match file {\n"
" Ok(mut file) => {\n"
" let mut contents = String::new();\n"
" file.read_to_string(&mut contents);\n"
" println!(\"Dear diary: {contents}\");\n"
" },\n"
" Err(err) => {\n"
" println!(\"The diary could not be opened: {err}\");\n"
" }\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/error-handling/result.md:27
msgid ""
" * As with `Option`, the successful value sits inside of `Result`, forcing "
"the developer to\n"
" explicitly extract it. This encourages error checking. In the case where "
"an error should never happen,\n"
" `unwrap()` or `expect()` can be called, and this is a signal of the "
"developer intent too. \n"
" * `Result` documentation is a recommended read. Not during the course, but "
"it is worth mentioning. \n"
" It contains a lot of convenience methods and functions that help "
"functional-style programming. \n"
" \n"
"</details>"
msgstr ""
" * `Option`와 마찬가지로 성공한(`OK`) 값은 `Result` 내부에만 있으므로 개발"
"자가 명시적으로 이를 추출하여야 합니다. 이렇게 하면 오류를 확인 할 수 있습니"
"다. 만일 오류가 절대 발생하지 않는 경우라면 `unwrap()`나 `expect()`를 사용"
"할 수 있으며 이는 개발자가 의도했음을 나타내는 신호이기도 합니다.\n"
" * 수업중엔 아니지만 `Result`에 대한 문서를 읽는 것을 권장합니다. 함수형 "
"프로그래밍 스타일에 도움이 되는 편리한 메서드와 함수이 많이 포함되어 있습니"
"다.\n"
" \n"
"</details>"
#: src/error-handling/try-operator.md:1
msgid "# Propagating Errors with `?`"
msgstr "# '?'를 이용한 오류 전파"
#: src/error-handling/try-operator.md:3
msgid ""
"The try-operator `?` is used to return errors to the caller. It lets you "
"turn\n"
"the common"
msgstr "시도(시행)연산자 `?`는 호출자에게 오류를 반환할 때 사용합니다. "
#: src/error-handling/try-operator.md:6
msgid ""
"```rust,ignore\n"
"match some_expression {\n"
" Ok(value) => value,\n"
" Err(err) => return Err(err),\n"
"}\n"
"```"
msgstr ""
#: src/error-handling/try-operator.md:13
msgid "into the much simpler"
msgstr "훨씬 간단한 방식으로"
#: src/error-handling/try-operator.md:15
msgid ""
"```rust,ignore\n"
"some_expression?\n"
"```"
msgstr ""
#: src/error-handling/try-operator.md:19
msgid "We can use this to simplify our error handing code:"
msgstr "이를 사용하면 오류를 처리할 수 단순화 할 수 있습니다:"
#: src/error-handling/try-operator.md:21
msgid ""
"```rust,editable\n"
"use std::fs;\n"
"use std::io::{self, Read};"
msgstr ""
#: src/error-handling/try-operator.md:25
msgid ""
"fn read_username(path: &str) -> Result<String, io::Error> {\n"
" let username_file_result = fs::File::open(path);"
msgstr ""
#: src/error-handling/try-operator.md:28
msgid ""
" let mut username_file = match username_file_result {\n"
" Ok(file) => file,\n"
" Err(e) => return Err(e),\n"
" };"
msgstr ""
#: src/error-handling/try-operator.md:33
msgid " let mut username = String::new();"
msgstr ""
#: src/error-handling/try-operator.md:35
msgid ""
" match username_file.read_to_string(&mut username) {\n"
" Ok(_) => Ok(username),\n"
" Err(e) => Err(e),\n"
" }\n"
"}"
msgstr ""
#: src/error-handling/try-operator.md:41
msgid ""
"fn main() {\n"
" //fs::write(\"config.dat\", \"alice\").unwrap();\n"
" let username = read_username(\"config.dat\");\n"
" println!(\"username or error: {username:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/error-handling/try-operator.md:52
#: src/error-handling/converting-error-types.md:57
msgid ""
"* The `username` variable can be either `Ok(string)` or `Err(error)`.\n"
"* Use the `fs::write` call to test out the different scenarios: no file, "
"empty file, file with username."
msgstr ""
"* `username` 변수는 `Ok(string)`이거나 `Err(error)`일 수 있습니다.\n"
"* `fs::write` 메서드를 사용하여 파일이 없거나, 비었거나, 중복되는 경우 등을 "
"테스트해 봅니다."
#: src/error-handling/converting-error-types.md:1
msgid "# Converting Error Types"
msgstr "# 오류타입 변환"
#: src/error-handling/converting-error-types.md:3
msgid ""
"The effective expansion of `?` is a little more complicated than previously "
"indicated:"
msgstr "`?`의 효과적인 적용은 좀 더 복잡하긴 합니다:"
#: src/error-handling/converting-error-types.md:5
msgid ""
"```rust,ignore\n"
"expression?\n"
"```"
msgstr ""
#: src/error-handling/converting-error-types.md:9
msgid "works the same as"
msgstr "위 표현은 아래와 같습니다."
#: src/error-handling/converting-error-types.md:11
msgid ""
"```rust,ignore\n"
"match expression {\n"
" Ok(value) => value,\n"
" Err(err) => return Err(From::from(err)),\n"
"}\n"
"```"
msgstr ""
#: src/error-handling/converting-error-types.md:18
msgid ""
"The `From::from` call here means we attempt to convert the error type to "
"the\n"
"type returned by the function:"
msgstr "`From::from` 호출은 오류타입을 함수에서 반환하는 타입으로 변환합니다: "
#: src/error-handling/converting-error-types.md:21
msgid ""
"```rust,editable\n"
"use std::{fs, io};\n"
"use std::io::Read;"
msgstr ""
#: src/error-handling/converting-error-types.md:25
msgid ""
"#[derive(Debug)]\n"
"enum ReadUsernameError {\n"
" IoError(io::Error),\n"
" EmptyUsername(String),\n"
"}"
msgstr ""
#: src/error-handling/converting-error-types.md:31
msgid ""
"impl From<io::Error> for ReadUsernameError {\n"
" fn from(err: io::Error) -> ReadUsernameError {\n"
" ReadUsernameError::IoError(err)\n"
" }\n"
"}"
msgstr ""
#: src/error-handling/converting-error-types.md:37
#: src/error-handling/deriving-error-enums.md:19
msgid ""
"fn read_username(path: &str) -> Result<String, ReadUsernameError> {\n"
" let mut username = String::with_capacity(100);\n"
" fs::File::open(path)?.read_to_string(&mut username)?;\n"
" if username.is_empty() {\n"
" return Err(ReadUsernameError::EmptyUsername(String::from(path)));\n"
" }\n"
" Ok(username)\n"
"}"
msgstr ""
#: src/error-handling/converting-error-types.md:46
msgid ""
"fn main() {\n"
" //fs::write(\"config.dat\", \"\").unwrap();\n"
" let username = read_username(\"config.dat\");\n"
" println!(\"username or error: {username:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/error-handling/deriving-error-enums.md:1
msgid "# Deriving Error Enums"
msgstr "# 또다른 오류 열거형"
#: src/error-handling/deriving-error-enums.md:3
msgid ""
"The [thiserror](https://docs.rs/thiserror/) crate is a popular way to create "
"an\n"
"error enum like we did on the previous page:"
msgstr ""
"[thiserror](https://docs.rs/thiserror/) 크레이트는 전페이지에서 처럼 \n"
"오류 enum을 만드는 일반적인 방법입니다."
#: src/error-handling/deriving-error-enums.md:6
msgid ""
"```rust,editable,compile_fail\n"
"use std::{fs, io};\n"
"use std::io::Read;\n"
"use thiserror::Error;"
msgstr ""
#: src/error-handling/deriving-error-enums.md:11
msgid ""
"#[derive(Error, Debug)]\n"
"enum ReadUsernameError {\n"
" #[error(\"Could not read: {0}\")]\n"
" IoError(#[from] io::Error),\n"
" #[error(\"Found no username in {0}\")]\n"
" EmptyUsername(String),\n"
"}"
msgstr ""
#: src/error-handling/deriving-error-enums.md:28
msgid ""
"fn main() {\n"
" //fs::write(\"config.dat\", \"\").unwrap();\n"
" match read_username(\"config.dat\") {\n"
" Ok(username) => println!(\"Username: {username}\"),\n"
" Err(err) => println!(\"Error: {err}\"),\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/error-handling/error-contexts.md:1
msgid "# Adding Context to Errors"
msgstr "# 오류에 상황정보 추가"
#: src/error-handling/error-contexts.md:3
msgid ""
"The widely used [anyhow](https://docs.rs/anyhow/) crate can help you add\n"
"contextual information to your errors and allows you to have fewer\n"
"custom error types:"
msgstr ""
"[anyhow](https://docs.rs/anyhow/) 크레이트는 오류에 대한 상황정보를 추가하기 "
"위해 널리 사용되며 사용자 정의 오류 유형을 줄일 수 있습니다: "
#: src/error-handling/error-contexts.md:7
msgid ""
"```rust,editable,compile_fail\n"
"use std::{fs, io};\n"
"use std::io::Read;\n"
"use thiserror::Error;\n"
"use anyhow::{Context, Result};"
msgstr ""
#: src/error-handling/error-contexts.md:13
msgid ""
"#[derive(Error, Debug)]\n"
"enum ReadUsernameError {\n"
" #[error(\"Found no username in {0}\")]\n"
" EmptyUsername(String),\n"
"}"
msgstr ""
#: src/error-handling/error-contexts.md:19
msgid ""
"fn read_username(path: &str) -> Result<String> {\n"
" let mut username = String::with_capacity(100);\n"
" fs::File::open(path)\n"
" .context(format!(\"Failed to open {path}\"))?\n"
" .read_to_string(&mut username)\n"
" .context(\"Failed to read\")?;\n"
" if username.is_empty() {\n"
" return Err(ReadUsernameError::EmptyUsername(String::from(path)))?;\n"
" }\n"
" Ok(username)\n"
"}"
msgstr ""
#: src/error-handling/error-contexts.md:31
msgid ""
"fn main() {\n"
" //fs::write(\"config.dat\", \"\").unwrap();\n"
" match read_username(\"config.dat\") {\n"
" Ok(username) => println!(\"Username: {username}\"),\n"
" Err(err) => println!(\"Error: {err:?}\"),\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/error-handling/error-contexts.md:42
msgid ""
"* `anyhow::Result<T>` is generic and it can hold any `Error` implementation "
"without changing the type signature.\n"
"* Actual error type inside of it can be extracted for examination if "
"necessary.\n"
"* Functionality provided by `anyhow::Result<T>` may be familiar to Go "
"developers, as it provides similar usage patterns and ergonomics\n"
" of `(T, error)` from Go. "
msgstr ""
#: src/testing.md:1
msgid "# Testing"
msgstr "# 테스트"
#: src/testing.md:3
msgid "Rust and Cargo come with a simple unit test framework:"
msgstr "러스트와 카고(cargo)는 간단한 테스트 프레임워크와 함께 제공됩니다:"
#: src/testing.md:5
msgid "* Unit tests are supported throughout your code."
msgstr "* 단위 테스트는 코드 전반에서 지원됩니다."
#: src/testing.md:7
msgid "* Integration tests are supported via the `tests/` directory."
msgstr "* 통합테스트는 `test/` 폴더를 통해 지원됩니다."
#: src/testing/unit-tests.md:1
msgid "# Unit Tests"
msgstr "# 단위 테스트"
#: src/testing/unit-tests.md:3
msgid "Mark unit tests with `#[test]`:"
msgstr "단위 테스트는 `#[test]` 표기로 이뤄집니다:"
#: src/testing/unit-tests.md:5
msgid ""
"```rust,editable\n"
"fn first_word(text: &str) -> &str {\n"
" match text.find(' ') {\n"
" Some(idx) => &text[..idx],\n"
" None => &text,\n"
" }\n"
"}"
msgstr ""
#: src/testing/unit-tests.md:13
msgid ""
"#[test]\n"
"fn test_empty() {\n"
" assert_eq!(first_word(\"\"), \"\");\n"
"}"
msgstr ""
#: src/testing/unit-tests.md:18
msgid ""
"#[test]\n"
"fn test_single_word() {\n"
" assert_eq!(first_word(\"Hello\"), \"Hello\");\n"
"}"
msgstr ""
#: src/testing/unit-tests.md:23
msgid ""
"#[test]\n"
"fn test_multiple_words() {\n"
" assert_eq!(first_word(\"Hello World\"), \"Hello\");\n"
"}\n"
"```"
msgstr ""
#: src/testing/unit-tests.md:29
msgid "Use `cargo test` to find and run the unit tests."
msgstr "`cargo test` 커맨드를 사용하면 단위 테스트를 찾아서 실행합니다."
#: src/testing/test-modules.md:1
msgid "# Test Modules"
msgstr "# 테스트 모듈"
#: src/testing/test-modules.md:3
msgid ""
"Unit tests are often put in a nested module (run tests on the\n"
"[Playground](https://play.rust-lang.org/)):"
msgstr ""
"단위 테스트는 종종 중첩 모듈 안에 존재합니다. [플레이그라운드](https://play."
"rust-lang.org/)에서 실행하시기 바랍니다) \n"
"--> 단위 테스트는 모듈로 분리해서 선언 가능합니다."
#: src/testing/test-modules.md:6
msgid ""
"```rust,editable\n"
"fn helper(a: &str, b: &str) -> String {\n"
" format!(\"{a} {b}\")\n"
"}"
msgstr ""
#: src/testing/test-modules.md:11
msgid ""
"pub fn main() {\n"
" println!(\"{}\", helper(\"Hello\", \"World\"));\n"
"}"
msgstr ""
#: src/testing/test-modules.md:19
msgid ""
" #[test]\n"
" fn test_helper() {\n"
" assert_eq!(helper(\"foo\", \"bar\"), \"foo bar\");\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/testing/test-modules.md:26
msgid ""
"* This lets you unit test private helpers.\n"
"* The `#[cfg(test)]` attribute is only active when you run `cargo test`."
msgstr ""
"* 개별화된 헬퍼모듈을 통해 단위테스트를 수행할 수 있습니다.\n"
"* `#[cfg(test)]` 속성은 오직 `cargo test` 커맨드 실행인 경우에만 동작합니다."
#: src/testing/doc-tests.md:1
msgid "# Documentation Tests"
msgstr "문서화주석 테스트"
#: src/testing/doc-tests.md:3
msgid "Rust has built-in support for documentation tests:"
msgstr "러스트는 문서화주석에 대한 테스트를 내장하여 제공합니다:"
#: src/testing/doc-tests.md:5
msgid ""
"```rust\n"
"/// Shortens a string to the given length.\n"
"///\n"
"/// ```\n"
"/// use playground::shorten_string;\n"
"/// assert_eq!(shorten_string(\"Hello World\", 5), \"Hello\");\n"
"/// assert_eq!(shorten_string(\"Hello World\", 20), \"Hello World\");\n"
"/// ```\n"
"pub fn shorten_string(s: &str, length: usize) -> &str {\n"
" &s[..std::cmp::min(length, s.len())]\n"
"}\n"
"```"
msgstr ""
#: src/testing/doc-tests.md:18
msgid ""
"* Code blocks in `///` comments are automatically seen as Rust code.\n"
"* The code will be compiled and executed as part of `cargo test`.\n"
"* Test the above code on the [Rust Playground](https://play.rust-lang.org/?"
"version=stable&mode=debug&edition=2021&gist=3ce2ad13ea1302f6572cb15cd96becf0)."
msgstr ""
"* `///` 주석안의 코드 블록은 자동으로 러스트 코드로 인식됩니다.\n"
"* 코드 블록은 `cargo test` 커맨드 구동시 컴파일되고 실행됩니다.\n"
"* 위 코드를 [Rust Playground](https://play.rust-lang.org/?"
"version=stable&mode=debug&edition=2021&gist=3ce2ad13ea1302f6572cb15cd96becf0)"
"에서 테스트 해 보시기 바랍니다."
#: src/testing/integration-tests.md:1
msgid "# Integration Tests"
msgstr "# 통합 테스트"
#: src/testing/integration-tests.md:3
msgid "If you want to test your library as a client, use an integration test."
msgstr ""
"라이브러리를 실제 테스트 하기위한 통합테스트는 `test/` 폴더 내에 `.rs`를 작성"
"하여 수행합니다: "
#: src/testing/integration-tests.md:5
msgid "Create a `.rs` file under `tests/`:"
msgstr " "
#: src/testing/integration-tests.md:7
msgid ""
"```rust,ignore\n"
"use my_library::init;"
msgstr ""
#: src/testing/integration-tests.md:10
msgid ""
"#[test]\n"
"fn test_init() {\n"
" assert!(init().is_ok());\n"
"}\n"
"```"
msgstr ""
#: src/testing/integration-tests.md:16
msgid "These tests only have access to the public API of your crate."
msgstr "이 테스트는 크레이트의 공개 API에만 접근할 수 있습니다."
#: src/unsafe.md:1
msgid "# Unsafe Rust"
msgstr "# 안전하지 않은 러스트"
#: src/unsafe.md:3
msgid "The Rust language has two parts:"
msgstr "러스트의 문법은 크게 두가지 부분으로 나뉩니다:"
#: src/unsafe.md:5
msgid ""
"* **Safe Rust:** memory safe, no undefined behavior possible.\n"
"* **Unsafe Rust:** can trigger undefined behavior if preconditions are "
"violated."
msgstr ""
"* **안전한 러스트:** 안전한 메모리, 정의되지 않은 동작 가능성 없음.\n"
"* **안전하지 않은 러스트:** 사전 조건을 위반하는 경우 정의되지 않은 동작을 "
"수행할 수 있습니다."
#: src/unsafe.md:8
msgid ""
"We will be seeing mostly safe Rust in this course, but it's important to "
"know\n"
"what Unsafe Rust is."
msgstr ""
"이 강의는 대부분 안전한 러스트에 대해 다루지만 **안전하지 않은 러스트가** 무"
"엇인지는 알아 두어야 합니다."
#: src/unsafe.md:11
msgid "Unsafe Rust gives you access to five new capabilities:"
msgstr "안전하지 않은 러스트는 다음과 같은 5가지 새로운 기능을 제공합니다:"
#: src/unsafe.md:13
msgid ""
"* Dereference raw pointers.\n"
"* Access or modify mutable static variables.\n"
"* Access `union` fields.\n"
"* Call `unsafe` functions, including `extern` functions.\n"
"* Implement `unsafe` traits."
msgstr ""
"* 원시 포인터 역참조(따라가기)\n"
"* 정적 가변변수 접근 및 수정\n"
"* `union` 필드 접근\n"
"* `extern` 함수를 포함한 `unsafe` 함수 호출\n"
"* `unsafe` 트레이트 구현"
#: src/unsafe.md:19
msgid ""
"We will briefly cover these capabilities next. For full details, please see\n"
"[Chapter 19.1 in the Rust Book](https://doc.rust-lang.org/book/ch19-01-"
"unsafe-rust.html)\n"
"and the [Rustonomicon](https://doc.rust-lang.org/nomicon/)."
msgstr ""
"위 기능에 대해 간략히 살펴보겠습니다. 자세한 내용은 [Chapter 19.1 in the "
"Rust Book](https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html)\n"
"와 [Rustonomicon](https://doc.rust-lang.org/nomicon/)를 참조하세요"
#: src/unsafe/raw-pointers.md:1
msgid "# Dereferencing Raw Pointers"
msgstr "# 원시 포인터 역참조(따라가기)"
#: src/unsafe/raw-pointers.md:3
msgid "Creating pointers is safe, but dereferencing them requires `unsafe`:"
msgstr ""
"포인터 생성은 안전합니다. 하지만 역참조(따라가기)할 경우 `unsafe`가 필요합니"
"다:"
#: src/unsafe/raw-pointers.md:5
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let mut num = 5;"
msgstr ""
#: src/unsafe/raw-pointers.md:9
msgid ""
" let r1 = &mut num as *mut i32;\n"
" let r2 = &num as *const i32;"
msgstr ""
#: src/unsafe/raw-pointers.md:12
msgid ""
" unsafe {\n"
" println!(\"r1 is: {}\", *r1);\n"
" *r1 = 10; // Data race if r1 is being written concurrently!\n"
" println!(\"r2 is: {}\", *r2);\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/unsafe/mutable-static-variables.md:1
msgid "# Mutable Static Variables"
msgstr "# 정적 가변 변수"
#: src/unsafe/mutable-static-variables.md:3
msgid "It is safe to read an immutable static variable:"
msgstr "불변 정적변수를 읽는 것은 '안전'합니다:"
#: src/unsafe/mutable-static-variables.md:5
msgid ""
"```rust,editable\n"
"static HELLO_WORLD: &str = \"Hello, world!\";"
msgstr ""
#: src/unsafe/mutable-static-variables.md:8
msgid ""
"fn main() {\n"
" println!(\"name is: {}\", HELLO_WORLD);\n"
"}\n"
"```"
msgstr ""
#: src/unsafe/mutable-static-variables.md:13
msgid ""
"However, since data races can occur, it is unsafe to read and write mutable\n"
"static variables:"
msgstr ""
"하지만, 데이터 레이스가 발생할 수 있으므로 정적 가변변수를 읽고 쓰는 것은 '안"
"전하지 않습니다':"
#: src/unsafe/mutable-static-variables.md:16
msgid ""
"```rust,editable\n"
"static mut COUNTER: u32 = 0;"
msgstr ""
#: src/unsafe/mutable-static-variables.md:19
msgid ""
"fn add_to_counter(inc: u32) {\n"
" unsafe { COUNTER += inc; } // Potential data race!\n"
"}"
msgstr ""
#: src/unsafe/mutable-static-variables.md:23
msgid ""
"fn main() {\n"
" add_to_counter(42);"
msgstr ""
#: src/unsafe/mutable-static-variables.md:26
msgid ""
" unsafe { println!(\"COUNTER: {}\", COUNTER); } // Potential data race!\n"
"}\n"
"```"
msgstr ""
#: src/unsafe/unsafe-functions.md:1
msgid "# Calling Unsafe Functions"
msgstr "# '안전하지 않은' 함수 호출"
#: src/unsafe/unsafe-functions.md:3
msgid ""
"A function or method can be marked `unsafe` if it has extra preconditions "
"you\n"
"must uphold:"
msgstr ""
"다음과 같은 추가 전제 조건이 있는 경우 함수나 메서드는 `unsafe` 표시할 수 있"
"습니다:"
#: src/unsafe/unsafe-functions.md:6
msgid ""
"```rust,editable\n"
"fn main() {\n"
" let emojis = \"🗻∈🌏\";\n"
" unsafe {\n"
" // Undefined behavior if indices do not lie on UTF-8 sequence "
"boundaries.\n"
" println!(\"{}\", emojis.get_unchecked(0..4));\n"
" println!(\"{}\", emojis.get_unchecked(4..7));\n"
" println!(\"{}\", emojis.get_unchecked(7..11));\n"
" }\n"
"}\n"
"```"
msgstr ""
"```rust,editable\n"
"fn main() {\n"
" let emojis = \"🗻∈🌏\";\n"
" unsafe {\n"
" // 인덱스가 UTF-8 시퀀스 경계에 있지 않은경우 정의되지 않은"
"(undefined) 동작입니다.\n"
" println!(\"{}\", emojis.get_unchecked(0..4));\n"
" println!(\"{}\", emojis.get_unchecked(4..7));\n"
" println!(\"{}\", emojis.get_unchecked(7..11));\n"
" }\n"
"}\n"
"```"
#: src/unsafe/extern-functions.md:1
msgid "# Calling External Code"
msgstr "# 외부 코드 호출(Calling External Code)"
#: src/unsafe/extern-functions.md:3
msgid ""
"Functions from other languages might violate the guarantees of Rust. "
"Calling\n"
"them is thus unsafe:"
msgstr ""
"다른 언어의 함수는 러스트의 보증을 위반할 수 있습니다. 따라서 이를 호출하는 "
"것은 '안전하지 않습니다':"
#: src/unsafe/extern-functions.md:6
msgid ""
"```rust,editable\n"
"extern \"C\" {\n"
" fn abs(input: i32) -> i32;\n"
"}"
msgstr ""
#: src/unsafe/extern-functions.md:11
msgid ""
"fn main() {\n"
" unsafe {\n"
" // Undefined behavior if abs misbehaves.\n"
" println!(\"Absolute value of -3 according to C: {}\", abs(-3));\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/unsafe/unions.md:1
msgid "# Unions"
msgstr "# Unions"
#: src/unsafe/unions.md:3
msgid "Unions are like enums, but you need to track the active field yourself:"
msgstr "유니온타입은 열거형(enum)과 같지만 직접 활성 필드를 추척해야 합니다:"
#: src/unsafe/unions.md:5
msgid ""
"```rust,editable\n"
"#[repr(C)]\n"
"union MyUnion {\n"
" i: u8,\n"
" b: bool,\n"
"}"
msgstr ""
#: src/unsafe/unions.md:12
msgid ""
"fn main() {\n"
" let u = MyUnion { i: 42 };\n"
" println!(\"int: {}\", unsafe { u.i });\n"
" println!(\"bool: {}\", unsafe { u.b }); // Undefined behavior!\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-3/afternoon.md:1
msgid "# Day 3: Afternoon Exercises"
msgstr "# 3일차 오후 연습문제"
#: src/exercises/day-3/afternoon.md:3
msgid "Let us build a safe wrapper for reading directory content!"
msgstr ""
"이번 연습문제에서는 파일 폴더를 안전하게 읽을 수 있는 래퍼를 만들어 봅니다."
#: src/exercises/day-3/afternoon.md:7
msgid "After looking at the exercise, you can look at the [solution] provided."
msgstr "연습문제를 살펴 본 후, 제공된 [solutions]을 살펴볼 수 있습니다."
#: src/exercises/day-3/safe-ffi-wrapper.md:1
msgid "# Safe FFI Wrapper"
msgstr "# FFI래퍼"
#: src/exercises/day-3/safe-ffi-wrapper.md:3
msgid ""
"Rust has great support for calling functions through a _foreign function\n"
"interface_ (FFI). We will use this to build a safe wrapper the `glibc` "
"functions\n"
"you would use from C to read the filenames of a directory."
msgstr ""
"러스트는 _외부 기능 호출(FFI)_을 지원합니다. 이를 이용하여 C에서 사용할 폴더 "
"내 파일이름을 읽어오는 `glibc`함수를 만들 것입니다."
#: src/exercises/day-3/safe-ffi-wrapper.md:7
msgid "You will want to consult the manual pages:"
msgstr "아래 리눅스 메뉴얼 문서들을 참조하시기 바랍니다:"
#: src/exercises/day-3/safe-ffi-wrapper.md:9
msgid ""
"* [`opendir(3)`](https://man7.org/linux/man-pages/man3/opendir.3.html)\n"
"* [`readdir(3)`](https://man7.org/linux/man-pages/man3/readdir.3.html)\n"
"* [`closedir(3)`](https://man7.org/linux/man-pages/man3/closedir.3.html)"
msgstr ""
#: src/exercises/day-3/safe-ffi-wrapper.md:13
msgid ""
"You will also want to browse the [`std::ffi`] module, particular for "
"[`CStr`]\n"
"and [`CString`] types which are used to hold NUL-terminated strings coming "
"from\n"
"C. The [Nomicon] also has a very useful chapter about FFI."
msgstr ""
"C에서 오는 NUL-terminated 문자열을 보유하는 [`CStr`]과 [`CString`] 타입 등"
"을 확인 하기 위해 또한 `std::ffi`모듈을 탐색할 수도 있습니다. [Nomicon]문서 "
"또한 FFI에 대한 유용한 내용을 담고 있습니다."
#: src/exercises/day-3/safe-ffi-wrapper.md:17
msgid ""
"[`std::ffi`]: https://doc.rust-lang.org/std/ffi/\n"
"[`CStr`]: https://doc.rust-lang.org/std/ffi/struct.CStr.html\n"
"[`CString`]: https://doc.rust-lang.org/std/ffi/struct.CString.html\n"
"[Nomicon]: https://doc.rust-lang.org/nomicon/ffi.html"
msgstr ""
#: src/exercises/day-3/safe-ffi-wrapper.md:22
msgid ""
"Copy the code below to <https://play.rust-lang.org/> and fill in the "
"missing\n"
"functions and methods:"
msgstr ""
"아래 코드를 <https://play.rust-lang.org/>에 복사하고 빠진 함수와 메서드를 채"
"워봅니다."
#: src/exercises/day-3/safe-ffi-wrapper.md:29
msgid ""
"mod ffi {\n"
" use std::os::raw::{c_char, c_int, c_long, c_ulong, c_ushort};"
msgstr ""
#: src/exercises/day-3/safe-ffi-wrapper.md:32
#: src/exercises/day-3/solutions-afternoon.md:26
msgid ""
" // Opaque type. See https://doc.rust-lang.org/nomicon/ffi.html.\n"
" #[repr(C)]\n"
" pub struct DIR {\n"
" _data: [u8; 0],\n"
" _marker: core::marker::PhantomData<(*mut u8, core::marker::"
"PhantomPinned)>,\n"
" }"
msgstr ""
#: src/exercises/day-3/safe-ffi-wrapper.md:39
#: src/exercises/day-3/solutions-afternoon.md:33
msgid ""
" // Layout as per readdir(3) and definitions in /usr/include/x86_64-linux-"
"gnu.\n"
" #[repr(C)]\n"
" pub struct dirent {\n"
" pub d_ino: c_long,\n"
" pub d_off: c_ulong,\n"
" pub d_reclen: c_ushort,\n"
" pub d_type: c_char,\n"
" pub d_name: [c_char; 256],\n"
" }"
msgstr ""
#: src/exercises/day-3/safe-ffi-wrapper.md:49
#: src/exercises/day-3/solutions-afternoon.md:43
msgid ""
" extern \"C\" {\n"
" pub fn opendir(s: *const c_char) -> *mut DIR;\n"
" pub fn readdir(s: *mut DIR) -> *const dirent;\n"
" pub fn closedir(s: *mut DIR) -> c_int;\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/safe-ffi-wrapper.md:56
#: src/exercises/day-3/solutions-afternoon.md:50
msgid ""
"use std::ffi::{CStr, CString, OsStr, OsString};\n"
"use std::os::unix::ffi::OsStrExt;"
msgstr ""
#: src/exercises/day-3/safe-ffi-wrapper.md:59
msgid ""
"#[derive(Debug)]\n"
"struct DirectoryIterator {\n"
" path: CString,\n"
" dir: *mut ffi::DIR,\n"
"}"
msgstr ""
#: src/exercises/day-3/safe-ffi-wrapper.md:65
msgid ""
"impl DirectoryIterator {\n"
" fn new(path: &str) -> Result<DirectoryIterator, String> {\n"
" // Call opendir and return a Ok value if that worked,\n"
" // otherwise return Err with a message.\n"
" unimplemented!()\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/safe-ffi-wrapper.md:73
msgid ""
"impl Iterator for DirectoryIterator {\n"
" type Item = OsString;\n"
" fn next(&mut self) -> Option<OsString> {\n"
" // Keep calling readdir until we get a NULL pointer back.\n"
" unimplemented!()\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/safe-ffi-wrapper.md:81
msgid ""
"impl Drop for DirectoryIterator {\n"
" fn drop(&mut self) {\n"
" // Call closedir as needed.\n"
" unimplemented!()\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/safe-ffi-wrapper.md:88
msgid ""
"fn main() -> Result<(), String> {\n"
" let iter = DirectoryIterator::new(\".\")?;\n"
" println!(\"files: {:#?}\", iter.collect::<Vec<_>>());\n"
" Ok(())\n"
"}\n"
"```"
msgstr ""
#: src/welcome-day-4.md:1
msgid "# Welcome to Day 4"
msgstr "# 4일차 개요"
#: src/welcome-day-4.md:3
msgid "Today we will look at two main topics:"
msgstr "오늘 강의는 두 가지 주제를 다룹니다:"
#: src/welcome-day-4.md:5
msgid "* Concurrency: threads, channels, shared state, `Send` and `Sync`."
msgstr "* 동시성: 쓰레드, 채널, 상태 공유, `Send`와 `Sync`"
#: src/welcome-day-4.md:7
msgid ""
"* Android: building binaries and libraries, using AIDL, logging, and\n"
" interoperability with C, C++, and Java."
msgstr ""
"* 안드로이드: 바이너리와 라이브러리 만드는 방법, AIDL 사용법, 로깅하는 방법, "
"C/C++, 자바와의 상호 운용성"
#: src/welcome-day-4.md:10
msgid ""
"> We will attempt to call Rust from one of your own projects today. So try "
"to\n"
"> find a little corner of your code base where we can move some lines of "
"code to\n"
"> Rust. The fewer dependencies and \"exotic\" types the better. Something "
"that\n"
"> parses some raw bytes would be ideal."
msgstr ""
"> 우리는 오늘 여러분의 프로젝트에서 러스트 코드를 호출해볼 것입니다. 그 프로젝트에서 \n"
"> 러스트로 옮길만 한 작은 부분을 정하세요. 의존성이 적고 \"특이한\" 타입이 적을 수록 \n"
"> 좋습니다. 바이트 몇 개를 파싱하는 코드라면 완벽합니다."
#: src/concurrency.md:1
msgid "# Fearless Concurrency"
msgstr "# 겂없는 동시성"
#: src/concurrency.md:3
msgid ""
"Rust has full support for concurrency using OS threads with mutexes and\n"
"channels."
msgstr ""
"러스트는 동시성 지원이 막강합니다. 운영체제 레벨의 스레드를 사용하며, 뮤택스와 채널도 지원합니다."
#: src/concurrency.md:6
msgid ""
"The Rust type system plays an important role in making many concurrency "
"bugs\n"
"compile time bugs. This is often referred to as _fearless concurrency_ since "
"you\n"
"can rely on the compiler to ensure correctness at runtime."
msgstr ""
"러스트의 타입 시스템은 프로그램에 동시성 버그가 있을 경우, 컴파일 시에 에러가 "
"발생하도록 해 줍니다. 컴파일러를 이용해서 프로그램이 수행시에 정확히 동작함을 "
"미리 보장해 주기 때문에, 사람들은 이를 종종 _겁없는 동시성_ 이라고 합니다."
#: src/concurrency/threads.md:1
msgid "# Threads"
msgstr "# 스레드"
#: src/concurrency/threads.md:3
msgid "Rust threads work similarly to threads in other languages:"
msgstr "러스트의 스레드는 다른 언어의 스레드와 유사하게 동작합니다:"
#: src/concurrency/threads.md:5
msgid ""
"```rust,editable\n"
"use std::thread;\n"
"use std::time::Duration;"
msgstr ""
#: src/concurrency/threads.md:9
msgid ""
"fn main() {\n"
" thread::spawn(|| {\n"
" for i in 1..10 {\n"
" println!(\"Count in thread: {i}!\");\n"
" thread::sleep(Duration::from_millis(5));\n"
" }\n"
" });"
msgstr ""
#: src/concurrency/threads.md:17
msgid ""
" for i in 1..5 {\n"
" println!(\"Main thread: {i}\");\n"
" thread::sleep(Duration::from_millis(5));\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/concurrency/threads.md:24
msgid ""
"* Threads are all daemon threads, the main thread does not wait for them.\n"
"* Thread panics are independent of each other.\n"
" * Panics can carry a payload, which can be unpacked with `downcast_ref`."
msgstr ""
"* 스레드는 모두 데몬 스레드입니다. 따라서 메인 스레드는 이 스레드들이 끝나기를 "
"기다리지 않습니다.\n"
"* 한 스레드에서 발생한 패닉은 다른 스레드에게 영향을 끼치지 않습니다.\n"
" * 패닉은 추가정보(페이로드)를 포함할 수 있으며, 이는 `downcast_ref`로 풀어볼 수 있습니다."
#: src/concurrency/threads.md:32
msgid ""
"* Notice that the thread is stopped before it reaches 10 — the main thread "
"is\n"
" not waiting."
msgstr ""
"* 메인 스레드가 자식 스레드를 기다리지 않기 때문에 자식 스레드의 for문은 10까지 가지 않습니다."
#: src/concurrency/threads.md:35
msgid ""
"* Use `let handle = thread::spawn(...)` and later `handle.join()` to wait "
"for\n"
" the thread to finish."
msgstr ""
"* 만약 메인 스레드가 자식 스레드가 끝날 때 까지 기다리기를 원한다면 `let handle = thread::"
"spawn(...)`으로 스레드를 선언한 후 `handle.join()`로 연결하여 사용합니다."
#: src/concurrency/threads.md:38
msgid "* Trigger a panic in the thread, notice how this doesn't affect `main`."
msgstr ""
"* 자식 스레드에서 발생한 패닉이 메인 스레드에는 영향을 주지 않음을 확인하"
"시기 바랍니다."
#: src/concurrency/threads.md:40
msgid ""
"* Use the `Result` return value from `handle.join()` to get access to the "
"panic\n"
" payload. This is a good time to talk about [`Any`]."
msgstr ""
"* `handle.join()`사용시 `Result` 반환값을 통해 패닉의 추가정보에 접근할 수 있습"
"니다. 이 시점에서 [`Any`]에 대해 이야기를 해 보면 좋습니다."
#: src/concurrency/threads.md:43
msgid "[`Any`]: https://doc.rust-lang.org/std/any/index.html"
msgstr ""
#: src/concurrency/scoped-threads.md:1
msgid "# Scoped Threads"
msgstr "# 범위 스레드(Scoped Threads)"
#: src/concurrency/scoped-threads.md:3
msgid "Normal threads cannot borrow from their environment:"
msgstr "보통, 스레드는 스레드 밖에서 데이터를 빌릴 수 없습니다."
#: src/concurrency/scoped-threads.md:5
msgid ""
"```rust,editable,compile_fail\n"
"use std::thread;"
msgstr ""
#: src/concurrency/scoped-threads.md:8 src/concurrency/scoped-threads.md:22
msgid ""
"fn main() {\n"
" let s = String::from(\"Hello\");"
msgstr ""
#: src/concurrency/scoped-threads.md:11
msgid ""
" thread::spawn(|| {\n"
" println!(\"Length: {}\", s.len());\n"
" });\n"
"}\n"
"```"
msgstr ""
#: src/concurrency/scoped-threads.md:17
msgid "However, you can use a [scoped thread][1] for this:"
msgstr "하지만, [scoped thread][1]에서는 가능합니다:"
#: src/concurrency/scoped-threads.md:19
msgid ""
"```rust,editable\n"
"use std::thread;"
msgstr ""
#: src/concurrency/scoped-threads.md:25
msgid ""
" thread::scope(|scope| {\n"
" scope.spawn(|| {\n"
" println!(\"Length: {}\", s.len());\n"
" });\n"
" });\n"
"}\n"
"```"
msgstr ""
#: src/concurrency/scoped-threads.md:33
msgid "[1]: https://doc.rust-lang.org/std/thread/fn.scope.html"
msgstr ""
#: src/concurrency/scoped-threads.md:35
msgid ""
"<details>\n"
" \n"
"* The reason for that is that when the `thread::scope` function completes, "
"all the threads are guaranteed to be joined, so they can return borrowed "
"data.\n"
"* Normal Rust borrowing rules apply: you can either borrow mutably by one "
"thread, or immutably by any number of threads.\n"
" \n"
"</details>"
msgstr ""
"<details>\n"
" \n"
"* `thread::scope` 함수가 완료되면 그 안에서 생성된 모든 스레드들이 종료했음이 "
"보장되기 때문에, 그 때 빌렸던 데이터들을 다시 반환할 수 있기 때문입니다.\n"
"* 일반적인 러스트의 빌림 규칙이 적용됩니다: 한 스레드에 의한 가변 빌림 또는 "
"여러 스레드에 대한 불변 빌림중 하나만 가능합니다.\n"
" \n"
"</details>"
#: src/concurrency/channels.md:1
msgid "# Channels"
msgstr "# 채널"
#: src/concurrency/channels.md:3
msgid ""
"Rust channels have two parts: a `Sender<T>` and a `Receiver<T>`. The two "
"parts\n"
"are connected via the channel, but you only see the end-points."
msgstr ""
"러스트의 채널은 `Sender<T>` 와 `Receiver<T>` 두 부분으로 구성됩니다.\n"
"이 둘은 채널을 통해 서로 연결되어 있지만, 우리는 채널을 볼 수는 없고 이 양 "
"끝단만을 사용하게 됩니다."
#: src/concurrency/channels.md:6
msgid ""
"```rust,editable\n"
"use std::sync::mpsc;\n"
"use std::thread;"
msgstr ""
#: src/concurrency/channels.md:10 src/concurrency/channels/unbounded.md:10
msgid ""
"fn main() {\n"
" let (tx, rx) = mpsc::channel();"
msgstr ""
#: src/concurrency/channels.md:13
msgid ""
" tx.send(10).unwrap();\n"
" tx.send(20).unwrap();"
msgstr ""
#: src/concurrency/channels.md:16
msgid ""
" println!(\"Received: {:?}\", rx.recv());\n"
" println!(\"Received: {:?}\", rx.recv());"
msgstr ""
#: src/concurrency/channels.md:19
msgid ""
" let tx2 = tx.clone();\n"
" tx2.send(30).unwrap();\n"
" println!(\"Received: {:?}\", rx.recv());\n"
"}\n"
"```"
msgstr ""
#: src/concurrency/channels.md:27
msgid ""
"* `send()` and `recv()` return `Result`. If they return `Err`, it means the "
"counterpart `Sender` or `Receiver` is dropped and the channel is closed."
msgstr ""
"* `send()`와 `recv()`는 `Result`를 반환합니다. 만일 `Err`가 반환된다면, 상대"
"방의 `Sender`또는 `Receiver`가 삭제되었고 채널이 닫혔다는 뜻입니다."
#: src/concurrency/channels/unbounded.md:1
msgid "# Unbounded Channels"
msgstr "# 무경계 채널(Unbounded Channels)"
#: src/concurrency/channels/unbounded.md:3
msgid "You get an unbounded and asynchronous channel with `mpsc::channel()`:"
msgstr "`mpsc::channel()` 함수는 경계가 없는 비동기 채널을 생성합니다: "
#: src/concurrency/channels/unbounded.md:5
#: src/concurrency/channels/bounded.md:5
msgid ""
"```rust,editable\n"
"use std::sync::mpsc;\n"
"use std::thread;\n"
"use std::time::Duration;"
msgstr ""
#: src/concurrency/channels/unbounded.md:13
#: src/concurrency/channels/bounded.md:13
msgid ""
" thread::spawn(move || {\n"
" let thread_id = thread::current().id();\n"
" for i in 1..10 {\n"
" tx.send(format!(\"Message {i}\")).unwrap();\n"
" println!(\"{thread_id:?}: sent Message {i}\");\n"
" }\n"
" println!(\"{thread_id:?}: done\");\n"
" });\n"
" thread::sleep(Duration::from_millis(100));"
msgstr ""
#: src/concurrency/channels/unbounded.md:23
#: src/concurrency/channels/bounded.md:23
msgid ""
" for msg in rx.iter() {\n"
" println!(\"Main: got {}\", msg);\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/concurrency/channels/bounded.md:1
msgid "# Bounded Channels"
msgstr "# 경계가 있는 채널(Bounded Channels)"
#: src/concurrency/channels/bounded.md:3
msgid "Bounded and synchronous channels make `send` block the current thread:"
msgstr "경계가 있는 동기 채널은 `send`가 현제 스레드를 블로킹 하도록 만듭니다:"
#: src/concurrency/channels/bounded.md:10
msgid ""
"fn main() {\n"
" let (tx, rx) = mpsc::sync_channel(3);"
msgstr ""
#: src/concurrency/shared_state.md:1
msgid "# Shared State"
msgstr "# 상태 공유(Shared State)"
#: src/concurrency/shared_state.md:3
msgid ""
"Rust uses the type system to enforce synchronization of shared data. This "
"is\n"
"primarily done via two types:"
msgstr ""
"러스트는 주로 아래 두 가지 타입을 이용해서 공유 데이터 동기화를 수행합"
"니다: "
#: src/concurrency/shared_state.md:6
msgid ""
"* [`Arc<T>`][1], atomic reference counted `T`: handled sharing between "
"threads and\n"
" takes care to deallocate `T` when the last thread exits,\n"
"* [`Mutex<T>`][2]: ensures mutual exclusion access to the `T` value."
msgstr ""
"* [`Arc<T>`][1], `T`에 대한 아토믹 참조 카운트: 이 참조는 다수의 스레드 사이에서 "
"공유될 수 있고, 참조하던 마지막 스레드가 종료할 경우 `T`를 반환합니다.\n"
"* [`Mutex<T>`][2]: `T`값에 대한 상호 배제 엑세스를 보장합니다."
#: src/concurrency/shared_state.md:10
msgid ""
"[1]: https://doc.rust-lang.org/std/sync/struct.Arc.html\n"
"[2]: https://doc.rust-lang.org/std/sync/struct.Mutex.html"
msgstr ""
"[1]: https://doc.rust-lang.org/std/sync/struct.Arc.html\n"
"[2]: https://doc.rust-lang.org/std/sync/struct.Mutex.html"
#: src/concurrency/shared_state/arc.md:1
msgid "# `Arc`"
msgstr "# `Arc`"
#: src/concurrency/shared_state/arc.md:3
msgid "[`Arc<T>`][1] allows shared read-only access via its `clone` method:"
msgstr "[`Arc<T>`][1]의 `clone` 메서드를 이용하면 여러 스레드가 한 데이터를 동시에 "
"(_역주_: 그리고 안전하게. 스레드가 하나라도 살아있는 동안에는 `T`가 반환되지 않음) "
"읽을 수 있습니다:"
#: src/concurrency/shared_state/arc.md:5
msgid ""
"```rust,editable\n"
"use std::thread;\n"
"use std::sync::Arc;"
msgstr ""
#: src/concurrency/shared_state/arc.md:9
msgid ""
"fn main() {\n"
" let v = Arc::new(vec![10, 20, 30]);\n"
" let mut handles = Vec::new();\n"
" for _ in 1..5 {\n"
" let v = v.clone();\n"
" handles.push(thread::spawn(move || {\n"
" let thread_id = thread::current().id();\n"
" println!(\"{thread_id:?}: {v:?}\");\n"
" }));\n"
" }"
msgstr ""
#: src/concurrency/shared_state/arc.md:20
msgid ""
" handles.into_iter().for_each(|h| h.join().unwrap());\n"
" println!(\"v: {v:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/concurrency/shared_state/arc.md:25
msgid "[1]: https://doc.rust-lang.org/std/sync/struct.Arc.html"
msgstr ""
#: src/concurrency/shared_state/arc.md:29
msgid ""
"* `Arc` stands for \"Atomic Reference Counted\", a thread safe version of "
"`Rc` that uses atomic operations.\n"
"* `Arc::clone()` has the cost of atomic operations that get executed, but "
"after that the use of the `T` is free.\n"
"* Beware of reference cycles, Rust does not have a garbage collector to "
"detect those.\n"
" * `std::sync::Weak` can help.\n"
" \n"
"</details>"
msgstr ""
"* `Arc`는 \"Atomic Reference Counted\"를 의미하며, 스레드 안정성을 보장하는 "
"`Rc`라고 생각하면 됩니다.\n"
"* `Arc::clone()`는 아토믹 연산을 수행하기 때문에 그 때 코스트가 좀 있지만, "
"일단 `clone()`이 끝난 후 `T`를 사용하는 대에는 아무런 오버헤드가 없습니다.\n"
"* 순환 참조가 발생하지 않도록 주의해야 합니다. 러스트는 순환 참조를 감지하는 "
"가비지 컬랙터가 없습니다.\n"
" * 순환 참조를 피하는데 `std::sync::Weak`가 도움이 될 것입니다.\n"
"</details>"
#: src/concurrency/shared_state/mutex.md:1
msgid "# `Mutex`"
msgstr "# `Mutex`"
#: src/concurrency/shared_state/mutex.md:3
msgid ""
"[`Mutex<T>`][1] ensures mutual exclusion _and_ allows mutable access to `T`\n"
"behind a read-only interface:"
msgstr ""
"[`Mutex<T>`][1]를 이용하면 불변 참조를 통해서도 `T`의 값을 수정할 수가 있으며, "
"_이에 더해서_ 한 번에 한 스레드만 `T`의 값을 접근(읽거나 쓰거나)함을 보장해 줍니다:"
#: src/concurrency/shared_state/mutex.md:6
msgid ""
"```rust,editable\n"
"use std::sync::Mutex;"
msgstr ""
#: src/concurrency/shared_state/mutex.md:9
msgid ""
"fn main() {\n"
" let v: Mutex<Vec<i32>> = Mutex::new(vec![10, 20, 30]);\n"
" println!(\"v: {:?}\", v.lock().unwrap());"
msgstr ""
#: src/concurrency/shared_state/mutex.md:13
msgid ""
" {\n"
" let v: &Mutex<Vec<i32>> = &v;\n"
" let mut guard = v.lock().unwrap();\n"
" guard.push(40);\n"
" }"
msgstr ""
#: src/concurrency/shared_state/mutex.md:19
msgid ""
" println!(\"v: {:?}\", v.lock().unwrap());\n"
"}\n"
"```"
msgstr ""
#: src/concurrency/shared_state/mutex.md:23
msgid ""
"Notice how we have a [`impl<T: Send> Sync for Mutex<T>`][2] blanket\n"
"implementation."
msgstr ""
"모든 `Mutex<T>`는 [`impl<T: Send> Sync for Mutex<T>`][2]를 자동으로 구현함을 참조하세요."
#: src/concurrency/shared_state/mutex.md:26
msgid ""
"[1]: https://doc.rust-lang.org/std/sync/struct.Mutex.html\n"
"[2]: https://doc.rust-lang.org/std/sync/struct.Mutex.html#impl-Sync-for-"
"Mutex%3CT%3E\n"
"[3]: https://doc.rust-lang.org/std/sync/struct.Arc.html"
msgstr ""
#: src/concurrency/shared_state/mutex.md:30
msgid ""
"<details>\n"
" \n"
"* `Mutex` in Rust looks like a collection with just one element - the "
"protected data.\n"
" * It is not possible to forget to acquire the mutex before accessing the "
"protected data.\n"
"* A read-write lock counterpart - `RwLock`.\n"
"* Why does `lock()` return a `Result`? \n"
" * If the thread that held the `Mutex` panicked, the `Mutex` becomes "
"\"poisoned\" to signal that the data it protected might be in an "
"inconsistent state. Calling `lock()` on a poisoned mutex fails with a "
"[`PoisonError`]. You can call `into_inner()` on the error to recover the "
"data regardless."
msgstr ""
"<details>\n"
" \n"
"* 러스트의 `Mutex`는 오직 하나의 데이터만 담을 수 있는 컬렉션처럼 볼 수도"
" 있습니다. 다른 컬렉션과 다른 점은, 그 데이터가 동시성 문제로부터 자유롭다는"
" 점입니다.\n"
" * `Mutex`는 뮤텍스를 획득하지 않으면 보호된 데이터에 접근하는 것이 불가능"
" 하도록 디자인 되어 있습니다.\n"
"* `Mutex`는 읽기와 쓰기에 대한 잠금을 구별하지 않기 때문에 여러 스레드에서"
" 데이터를 \"읽기\"만 하려고 해도 이를 동시에 허용하지 않습니다. 즉, 한 번에 한"
" 스레드에서의 읽기만 허용이 됩니다. \"읽기\"에 대한 동시성을 지원하면서"
" \"쓰기\"에 대해서 안전하고 싶다면 `RwLock`을 사용할 수 있습니다.\n"
"* 왜 `lock()`이 `Result`를 반환할까요?\n"
" * `Mutex`를 획득한 스레드에서 패닉이 발생하면, 데이터가 올바르지 않은 상황이"
" 될 수 있습니다. 이를 `Mutex`가 \"중독(poisoned)\" 되었다고 표현하며, 중독된"
" 뮤텍스에서 `lock()`을 호출하면 실패하고 [`PoisonError`]가 발생합니다."
" 이러한 오류로부터 데이터를 복구하기 위해 `into_inner()`를 호출할 수 있습니다."
#: src/concurrency/shared_state/mutex.md:38
msgid ""
"[`PoisonError`]: https://doc.rust-lang.org/std/sync/struct.PoisonError."
"html \n"
" \n"
"</details>"
msgstr ""
#: src/concurrency/shared_state/example.md:3
msgid "Let us see `Arc` and `Mutex` in action:"
msgstr "`Arc`와 `Mutex`의 동작을 살펴봅시다:"
#: src/concurrency/shared_state/example.md:5
msgid ""
"```rust,editable,compile_fail\n"
"use std::thread;\n"
"// use std::sync::{Arc, Mutex};"
msgstr ""
#: src/concurrency/shared_state/example.md:9
msgid ""
"fn main() {\n"
" let mut v = vec![10, 20, 30];\n"
" let handle = thread::spawn(|| {\n"
" v.push(10);\n"
" });\n"
" v.push(1000);"
msgstr ""
#: src/concurrency/shared_state/example.md:16
msgid ""
" handle.join().unwrap();\n"
" println!(\"v: {v:?}\");\n"
"}\n"
"```"
msgstr ""
#: src/concurrency/shared_state/example.md:23
msgid ""
"Possible solution:\n"
" \n"
"```rust,editable\n"
"use std::sync::{Arc, Mutex};\n"
"use std::thread;"
msgstr ""
"가능한 해결방법입니다.:\n"
" \n"
"```rust,editable\n"
"use std::sync::{Arc, Mutex};\n"
"use std::thread;"
#: src/concurrency/shared_state/example.md:29
msgid ""
"fn main() {\n"
" let v = Arc::new(Mutex::new(vec![10, 20, 30]));"
msgstr ""
#: src/concurrency/shared_state/example.md:32
msgid ""
" let v2 = v.clone();\n"
" let handle = thread::spawn(move || {\n"
" let mut v2 = v2.lock().unwrap();\n"
" v2.push(10);\n"
" });"
msgstr ""
#: src/concurrency/shared_state/example.md:38
msgid ""
" {\n"
" let mut v = v.lock().unwrap();\n"
" v.push(1000);\n"
" }"
msgstr ""
#: src/concurrency/shared_state/example.md:43
msgid " handle.join().unwrap();"
msgstr ""
#: src/concurrency/shared_state/example.md:45
msgid ""
" {\n"
" let v = v.lock().unwrap();\n"
" println!(\"v: {v:?}\");\n"
" }\n"
"}\n"
"```\n"
" \n"
"Notable parts:"
msgstr ""
" {\n"
" let v = v.lock().unwrap();\n"
" println!(\"v: {v:?}\");\n"
" }\n"
"}\n"
"```\n"
" \n"
"참고 사항:"
#: src/concurrency/shared_state/example.md:54
msgid ""
"* `v` is wrapped in both `Arc` and `Mutex`, because their concerns are "
"orthogonal.\n"
"* `v: Arc<_>` needs to be cloned as `v2` before it can be moved into another "
"thread. Note `move` was added to the lambda signature.\n"
"* Blocks are introduced to narrow the scope of the `LockGuard` as much as "
"possible.\n"
"* We still need to acquire the `Mutex` to print our `Vec`."
msgstr ""
"* `v`는 `Arc`와 `Mutex` 모두에 포함되어 있습니다. 이는 `Arc`와 `Mutex`가 서로 "
"완전히 다른 문제를 위한 도구이기 때문입니다.\n"
"* `v: Arc<_>`를 다른 스레드에서 사용하려면, 먼저 `v2`로 복사를 하고 이를 그 "
"스레드로 이동 해야 합니다. 그래서 람다의 시그니처에 `move`가 있는 것입니다.\n"
"* 블록은 `LockGuard`의 범위를 최대한 좁히기 위해 사용되었습니다.\n"
"* `Vec`을 단순히 출력하기 위해서도 여전히 `Mutex`를 획득해야 합니다."
#: src/concurrency/send-sync.md:1
msgid "# `Send` and `Sync`"
msgstr "# `Send`와 `Sync`"
#: src/concurrency/send-sync.md:3
msgid ""
"How does Rust know to forbid shared access across thread? The answer is in "
"two traits:"
msgstr ""
"러스트는 어떻게 해서 스레드 간에 특정 데이터 타입이 공유될 수 있거나, 안된다는 것을 "
"알까요? 정답은 다음 두 트레이트에 있습니다:"
#: src/concurrency/send-sync.md:5
msgid ""
"* [`Send`][1]: a type `T` is `Send` if it is safe to move a `T` across a "
"thread\n"
" boundary.\n"
"* [`Sync`][2]: a type `T` is `Sync` if it is safe to move a `&T` across a "
"thread\n"
" boundary."
msgstr ""
"* [`Send`][1]: `T`가 스레드 간 이동이 안전하다면, `T`의 타입은 `Send`입니"
"다.\n"
"* [`Sync`][2]: `&T`가 스레드 간 이동이 안전하다면, `&T`의 타입은 `Sync`입니"
"다."
#: src/concurrency/send-sync.md:10
msgid ""
"Both traits are not to be implemented. They are implemented automatically "
"when \n"
"the compiler determines it’s appropriate."
msgstr ""
"이 트레이트는 프로그래머가 수동으로 구현을 해야 하는 트레이트가 아닙니다. "
"컴파일러는 적당하다고 판단되면 이 두 트레이트를 자동으로 구현합니다."
#: src/concurrency/send-sync.md:13
msgid ""
"[1]: https://doc.rust-lang.org/std/marker/trait.Send.html\n"
"[2]: https://doc.rust-lang.org/std/marker/trait.Sync.html"
msgstr ""
#: src/concurrency/send-sync.md:18
msgid ""
"* One can think of these traits as markers that the type has certain\n"
" thread-safety properties.\n"
"* They can be used in the generic constraints as normal traits.\n"
" \n"
"</details>"
msgstr ""
"* `Sync`와 `Send`는 어떤 타입이 특정한 스레드-안전 속성을 가짐을 나타내는 마커로 "
"생각할 수 있습니다.\n"
"* 이 두 트레이트는 제너릭에서 제약 조건을 나타내는 트레이트로 사용될 수도 있습니다.\n"
"</details>"
#: src/concurrency/send-sync/send.md:1
msgid "# `Send`"
msgstr "# `Send`"
#: src/concurrency/send-sync/send.md:3
msgid ""
"> A type `T` is [`Send`][1] if it is safe to move a `T` value to another "
"thread."
msgstr "> `T`가 스레드 간에 안전하게 이동될 수 있다면, `T`의 타입은 `Send`입니다."
#: src/concurrency/send-sync/send.md:5
msgid ""
"The effect of moving ownership to another thread is that _destructors_ will "
"run\n"
"in that thread. So the question is when you can allocate a value in one "
"thread\n"
"and deallocate it in another."
msgstr ""
"소유권을 다른 스레드로 이동하면 소멸자가 해당 스레드에서 실행됩니다. \n"
"여기서 의문은 \"언제 한 스레드에서 값을 할당하고 다른 스레드에서 값을 할당 해"
"제할 수 있는가\" 입니다. "
#: src/concurrency/send-sync/send.md:9
msgid "[1]: https://doc.rust-lang.org/std/marker/trait.Send.html"
msgstr ""
#: src/concurrency/send-sync/sync.md:1
msgid "# `Sync`"
msgstr "# `Sync`"
#: src/concurrency/send-sync/sync.md:3
msgid ""
"> A type `T` is [`Sync`][1] if it is safe to access a `T` value from "
"multiple\n"
"> threads at the same time."
msgstr ""
"> `&T`가 여러 스레드에서 안전하게 접근될 수 있다면, `&T`의 타입은 `Sync`입니다."
#: src/concurrency/send-sync/sync.md:6
msgid "More precisely, the definition is:"
msgstr "좀 더 정확한 정의는 다음과 같습니다:"
#: src/concurrency/send-sync/sync.md:8
msgid "> `T` is `Sync` if and only if `&T` is `Send`"
msgstr "`&T`가 `Send`인 경우에만 `T`의 타입이 `Sync`가 됩니다."
#: src/concurrency/send-sync/sync.md:10
msgid "[1]: https://doc.rust-lang.org/std/marker/trait.Sync.html"
msgstr ""
#: src/concurrency/send-sync/sync.md:14
msgid ""
"This statement is essentially a shorthand way of saying that if a type is "
"thread-safe for shared use, it is also thread-safe to pass references of it "
"across threads."
msgstr ""
"위 문장을 풀어서 이야기 하면, 어떤 타입이 스레드 간에 공유되어서 사용되기에 안전하다면 "
"그 타입의 참조 타입은 스레드 간에 이동 가능하다는 것입니다."
#: src/concurrency/send-sync/sync.md:16
msgid ""
"This is because if a type is Sync it means that it can be shared across "
"multiple threads without the risk of data races or other synchronization "
"issues, so it is safe to move it to another thread. A reference to the type "
"is also safe to move to another thread, because the data it references can "
"be accessed from any thread safely."
msgstr ""
"이는 다음과 같이 증명할 수 있습니다: 어떤 타입이 `Sync`라는 말은 곧 그 타입이 여러 스레드들 사이에서 "
"데이터 레이스나 여타 동기화 문제 없이 공유 가능하다는 말입니다. "
"스레드 간 공유가 안전하다면, 스레드간 이동도 안전할 수 밖에 없습니다. "
"어떤 타입의 스레드간 이동이 안전하다면, 그 타입의 참조 또한 스레드간 이동이 "
"안전할 수 밖에 없습니다."
#: src/concurrency/send-sync/examples.md:1
msgid "# Examples"
msgstr "# 예제"
#: src/concurrency/send-sync/examples.md:3
msgid "## `Send + Sync`"
msgstr ""
#: src/concurrency/send-sync/examples.md:5
msgid "Most types you come across are `Send + Sync`:"
msgstr "여러분이 다루게 될 대부분의 타입은 `Send + Sync`입니다:"
#: src/concurrency/send-sync/examples.md:7
msgid ""
"* `i8`, `f32`, `bool`, `char`, `&str`, ...\n"
"* `(T1, T2)`, `[T; N]`, `&[T]`, `struct { x: T }`, ...\n"
"* `String`, `Option<T>`, `Vec<T>`, `Box<T>`, ...\n"
"* `Arc<T>`: Explicitly thread-safe via atomic reference count.\n"
"* `Mutex<T>`: Explicitly thread-safe via internal locking.\n"
"* `AtomicBool`, `AtomicU8`, ...: Uses special atomic instructions."
msgstr ""
"* `i8`, `f32`, `bool`, `char`, `&str`, ...\n"
"* `(T1, T2)`, `[T; N]`, `&[T]`, `struct { x: T }`, ...\n"
"* `String`, `Option<T>`, `Vec<T>`, `Box<T>`, ...\n"
"* `Arc<T>`: 참조 카운트 조작을 아토믹 하기 때문에 스레드 안전함.\n"
"* `Mutex<T>`: 값을 접근하기 위해 뮤택스를 잠궈야 하기 때문에 스레드 안전함.\n"
"* `AtomicBool`, `AtomicU8`, ...: 값을 접근할 때 특별한 아토믹 명령어들을 사용합니다."
#: src/concurrency/send-sync/examples.md:14
msgid ""
"The generic types are typically `Send + Sync` when the type parameters are\n"
"`Send + Sync`."
msgstr ""
"제너릭 타입은 일반적으로 타입 파라메터가 `Send + Sync`이면 `Send + Sync` 입니"
"다."
#: src/concurrency/send-sync/examples.md:17
msgid "## `Send + !Sync`"
msgstr ""
#: src/concurrency/send-sync/examples.md:19
msgid ""
"These types can be moved to other threads, but they're not thread-safe.\n"
"Typically because of interior mutability:"
msgstr ""
"아래 타입들은 다른 스레드로 이동될 수 있지만 내부적으로 값이 변경될 수 있기 때문에 "
"스레드 안전하지 않습니다."
#: src/concurrency/send-sync/examples.md:22
msgid ""
"* `mpsc::Sender<T>`\n"
"* `mpsc::Receiver<T>`\n"
"* `Cell<T>`\n"
"* `RefCell<T>`"
msgstr ""
#: src/concurrency/send-sync/examples.md:27
msgid "## `!Send + Sync`"
msgstr ""
#: src/concurrency/send-sync/examples.md:29
msgid ""
"These types are thread-safe, but they cannot be moved to another thread:"
msgstr "아래 타입들은 스레드 안전하지만 다른 스레드로 이동될 수 없습니다:"
#: src/concurrency/send-sync/examples.md:31
msgid ""
"* `MutexGuard<T>`: Uses OS level primitives which must be deallocated on "
"the\n"
" thread which created them."
msgstr ""
"* `MutexGuard<T>`: 내부적으로, 운영체제가 제공하는 primitive를 사용하는데, 이 primitive는 "
"생성된 스레드에서 해제가 이루어져야 합니다. (_역주_: 그래서 다른 스레드로 옮길 수 없습니다.)"
#: src/concurrency/send-sync/examples.md:34
msgid "## `!Send + !Sync`"
msgstr ""
#: src/concurrency/send-sync/examples.md:36
msgid "These types are not thread-safe and cannot be moved to other threads:"
msgstr "아래 타입들은 스레드 안전하지도 않고 다른 스레드로 이동될 수도 없습니다:"
#: src/concurrency/send-sync/examples.md:38
msgid ""
"* `Rc<T>`: each `Rc<T>` has a reference to an `RcBox<T>`, which contains a\n"
" non-atomic reference count.\n"
"* `*const T`, `*mut T`: Rust assumes raw pointers may have special\n"
" concurrency considerations."
msgstr ""
"* `Rc<T>`: `Rc<T>` 는 아토믹하지 않은 방식으로 참조 카운트를 조작하는 `RcBox<T>`를 참조합"
"니다.\n"
"* `*const T`, `*mut T`: 러스트는 포인터가 스레드 안전하지 않다고 가정합니다."
#: src/exercises/day-4/morning.md:1 src/exercises/day-4/afternoon.md:1
msgid "# Exercises"
msgstr "# 연습문제"
#: src/exercises/day-4/morning.md:3
msgid "Let us practice our new concurrency skills with"
msgstr "동시성 기법들을 연습해 봅시다:"
#: src/exercises/day-4/morning.md:5
msgid "* Dining philosophers: a classic problem in concurrency."
msgstr "* 식사하는 철학자 문제: 고적적인 동시성 문제입니다."
#: src/exercises/day-4/morning.md:7
msgid ""
"* Multi-threaded link checker: a larger project where you'll use Cargo to\n"
" download dependencies and then check links in parallel."
msgstr ""
"* 멀티 스레드 링크 검사기: 병렬적으로 웹페이지의 링크들을 체크합니다. "
"카고를 통해 몇 가지 의존성들을 다운도르 받아야 하는 큰 프로젝트 입니다."
#: src/exercises/day-4/dining-philosophers.md:1
msgid "# Dining Philosophers"
msgstr "# 식사하는 철학자들"
#: src/exercises/day-4/dining-philosophers.md:3
msgid "The dining philosophers problem is a classic problem in concurrency:"
msgstr "식사하는 철학자 문제는 동시성에 있어서 고전적인 문제입니다:"
#: src/exercises/day-4/dining-philosophers.md:5
msgid ""
"> Five philosophers dine together at the same table. Each philosopher has "
"their\n"
"> own place at the table. There is a fork between each plate. The dish "
"served is\n"
"> a kind of spaghetti which has to be eaten with two forks. Each philosopher "
"can\n"
"> only alternately think and eat. Moreover, a philosopher can only eat "
"their\n"
"> spaghetti when they have both a left and right fork. Thus two forks will "
"only\n"
"> be available when their two nearest neighbors are thinking, not eating. "
"After\n"
"> an individual philosopher finishes eating, they will put down both forks."
msgstr ""
"> 5명의 철학자가 원탁에서 식사를 하고 있습니다. \n"
"> 철학자는 원탁에서 자신의 자리에 앉아있습니다.\n"
"> 포크는 각 접시 사이에 있습니다. \n"
"> 제공되는 요리를 먹기 위해서는 두 개의 포크를 모두 사용해야합니다.\n"
"> 철학자는 생각을 하다가 배가 고프면 자신의 좌,우의 포크를 들어 요리를 먹습니"
"다.\n"
"> 철학자는 요리를 먹은 후에는 포크를 다시 자리에 내려놓습니다.\n"
"> 철학자는 자신의 좌,우에 포크가 있을때만 요리를 먹을 수 있습니다.\n"
"> 따라서 두 개의 포크는 오직 자신의 좌,우 철학자가 생각을 할 때만 사용할 수 있"
"습니다."
#: src/exercises/day-4/dining-philosophers.md:13
msgid ""
"You will need a local [Cargo installation](../../cargo/running-locally.md) "
"for\n"
"this exercise. Copy the code below to `src/main.rs` file, fill out the "
"blanks,\n"
"and test that `cargo run` does not deadlock:"
msgstr ""
"이번 훈련에서는 [카고 설치하기](../../cargo/running-locally.md)가 필요합니"
"다.\n"
"아래 코드를 복사해서 `src/main.rs`에 붙여놓고 빈 부분을 채우고, `cargo run` "
"커맨드로 테스트 해서 교착상태(데드락)가 발생하지 않는지 확인합니다:"
#: src/exercises/day-4/dining-philosophers.md:17
msgid ""
"```rust,compile_fail\n"
"use std::sync::mpsc;\n"
"use std::sync::{Arc, Mutex};\n"
"use std::thread;\n"
"use std::time::Duration;"
msgstr ""
#: src/exercises/day-4/dining-philosophers.md:23
#: src/exercises/day-4/solutions-morning.md:28
msgid "struct Fork;"
msgstr ""
#: src/exercises/day-4/dining-philosophers.md:25
msgid ""
"struct Philosopher {\n"
" name: String,\n"
" // left_fork: ...\n"
" // right_fork: ...\n"
" // thoughts: ...\n"
"}"
msgstr ""
#: src/exercises/day-4/dining-philosophers.md:32
msgid ""
"impl Philosopher {\n"
" fn think(&self) {\n"
" self.thoughts\n"
" .send(format!(\"Eureka! {} has a new idea!\", &self.name))\n"
" .unwrap();\n"
" }"
msgstr ""
#: src/exercises/day-4/dining-philosophers.md:39
msgid ""
" fn eat(&self) {\n"
" // Pick up forks...\n"
" println!(\"{} is eating...\", &self.name);\n"
" thread::sleep(Duration::from_millis(10));\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-4/dining-philosophers.md:46
#: src/exercises/day-4/solutions-morning.md:60
msgid ""
"static PHILOSOPHERS: &[&str] =\n"
" &[\"Socrates\", \"Plato\", \"Aristotle\", \"Thales\", \"Pythagoras\"];"
msgstr ""
#: src/exercises/day-4/dining-philosophers.md:49
msgid ""
"fn main() {\n"
" // Create forks"
msgstr ""
#: src/exercises/day-4/dining-philosophers.md:52
msgid " // Create philosophers"
msgstr ""
#: src/exercises/day-4/dining-philosophers.md:54
msgid " // Make them think and eat"
msgstr ""
#: src/exercises/day-4/dining-philosophers.md:56
msgid ""
" // Output their thoughts\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-4/link-checker.md:1
msgid "# Multi-threaded Link Checker"
msgstr "# 멀티스레드 링크 검사기"
#: src/exercises/day-4/link-checker.md:3
msgid ""
"Let us use our new knowledge to create a multi-threaded link checker. It "
"should\n"
"start at a webpage and check that links on the page are valid. It should\n"
"recursively check other pages on the same domain and keep doing this until "
"all\n"
"pages have been validated."
msgstr ""
"새로 배운것들을 활용해서 멀티 스레드 링크 검사기를 만듭니다. \n"
"이 검사기는 웹페이지 안에 있는 링크들이 유효한지 확인합니다. \n"
"그리고 재귀적으로 동일 도메인의 다른 모든 페이지가 유효한지 확인합니다."
#: src/exercises/day-4/link-checker.md:8
msgid ""
"For this, you will need an HTTP client such as [`reqwest`][1]. Create a new\n"
"Cargo project and `reqwest` it as a dependency with:"
msgstr ""
"이를 위해서 [`reqwest`][1]와 같은 HTTP 클라이언트가 필요합니다. 새로운 로컬 "
"프로젝트를 만들고 [`reqwest`][1]를 의존성에 추가하십시요"
#: src/exercises/day-4/link-checker.md:11
msgid ""
"```shell\n"
"$ cargo new link-checker\n"
"$ cd link-checker\n"
"$ cargo add --features blocking,rustls-tls reqwest\n"
"```"
msgstr ""
#: src/exercises/day-4/link-checker.md:17
msgid ""
"> If `cargo add` fails with `error: no such subcommand`, then please edit "
"the\n"
"> `Cargo.toml` file by hand. Add the dependencies listed below."
msgstr ""
"> 만일 `cargo add` 커맨드가 `error: no such subcommand` 로 실패한다면 \n"
"> `Cargo.toml` 파일을 직접 수정해도 됩니다. 아래에 전체 의존성 내용이 있습니"
"다."
#: src/exercises/day-4/link-checker.md:20
msgid ""
"You will also need a way to find links. We can use [`scraper`][2] for that:"
msgstr "링크를 찾기 위해서 [`scraper`][2]도 추가합니다:"
#: src/exercises/day-4/link-checker.md:22
msgid ""
"```shell\n"
"$ cargo add scraper\n"
"```"
msgstr ""
#: src/exercises/day-4/link-checker.md:26
msgid ""
"Finally, we'll need some way of handling errors. We [`thiserror`][3] for "
"that:"
msgstr "마지막으로 오류 처리하는 방법으로 [`thiserror`][3]도 추가합니다:"
#: src/exercises/day-4/link-checker.md:28
msgid ""
"```shell\n"
"$ cargo add thiserror\n"
"```"
msgstr ""
#: src/exercises/day-4/link-checker.md:32
msgid ""
"The `cargo add` calls will update the `Cargo.toml` file to look like this:"
msgstr "모든 `cargo add`가 끝나면 `Cargo.toml`에 아래 내용이 추가됩니다:"
#: src/exercises/day-4/link-checker.md:34
msgid ""
"```toml\n"
"[dependencies]\n"
"reqwest = { version = \"0.11.12\", features = [\"blocking\", \"rustls-"
"tls\"] }\n"
"scraper = \"0.13.0\"\n"
"thiserror = \"1.0.37\"\n"
"```"
msgstr ""
#: src/exercises/day-4/link-checker.md:41
msgid ""
"You can now download the start page. Try with a small site such as\n"
"`https://www.google.org/`."
msgstr "이제 `https://www.google.org/` 같은 웹 페이지를 탐색할 수 있습니다. "
#: src/exercises/day-4/link-checker.md:44
msgid "Your `src/main.rs` file should look something like this:"
msgstr "`rc/main.rs`파일은 아래와 같습니다:"
#: src/exercises/day-4/link-checker.md:46
msgid ""
"```rust,compile_fail\n"
"use reqwest::blocking::{get, Response};\n"
"use reqwest::Url;\n"
"use scraper::{Html, Selector};\n"
"use thiserror::Error;"
msgstr ""
#: src/exercises/day-4/link-checker.md:52
msgid ""
"#[derive(Error, Debug)]\n"
"enum Error {\n"
" #[error(\"request error: {0}\")]\n"
" ReqwestError(#[from] reqwest::Error),\n"
"}"
msgstr ""
#: src/exercises/day-4/link-checker.md:58
msgid ""
"fn extract_links(response: Response) -> Result<Vec<Url>, Error> {\n"
" let base_url = response.url().to_owned();\n"
" let document = response.text()?;\n"
" let html = Html::parse_document(&document);\n"
" let selector = Selector::parse(\"a\").unwrap();"
msgstr ""
#: src/exercises/day-4/link-checker.md:64
msgid ""
" let mut valid_urls = Vec::new();\n"
" for element in html.select(&selector) {\n"
" if let Some(href) = element.value().attr(\"href\") {\n"
" match base_url.join(href) {\n"
" Ok(url) => valid_urls.push(url),\n"
" Err(err) => {\n"
" println!(\"On {base_url}: could not parse {href:?}: "
"{err} (ignored)\",);\n"
" }\n"
" }\n"
" }\n"
" }"
msgstr ""
#: src/exercises/day-4/link-checker.md:76
msgid ""
" Ok(valid_urls)\n"
"}"
msgstr ""
#: src/exercises/day-4/link-checker.md:79
msgid ""
"fn main() {\n"
" let start_url = Url::parse(\"https://www.google.org\").unwrap();\n"
" let response = get(start_url).unwrap();\n"
" match extract_links(response) {\n"
" Ok(links) => println!(\"Links: {links:#?}\"),\n"
" Err(err) => println!(\"Could not extract links: {err:#}\"),\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-4/link-checker.md:89
msgid "Run the code in `src/main.rs` with"
msgstr "아래 커맨드로 소스를 실행합니다: "
#: src/exercises/day-4/link-checker.md:91
msgid ""
"```shell\n"
"$ cargo run\n"
"```"
msgstr ""
#: src/exercises/day-4/link-checker.md:95
msgid "## Tasks"
msgstr "## 할 일"
#: src/exercises/day-4/link-checker.md:97
msgid ""
"* Use threads to check the links in parallel: send the URLs to be checked to "
"a\n"
" channel and let a few threads check the URLs in parallel.\n"
"* Extend this to recursively extract links from all pages on the\n"
" `www.google.org` domain. Put an upper limit of 100 pages or so so that "
"you\n"
" don't end up being blocked by the site."
msgstr ""
"* 스레드를 사용하여 링크를 병렬로 확인합니다: URL을 채널로 보내서 몇 개의 스"
"레드가 URL을 병렬로 체크하도록 합니다.\n"
"* `www.google.org`도메인의 모든 페이지를 재귀적으로 확인하기 위해 코드를 확장"
"해서 작성합니다: 차단당하지 않도록 100페이지 정도로 제한을 두시"
"기 바랍니다."
#: src/exercises/day-4/link-checker.md:103
msgid ""
"[1]: https://docs.rs/reqwest/\n"
"[2]: https://docs.rs/scraper/\n"
"[3]: https://docs.rs/thiserror/"
msgstr ""
#: src/android.md:1
msgid "# Android"
msgstr "# 안드로이드"
#: src/android.md:3
msgid ""
"Rust is supported for native platform development on Android. This means "
"that\n"
"you can write new operating system services in Rust, as well as extending\n"
"existing services."
msgstr ""
"러스트는 안드로이드 네이티브 플랫폼 개발을 지원합니다. 기존의 OS 서비스를 "
"확장하거나, 새로운 서비스를 만드는데 러스트를 쓸 수 있습니다."
#: src/android/setup.md:1
msgid "# Setup"
msgstr "# 설치"
#: src/android/setup.md:3
msgid ""
"We will be using an Android Virtual Device to test our code. Make sure you "
"have\n"
"access to one or create a new one with:"
msgstr ""
"안드로이드 가상 디바이스(Android Virtual Device)를 사용하여 여러분의 코드를 "
"수행할 겁니다. 새로운 가상 디바이스를 생성하려면 아래의 명령어를 사용하세요."
#: src/android/setup.md:6
msgid ""
"```shell\n"
"$ source build/envsetup.sh\n"
"$ lunch aosp_cf_x86_64_phone-userdebug\n"
"$ acloud create\n"
"```"
msgstr ""
#: src/android/setup.md:12
msgid ""
"Please see the [Android Developer\n"
"Codelab](https://source.android.com/docs/setup/start) for details."
msgstr ""
"자세한 내용은 [Android Developer\n"
"Codelab](https://source.android.com/docs/setup/start)을 참조하십시오."
#: src/android/build-rules.md:1
msgid "# Build Rules"
msgstr "# 빌드 규칙(Build Rules)"
#: src/android/build-rules.md:3
msgid "The Android build system (Soong) supports Rust via a number of modules:"
msgstr ""
"안드로이드 빌드 시스템(Soong)은 다음과 같은 여러 모듈을 통해 러스트를 지원합"
"니다:"
#: src/android/build-rules.md:5
msgid ""
"| Module Type | "
"Description "
"|\n"
"|-------------------|----------------------------------------------------------------------------------------------------|\n"
"| `rust_binary` | Produces a Rust "
"binary. "
"|\n"
"| `rust_library` | Produces a Rust library, and provides both `rlib` and "
"`dylib` variants. |\n"
"| `rust_ffi` | Produces a Rust C library usable by `cc` modules, and "
"provides both static and shared variants. |\n"
"| `rust_proc_macro` | Produces a `proc-macro` Rust library. These are "
"analogous to compiler plugins. |\n"
"| `rust_test` | Produces a Rust test binary that uses the standard "
"Rust test harness. |\n"
"| `rust_fuzz` | Produces a Rust fuzz binary leveraging "
"`libfuzzer`. |\n"
"| `rust_protobuf` | Generates source and produces a Rust library that "
"provides an interface for a particular protobuf. |\n"
"| `rust_bindgen` | Generates source and produces a Rust library "
"containing Rust bindings to C libraries. |"
msgstr ""
"| Module Type | Description "
"|\n"
"|-------------------|------------------------------------------------------|\n"
"| `rust_binary` | 러스트 바이너리를 생성합니다.|\n"
"| `rust_library` | 러스트 라이브러리(rlib혹은 dylib)를 생성합니다.|\n"
"| `rust_ffi` | cc 모듈에서 사용할 수 있는 C library (정적 혹은 동적)를 생성합니다.|\n"
"| `rust_proc_macro` | `proc-macro`를 구현하는 러스트 라이브러리를 생성합니다. "
"컴파일러의 플러그인으로 생각해도 좋습니다.|\n"
"| `rust_test` | 표준 러스트 테스트 러너를 사용하는 테스트 바이너리를 생성합니다.|\n"
"| `rust_fuzz` | `libfuzzer`를 사용하여 fuzz 바이너리를 생성합니다.|\n"
"| `rust_protobuf` | 프로토버프(protobuf) 인터페이스를 제공하는 러스트 라이브러리를 생성합니다.|\n"
"| `rust_bindgen` | C 라이브러리에 대한 러스트 바인딩을 제공하는 러스트 라이브러리를 생성합니다.|"
#: src/android/build-rules.md:16
msgid "We will look at `rust_binary` and `rust_library` next."
msgstr "다음은 `rust_binary`와 `rust_library`를 살펴봅니다."
#: src/android/build-rules/binary.md:1
msgid "# Rust Binaries"
msgstr "# 러스트 바이너리"
#: src/android/build-rules/binary.md:3
msgid ""
"Let us start with a simple application. At the root of an AOSP checkout, "
"create\n"
"the following files:"
msgstr ""
"간단한 응용 프로그램으로 시작해 보겠습니다. AOSP 체크아웃의 루트에서 다음 파"
"일을 생성합니다:"
#: src/android/build-rules/binary.md:6 src/android/build-rules/library.md:13
msgid "_hello_rust/Android.bp_:"
msgstr ""
#: src/android/build-rules/binary.md:8
msgid ""
"```javascript\n"
"rust_binary {\n"
" name: \"hello_rust\",\n"
" crate_name: \"hello_rust\",\n"
" srcs: [\"src/main.rs\"],\n"
"}\n"
"```"
msgstr ""
#: src/android/build-rules/binary.md:16 src/android/build-rules/library.md:34
msgid "_hello_rust/src/main.rs_:"
msgstr ""
#: src/android/build-rules/binary.md:18
msgid ""
"```rust\n"
"//! Rust demo."
msgstr ""
#: src/android/build-rules/binary.md:21
msgid ""
"/// Prints a greeting to standard output.\n"
"fn main() {\n"
" println!(\"Hello from Rust!\");\n"
"}\n"
"```"
msgstr ""
#: src/android/build-rules/binary.md:27
msgid "You can now build, push, and run the binary:"
msgstr "그런 다음, 이 바이너리를 빌드하고, 가상 디바이스에 넣고, 실행합니다:"
#: src/android/build-rules/binary.md:29
msgid ""
"```shell\n"
"$ m hello_rust\n"
"$ adb push $ANDROID_PRODUCT_OUT/system/bin/hello_rust /data/local/tmp\n"
"$ adb shell /data/local/tmp/hello_rust\n"
"Hello from Rust!\n"
"```"
msgstr ""
#: src/android/build-rules/library.md:1
msgid "# Rust Libraries"
msgstr "# 러스트 라이브러리"
#: src/android/build-rules/library.md:3
msgid "You use `rust_library` to create a new Rust library for Android."
msgstr "`rust_library`를 사용하여 안드로이드용 새 러스트 라이브러리를 만듭니다."
#: src/android/build-rules/library.md:5
msgid "Here we declare a dependency on two libraries:"
msgstr "여기서 두 개의 라이브러리에 대한 의존성을 선언합니다."
#: src/android/build-rules/library.md:7
msgid ""
"* `libgreeting`, which we define below,\n"
"* `libtextwrap`, which is a crate already vendored in\n"
" [`external/rust/crates/`][crates]."
msgstr ""
"* 아래에 정의한 `libgreeting`.\n"
"* [`external/rust/crates/`][crates]에 존재하는 `libtextwrap`."
#: src/android/build-rules/library.md:11
msgid ""
"[crates]: https://cs.android.com/android/platform/superproject/+/master:"
"external/rust/crates/"
msgstr ""
#: src/android/build-rules/library.md:15
msgid ""
"```javascript\n"
"rust_binary {\n"
" name: \"hello_rust_with_dep\",\n"
" crate_name: \"hello_rust_with_dep\",\n"
" srcs: [\"src/main.rs\"],\n"
" rustlibs: [\n"
" \"libgreetings\",\n"
" \"libtextwrap\",\n"
" ],\n"
" prefer_rlib: true,\n"
"}"
msgstr ""
#: src/android/build-rules/library.md:27
msgid ""
"rust_library {\n"
" name: \"libgreetings\",\n"
" crate_name: \"greetings\",\n"
" srcs: [\"src/lib.rs\"],\n"
"}\n"
"```"
msgstr ""
#: src/android/build-rules/library.md:36
msgid ""
"```rust,ignore\n"
"//! Rust demo."
msgstr ""
#: src/android/build-rules/library.md:39
msgid ""
"use greetings::greeting;\n"
"use textwrap::fill;"
msgstr ""
#: src/android/build-rules/library.md:42
msgid ""
"/// Prints a greeting to standard output.\n"
"fn main() {\n"
" println!(\"{}\", fill(&greeting(\"Bob\"), 24));\n"
"}\n"
"```"
msgstr ""
#: src/android/build-rules/library.md:48
msgid "_hello_rust/src/lib.rs_:"
msgstr ""
#: src/android/build-rules/library.md:50
msgid ""
"```rust,ignore\n"
"//! Greeting library."
msgstr ""
#: src/android/build-rules/library.md:53
msgid ""
"/// Greet `name`.\n"
"pub fn greeting(name: &str) -> String {\n"
" format!(\"Hello {name}, it is very nice to meet you!\")\n"
"}\n"
"```"
msgstr ""
#: src/android/build-rules/library.md:59
msgid "You build, push, and run the binary like before:"
msgstr "이전처럼, 빌드하고, 가상 디바이스로 넣고, 실행합니다:"
#: src/android/build-rules/library.md:61
msgid ""
"```shell\n"
"$ m hello_rust_with_dep\n"
"$ adb push $ANDROID_PRODUCT_OUT/system/bin/hello_rust_with_dep /data/local/"
"tmp\n"
"$ adb shell /data/local/tmp/hello_rust_with_dep\n"
"Hello Bob, it is very\n"
"nice to meet you!\n"
"```"
msgstr ""
#: src/android/aidl.md:1
msgid "# AIDL"
msgstr "# AIDL"
#: src/android/aidl.md:3
msgid ""
"The [Android Interface Definition Language\n"
"(AIDL)](https://developer.android.com/guide/components/aidl) is supported in "
"Rust:"
msgstr ""
"러스트는 [안드로이드 인터페이스 정의 언어(AIDL)](https://developer.android."
"com/guide/components/aidl)를 지원합니다:"
#: src/android/aidl.md:6
msgid ""
"* Rust code can call existing AIDL servers,\n"
"* You can create new AIDL servers in Rust."
msgstr ""
"* 러스트 코드에서 기존 AIDL 서버를 호출 할 수 있습니다. \n"
"* 러스트에서 새로운 AIDL 서버를 생성할 수 있습니다."
#: src/android/aidl/interface.md:1
msgid "# AIDL Interfaces"
msgstr "# AIDL 인터페이스"
#: src/android/aidl/interface.md:3
msgid "You declare the API of your service using an AIDL interface:"
msgstr "AIDL 인터페이스를 이용해서 서비스의 API를 선언합니다: "
#: src/android/aidl/interface.md:5
msgid ""
"*birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl*:"
msgstr ""
#: src/android/aidl/interface.md:7 src/android/aidl/changing.md:6
msgid ""
"```java\n"
"package com.example.birthdayservice;"
msgstr ""
#: src/android/aidl/interface.md:10
msgid ""
"/** Birthday service interface. */\n"
"interface IBirthdayService {\n"
" /** Generate a Happy Birthday message. */\n"
" String wishHappyBirthday(String name, int years);\n"
"}\n"
"```"
msgstr ""
#: src/android/aidl/interface.md:17
msgid "*birthday_service/aidl/Android.bp*:"
msgstr ""
#: src/android/aidl/interface.md:19
msgid ""
"```javascript\n"
"aidl_interface {\n"
" name: \"com.example.birthdayservice\",\n"
" srcs: [\"com/example/birthdayservice/*.aidl\"],\n"
" unstable: true,\n"
" backend: {\n"
" rust: { // Rust is not enabled by default\n"
" enabled: true,\n"
" },\n"
" },\n"
"}\n"
"```"
msgstr ""
#: src/android/aidl/interface.md:32
msgid ""
"Add `vendor_available: true` if your AIDL file is used by a binary in the "
"vendor\n"
"partition."
msgstr ""
"AIDL 파일이 벤더 파티션에 있는 바이너리에서 사용될 경우 `vendor_available: true`"
"를 추가합니다."
#: src/android/aidl/implementation.md:1
msgid "# Service Implementation"
msgstr "# 서비스 구현"
#: src/android/aidl/implementation.md:3
msgid "We can now implement the AIDL service:"
msgstr "이제 AIDL서비스를 구현할 수 있습니다:"
#: src/android/aidl/implementation.md:5
msgid "*birthday_service/src/lib.rs*:"
msgstr ""
#: src/android/aidl/implementation.md:7
msgid ""
"```rust,ignore\n"
"//! Implementation of the `IBirthdayService` AIDL interface.\n"
"use com_example_birthdayservice::aidl::com::example::birthdayservice::"
"IBirthdayService::IBirthdayService;\n"
"use com_example_birthdayservice::binder;"
msgstr ""
#: src/android/aidl/implementation.md:12
msgid ""
"/// The `IBirthdayService` implementation.\n"
"pub struct BirthdayService;"
msgstr ""
#: src/android/aidl/implementation.md:15
msgid "impl binder::Interface for BirthdayService {}"
msgstr ""
#: src/android/aidl/implementation.md:17
msgid ""
"impl IBirthdayService for BirthdayService {\n"
" fn wishHappyBirthday(&self, name: &str, years: i32) -> binder::"
"Result<String> {\n"
" Ok(format!(\n"
" \"Happy Birthday {name}, congratulations with the {years} years!"
"\"\n"
" ))\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/android/aidl/implementation.md:26 src/android/aidl/server.md:28
#: src/android/aidl/client.md:37
msgid "*birthday_service/Android.bp*:"
msgstr ""
#: src/android/aidl/implementation.md:28
msgid ""
"```javascript\n"
"rust_library {\n"
" name: \"libbirthdayservice\",\n"
" srcs: [\"src/lib.rs\"],\n"
" crate_name: \"birthdayservice\",\n"
" rustlibs: [\n"
" \"com.example.birthdayservice-rust\",\n"
" \"libbinder_rs\",\n"
" ],\n"
"}\n"
"```"
msgstr ""
#: src/android/aidl/server.md:1
msgid "# AIDL Server"
msgstr "# AIDL 서버"
#: src/android/aidl/server.md:3
msgid "Finally, we can create a server which exposes the service:"
msgstr "마지막으로 서비스를 제공하는 서버를 만들 수 있습니다:"
#: src/android/aidl/server.md:5
msgid "*birthday_service/src/server.rs*:"
msgstr ""
#: src/android/aidl/server.md:7
msgid ""
"```rust,ignore\n"
"//! Birthday service.\n"
"use birthdayservice::BirthdayService;\n"
"use com_example_birthdayservice::aidl::com::example::birthdayservice::"
"IBirthdayService::BnBirthdayService;\n"
"use com_example_birthdayservice::binder;"
msgstr ""
#: src/android/aidl/server.md:13 src/android/aidl/client.md:12
msgid "const SERVICE_IDENTIFIER: &str = \"birthdayservice\";"
msgstr ""
#: src/android/aidl/server.md:15
msgid ""
"/// Entry point for birthday service.\n"
"fn main() {\n"
" let birthday_service = BirthdayService;\n"
" let birthday_service_binder = BnBirthdayService::new_binder(\n"
" birthday_service,\n"
" binder::BinderFeatures::default(),\n"
" );\n"
" binder::add_service(SERVICE_IDENTIFIER, birthday_service_binder."
"as_binder())\n"
" .expect(\"Failed to register service\");\n"
" binder::ProcessState::join_thread_pool()\n"
"}\n"
"```"
msgstr ""
#: src/android/aidl/server.md:30
msgid ""
"```javascript\n"
"rust_binary {\n"
" name: \"birthday_server\",\n"
" crate_name: \"birthday_server\",\n"
" srcs: [\"src/server.rs\"],\n"
" rustlibs: [\n"
" \"com.example.birthdayservice-rust\",\n"
" \"libbinder_rs\",\n"
" \"libbirthdayservice\",\n"
" ],\n"
" prefer_rlib: true,\n"
"}\n"
"```"
msgstr ""
#: src/android/aidl/deploy.md:1
msgid "# Deploy"
msgstr "# 배포"
#: src/android/aidl/deploy.md:3
msgid "We can now build, push, and start the service:"
msgstr "서비스를 빌드하고, 가상 디바이스에 넣고, 시작 할 수 있습니다:"
#: src/android/aidl/deploy.md:5
msgid ""
"```shell\n"
"$ m birthday_server\n"
"$ adb push $ANDROID_PRODUCT_OUT/system/bin/birthday_server /data/local/tmp\n"
"$ adb shell /data/local/tmp/birthday_server\n"
"```"
msgstr ""
#: src/android/aidl/deploy.md:11
msgid "In another terminal, check that the service runs:"
msgstr "다른 터미널을 띄워서 서비스가 잘 수행되고 있는지 확인합니다:"
#: src/android/aidl/deploy.md:13
msgid ""
"```shell\n"
"$ adb shell service check birthdayservice\n"
"Service birthdayservice: found\n"
"```"
msgstr ""
#: src/android/aidl/deploy.md:18
msgid "You can also call the service with `service call`:"
msgstr "`service call`명렁어로 서비스를 호출할 수도 있습니다:"
#: src/android/aidl/deploy.md:20
msgid ""
"```shell\n"
"$ $ adb shell service call birthdayservice 1 s16 Bob i32 24\n"
"Result: Parcel(\n"
" 0x00000000: 00000000 00000036 00610048 00700070 '....6...H.a.p.p.'\n"
" 0x00000010: 00200079 00690042 00740072 00640068 'y. .B.i.r.t.h.d.'\n"
" 0x00000020: 00790061 00420020 0062006f 0020002c 'a.y. .B.o.b.,. .'\n"
" 0x00000030: 006f0063 0067006e 00610072 00750074 'c.o.n.g.r.a.t.u.'\n"
" 0x00000040: 0061006c 00690074 006e006f 00200073 'l.a.t.i.o.n.s. .'\n"
" 0x00000050: 00690077 00680074 00740020 00650068 'w.i.t.h. .t.h.e.'\n"
" 0x00000060: 00320020 00200034 00650079 00720061 ' .2.4. .y.e.a.r.'\n"
" 0x00000070: 00210073 00000000 's.!..... ')\n"
"```"
msgstr ""
#: src/android/aidl/client.md:1
msgid "# AIDL Client"
msgstr "# AIDL 클라이언트"
#: src/android/aidl/client.md:3
msgid "Finally, we can create a Rust client for our new service."
msgstr "마지막으로, 아까 추가한 서비스에 대한 클라이언트를 러스트로 만들겠습니다."
#: src/android/aidl/client.md:5
msgid "*birthday_service/src/client.rs*:"
msgstr ""
#: src/android/aidl/client.md:7
msgid ""
"```rust,ignore\n"
"//! Birthday service.\n"
"use com_example_birthdayservice::aidl::com::example::birthdayservice::"
"IBirthdayService::IBirthdayService;\n"
"use com_example_birthdayservice::binder;"
msgstr ""
#: src/android/aidl/client.md:14
msgid ""
"/// Connect to the BirthdayService.\n"
"pub fn connect() -> Result<binder::Strong<dyn IBirthdayService>, binder::"
"StatusCode> {\n"
" binder::get_interface(SERVICE_IDENTIFIER)\n"
"}"
msgstr ""
#: src/android/aidl/client.md:19
msgid ""
"/// Call the birthday service.\n"
"fn main() -> Result<(), binder::Status> {\n"
" let name = std::env::args()\n"
" .nth(1)\n"
" .unwrap_or_else(|| String::from(\"Bob\"));\n"
" let years = std::env::args()\n"
" .nth(2)\n"
" .and_then(|arg| arg.parse::<i32>().ok())\n"
" .unwrap_or(42);"
msgstr ""
#: src/android/aidl/client.md:29
msgid ""
" binder::ProcessState::start_thread_pool();\n"
" let service = connect().expect(\"Failed to connect to "
"BirthdayService\");\n"
" let msg = service.wishHappyBirthday(&name, years)?;\n"
" println!(\"{msg}\");\n"
" Ok(())\n"
"}\n"
"```"
msgstr ""
#: src/android/aidl/client.md:39
msgid ""
"```javascript\n"
"rust_binary {\n"
" name: \"birthday_client\",\n"
" crate_name: \"birthday_client\",\n"
" srcs: [\"src/client.rs\"],\n"
" rustlibs: [\n"
" \"com.example.birthdayservice-rust\",\n"
" \"libbinder_rs\",\n"
" ],\n"
" prefer_rlib: true,\n"
"}\n"
"```"
msgstr ""
#: src/android/aidl/client.md:52
msgid "Notice that the client does not depend on `libbirthdayservice`."
msgstr "클라이언트는 `libbirthdayservice`에 의존하지 않음에 주목하세요. "
#: src/android/aidl/client.md:54
msgid "Build, push, and run the client on your device:"
msgstr "빌드하고, 가상 디바이스로 넣고, 실행합니다: "
#: src/android/aidl/client.md:56
msgid ""
"```shell\n"
"$ m birthday_client\n"
"$ adb push $ANDROID_PRODUCT_OUT/system/bin/birthday_client /data/local/tmp\n"
"$ adb shell /data/local/tmp/birthday_client Charlie 60\n"
"Happy Birthday Charlie, congratulations with the 60 years!\n"
"```"
msgstr ""
#: src/android/aidl/changing.md:1
msgid "# Changing API"
msgstr "# API 수정"
#: src/android/aidl/changing.md:3
msgid ""
"Let us extend the API with more functionality: we want to let clients "
"specify a\n"
"list of lines for the birthday card:"
msgstr ""
"API를 확장하여 더 많은 기능을 제공해 봅시다. 클라이언트가 생일 카드에 담길 "
"내용을 지정할 수 있도록 하겠습니다:"
#: src/android/aidl/changing.md:9
msgid ""
"/** Birthday service interface. */\n"
"interface IBirthdayService {\n"
" /** Generate a Happy Birthday message. */\n"
" String wishHappyBirthday(String name, int years, in String[] text);\n"
"}\n"
"```"
msgstr ""
#: src/android/logging.md:1
msgid "# Logging"
msgstr "# 로깅"
#: src/android/logging.md:3
msgid ""
"You should use the `log` crate to automatically log to `logcat` (on-device) "
"or\n"
"`stdout` (on-host):"
msgstr ""
"`log` 크레이트를 사용하면 안드로이드 디바이스 안에서 수행될 때에는 `logcat`으로, "
"호스트에서 수행될 때에는 `stdout`으로 로그가 자동으로 출력이 되도록 할 수 있습니다."
#: src/android/logging.md:6
msgid "_hello_rust_logs/Android.bp_:"
msgstr ""
#: src/android/logging.md:8
msgid ""
"```javascript\n"
"rust_binary {\n"
" name: \"hello_rust_logs\",\n"
" crate_name: \"hello_rust_logs\",\n"
" srcs: [\"src/main.rs\"],\n"
" rustlibs: [\n"
" \"liblog_rust\",\n"
" \"liblogger\",\n"
" ],\n"
" prefer_rlib: true,\n"
" host_supported: true,\n"
"}\n"
"```"
msgstr ""
#: src/android/logging.md:22
msgid "_hello_rust_logs/src/main.rs_:"
msgstr ""
#: src/android/logging.md:24
msgid ""
"```rust,ignore\n"
"//! Rust logging demo."
msgstr ""
#: src/android/logging.md:27
msgid "use log::{debug, error, info};"
msgstr ""
#: src/android/logging.md:29
msgid ""
"/// Logs a greeting.\n"
"fn main() {\n"
" logger::init(\n"
" logger::Config::default()\n"
" .with_tag_on_device(\"rust\")\n"
" .with_min_level(log::Level::Trace),\n"
" );\n"
" debug!(\"Starting program.\");\n"
" info!(\"Things are going fine.\");\n"
" error!(\"Something went wrong!\");\n"
"}\n"
"```"
msgstr ""
#: src/android/logging.md:42 src/android/interoperability/with-c/bindgen.md:98
#: src/android/interoperability/with-c/rust.md:73
msgid "Build, push, and run the binary on your device:"
msgstr "빌드하고, 가상 디바이스에 넣고, 실행합니다:"
#: src/android/logging.md:44
msgid ""
"```shell\n"
"$ m hello_rust_logs\n"
"$ adb push $ANDROID_PRODUCT_OUT/system/bin/hello_rust_logs /data/local/tmp\n"
"$ adb shell /data/local/tmp/hello_rust_logs\n"
"```"
msgstr ""
#: src/android/logging.md:50
msgid "The logs show up in `adb logcat`:"
msgstr "`adb logcat`커맨드로 로그를 확인합니다:"
#: src/android/logging.md:52
msgid ""
"```shell\n"
"$ adb logcat -s rust\n"
"09-08 08:38:32.454 2420 2420 D rust: hello_rust_logs: Starting program.\n"
"09-08 08:38:32.454 2420 2420 I rust: hello_rust_logs: Things are going "
"fine.\n"
"09-08 08:38:32.454 2420 2420 E rust: hello_rust_logs: Something went "
"wrong!\n"
"```"
msgstr ""
#: src/android/interoperability.md:1
msgid "# Interoperability"
msgstr "# 상호운용성(Interoperability)"
#: src/android/interoperability.md:3
msgid ""
"Rust has excellent support for interoperability with other languages. This "
"means\n"
"that you can:"
msgstr ""
"러스트는 다음과 같이 다른 언어와의 상호운용성을 훌륭히 지원합니다:"
#: src/android/interoperability.md:6
msgid ""
"* Call Rust functions from other languages.\n"
"* Call functions written in other languages from Rust."
msgstr ""
"* 타 언어에서 러스트 함수를 호출합니다. \n"
"* 타 언어의 함수를 러스트에서 호출합니다."
#: src/android/interoperability.md:9
msgid ""
"When you call functions in a foreign language we say that you're using a\n"
"_foreign function interface_, also known as FFI."
msgstr ""
"타 언어의 함수를 호출해서 사용하는 것을 FFI(foreign function interface)라고 "
"합니다."
#: src/android/interoperability/with-c.md:1
msgid "# Interoperability with C"
msgstr "# C와의 상호운용성"
#: src/android/interoperability/with-c.md:3
msgid ""
"Rust has full support for linking object files with a C calling convention.\n"
"Similarly, you can export Rust functions and call them from C."
msgstr ""
"러스트는 C 호출규약을 따르는 오브젝트 파일과 링킹할 수 있습니다.\n"
"또한, 반대로 러스트 함수를 내보내서 C에서 호출 할 수 도 있습니다. "
#: src/android/interoperability/with-c.md:6
msgid "You can do it by hand if you want:"
msgstr "원한다면 아래와 같이 수동으로 코딩할 수 있습니다:"
#: src/android/interoperability/with-c.md:8
msgid ""
"```rust\n"
"extern \"C\" {\n"
" fn abs(x: i32) -> i32;\n"
"}"
msgstr ""
#: src/android/interoperability/with-c.md:13
msgid ""
"fn main() {\n"
" let x = -42;\n"
" let abs_x = unsafe { abs(x) };\n"
" println!(\"{x}, {abs_x}\");\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/with-c.md:20
msgid ""
"We already saw this in the [Safe FFI Wrapper\n"
"exercise](../../exercises/day-3/safe-ffi-wrapper.md)."
msgstr ""
"우리는 이미 [Safe FFI 래퍼 연습문제](../../exercises/day-3/safe-ffi-wrapper."
"md)에서 이를 다루었습니다. "
#: src/android/interoperability/with-c.md:23
msgid ""
"> This assumes full knowledge of the target platform. Not recommended for\n"
"> production."
msgstr ""
"> 이러한 방법은 타겟 플랫폼의 모든 부분을 사전에 알고 있다는 전제를 깔고 있습니다.\n"
"> 상용 프로젝트에서는 권장하지 않습니다."
#: src/android/interoperability/with-c.md:26
msgid "We will look at better options next."
msgstr "좀 더 나은 옵션을 살펴보겠습니다."
#: src/android/interoperability/with-c/bindgen.md:1
msgid "# Using Bindgen"
msgstr "# Bindgen 사용하기"
#: src/android/interoperability/with-c/bindgen.md:3
msgid ""
"The [bindgen](https://rust-lang.github.io/rust-bindgen/introduction.html) "
"tool\n"
"can auto-generate bindings from a C header file."
msgstr ""
"[bindgen](https://rust-lang.github.io/rust-bindgen/introduction.html)는 C 헤"
"더파일에서 러스트 바인딩을 자동으로 생성하는 도구입니다."
#: src/android/interoperability/with-c/bindgen.md:6
msgid "First create a small C library:"
msgstr "먼저 작은 C라이브러리를 만들어 보겠습니다:"
#: src/android/interoperability/with-c/bindgen.md:8
msgid "_interoperability/bindgen/libbirthday.h_:"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:10
msgid ""
"```c\n"
"typedef struct card {\n"
" const char* name;\n"
" int years;\n"
"} card;"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:16
msgid ""
"void print_card(const card* card);\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:19
msgid "_interoperability/bindgen/libbirthday.c_:"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:21
msgid ""
"```c\n"
"#include <stdio.h>\n"
"#include \"libbirthday.h\""
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:25
msgid ""
"void print_card(const card* card) {\n"
" printf(\"+--------------\\n\");\n"
" printf(\"| Happy Birthday %s!\\n\", card->name);\n"
" printf(\"| Congratulations with the %i years!\\n\", card->years);\n"
" printf(\"+--------------\\n\");\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:33
msgid "Add this to your `Android.bp` file:"
msgstr "`Android.bp` 파일에 아래를 추가합니다:"
#: src/android/interoperability/with-c/bindgen.md:35
#: src/android/interoperability/with-c/bindgen.md:55
#: src/android/interoperability/with-c/bindgen.md:69
#: src/android/interoperability/with-c/bindgen.md:108
msgid "_interoperability/bindgen/Android.bp_:"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:37
msgid ""
"```javascript\n"
"cc_library {\n"
" name: \"libbirthday\",\n"
" srcs: [\"libbirthday.c\"],\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:44
msgid ""
"Create a wrapper header file for the library (not strictly needed in this\n"
"example):"
msgstr ""
"라이브러리에 대한 헤더 파일을 만듭니다(이 예시에서는 반드시 필요한 것은 아닙니다.):"
#: src/android/interoperability/with-c/bindgen.md:47
msgid "_interoperability/bindgen/libbirthday_wrapper.h_:"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:49
msgid ""
"```c\n"
"#include \"libbirthday.h\"\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:53
msgid "You can now auto-generate the bindings:"
msgstr "이제 바인딩을 자동으로 생성할 수 있습니다:"
#: src/android/interoperability/with-c/bindgen.md:57
msgid ""
"```javascript\n"
"rust_bindgen {\n"
" name: \"libbirthday_bindgen\",\n"
" crate_name: \"birthday_bindgen\",\n"
" wrapper_src: \"libbirthday_wrapper.h\",\n"
" source_stem: \"bindings\",\n"
" static_libs: [\"libbirthday\"],\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:67
msgid "Finally, we can use the bindings in our Rust program:"
msgstr "마침내, 러스트 프로그램에서 바인딩을 사용할 수 있습니다:"
#: src/android/interoperability/with-c/bindgen.md:71
msgid ""
"```javascript\n"
"rust_binary {\n"
" name: \"print_birthday_card\",\n"
" srcs: [\"main.rs\"],\n"
" rustlibs: [\"libbirthday_bindgen\"],\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:79
msgid "_interoperability/bindgen/main.rs_:"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:81
msgid ""
"```rust,compile_fail\n"
"//! Bindgen demo."
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:84
msgid "use birthday_bindgen::{card, print_card};"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:86
msgid ""
"fn main() {\n"
" let name = std::ffi::CString::new(\"Peter\").unwrap();\n"
" let card = card {\n"
" name: name.as_ptr(),\n"
" years: 42,\n"
" };\n"
" unsafe {\n"
" print_card(&card as *const card);\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:100
msgid ""
"```shell\n"
"$ m print_birthday_card\n"
"$ adb push $ANDROID_PRODUCT_OUT/system/bin/print_birthday_card /data/local/"
"tmp\n"
"$ adb shell /data/local/tmp/print_birthday_card\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:106
msgid "Finally, we can run auto-generated tests to ensure the bindings work:"
msgstr "마지막으로, 바인딩이 잘 작동하는지 확인하기 위해, 자동 생성된 테스트를 실행해 보겠습니다:"
#: src/android/interoperability/with-c/bindgen.md:110
msgid ""
"```javascript\n"
"rust_test {\n"
" name: \"libbirthday_bindgen_test\",\n"
" srcs: [\":libbirthday_bindgen\"],\n"
" crate_name: \"libbirthday_bindgen_test\",\n"
" test_suites: [\"general-tests\"],\n"
" auto_gen_config: true,\n"
" clippy_lints: \"none\", // Generated file, skip linting\n"
" lints: \"none\",\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:122
msgid ""
"```shell\n"
"$ atest libbirthday_bindgen_test\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/rust.md:1
msgid "# Calling Rust"
msgstr "# C에서 러스트 호출"
#: src/android/interoperability/with-c/rust.md:3
msgid "Exporting Rust functions and types to C is easy:"
msgstr "러스트에서 타입과 함수를 C로 내보내는 것은 간단합니다:"
#: src/android/interoperability/with-c/rust.md:5
msgid "_interoperability/rust/libanalyze/analyze.rs_"
msgstr ""
#: src/android/interoperability/with-c/rust.md:7
msgid ""
"```rust,editable\n"
"//! Rust FFI demo.\n"
"#![deny(improper_ctypes_definitions)]"
msgstr ""
#: src/android/interoperability/with-c/rust.md:11
msgid "use std::os::raw::c_int;"
msgstr ""
#: src/android/interoperability/with-c/rust.md:13
msgid ""
"/// Analyze the numbers.\n"
"#[no_mangle]\n"
"pub extern \"C\" fn analyze_numbers(x: c_int, y: c_int) {\n"
" if x < y {\n"
" println!(\"x ({x}) is smallest!\");\n"
" } else {\n"
" println!(\"y ({y}) is probably larger than x ({x})\");\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/rust.md:24
msgid "_interoperability/rust/libanalyze/analyze.h_"
msgstr ""
#: src/android/interoperability/with-c/rust.md:26
msgid ""
"```c\n"
"#ifndef ANALYSE_H\n"
"#define ANALYSE_H"
msgstr ""
#: src/android/interoperability/with-c/rust.md:30
msgid ""
"extern \"C\" {\n"
"void analyze_numbers(int x, int y);\n"
"}"
msgstr ""
#: src/android/interoperability/with-c/rust.md:34
msgid ""
"#endif\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/rust.md:37
msgid "_interoperability/rust/libanalyze/Android.bp_"
msgstr ""
#: src/android/interoperability/with-c/rust.md:39
msgid ""
"```javascript\n"
"rust_ffi {\n"
" name: \"libanalyze_ffi\",\n"
" crate_name: \"analyze_ffi\",\n"
" srcs: [\"analyze.rs\"],\n"
" include_dirs: [\".\"],\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/rust.md:48
msgid "We can now call this from a C binary:"
msgstr "이제 이 러스트 함수를 C바이너리에서 호출할 수 있습니다:"
#: src/android/interoperability/with-c/rust.md:50
msgid "_interoperability/rust/analyze/main.c_"
msgstr ""
#: src/android/interoperability/with-c/rust.md:52
msgid ""
"```c\n"
"#include \"analyze.h\""
msgstr ""
#: src/android/interoperability/with-c/rust.md:55
msgid ""
"int main() {\n"
" analyze_numbers(10, 20);\n"
" analyze_numbers(123, 123);\n"
" return 0;\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/rust.md:62
msgid "_interoperability/rust/analyze/Android.bp_"
msgstr ""
#: src/android/interoperability/with-c/rust.md:64
msgid ""
"```javascript\n"
"cc_binary {\n"
" name: \"analyze_numbers\",\n"
" srcs: [\"main.c\"],\n"
" static_libs: [\"libanalyze_ffi\"],\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/rust.md:75
msgid ""
"```shell\n"
"$ m analyze_numbers\n"
"$ adb push $ANDROID_PRODUCT_OUT/system/bin/analyze_numbers /data/local/tmp\n"
"$ adb shell /data/local/tmp/analyze_numbers\n"
"```"
msgstr ""
#: src/android/interoperability/with-c/rust.md:83
msgid ""
"`#[no_mangle]` disables Rust's usual name mangling, so the exported symbol "
"will just be the name of\n"
"the function. You can also use `#[export_name = \"some_name\"]` to specify "
"whatever name you want."
msgstr ""
"`#[no_mangle]`은 러스트의 네임 맹글링(name mangling)을 비활성화하므로 외부로 노출되는 "
"심볼의 이름은 함수의 이름 그대로가 됩니다.\n"
"심볼 이름을 바꾸고 싶다면 `#[export_name = \"some_name\"]`을 사용합니다."
#: src/android/interoperability/cpp.md:1
msgid "# With C++"
msgstr "# C++ 와의 상호운용성"
#: src/android/interoperability/cpp.md:3
msgid ""
"The [CXX crate][1] makes it possible to do safe interoperability between "
"Rust\n"
"and C++."
msgstr ""
"[CXX 크레이트][1]는 러스트와 C++ 사이의 안전한 상호운용성을 가능하게 해줍니"
"다."
#: src/android/interoperability/cpp.md:6
msgid "The overall approach looks like this:"
msgstr "전체적인 접근 방법은 다음과 같습니다. "
#: src/android/interoperability/cpp.md:8
msgid "<img src=\"cpp/overview.svg\">"
msgstr ""
#: src/android/interoperability/cpp.md:10
msgid "See the [CXX tutorial][2] for an full example of using this."
msgstr "사용하는 방법에 대해서는[CXX 튜토리얼][2] 를 참조합니다."
#: src/android/interoperability/cpp.md:12
msgid ""
"[1]: https://cxx.rs/\n"
"[2]: https://cxx.rs/tutorial.html"
msgstr ""
#: src/android/interoperability/java.md:1
msgid "# Interoperability with Java"
msgstr "# Java와의 상호운용성"
#: src/android/interoperability/java.md:3
msgid ""
"Java can load shared objects via [Java Native Interface\n"
"(JNI)](https://en.wikipedia.org/wiki/Java_Native_Interface). The [`jni`\n"
"crate](https://docs.rs/jni/) allows you to create a compatible library."
msgstr ""
"자바는 [Java Native Interface(JNI)](https://en.wikipedia.org/wiki/"
"Java_Native_Interface)를 통해 공유 라이브러리를 로드할 수 있습니다. [`jni` 크레이"
"트](https://docs.rs/jni/)를 사용하여 JNI 라이브러리를 만들 수 있습니다."
#: src/android/interoperability/java.md:7
msgid "First, we create a Rust function to export to Java:"
msgstr "먼저, 자바로 내보낼 러스트 함수를 생성합니다:"
#: src/android/interoperability/java.md:9
msgid "_interoperability/java/src/lib.rs_:"
msgstr ""
#: src/android/interoperability/java.md:11
msgid ""
"```rust,compile_fail\n"
"//! Rust <-> Java FFI demo."
msgstr ""
#: src/android/interoperability/java.md:14
msgid ""
"use jni::objects::{JClass, JString};\n"
"use jni::sys::jstring;\n"
"use jni::JNIEnv;"
msgstr ""
#: src/android/interoperability/java.md:18
msgid ""
"/// HelloWorld::hello method implementation.\n"
"#[no_mangle]\n"
"pub extern \"system\" fn Java_HelloWorld_hello(\n"
" env: JNIEnv,\n"
" _class: JClass,\n"
" name: JString,\n"
") -> jstring {\n"
" let input: String = env.get_string(name).unwrap().into();\n"
" let greeting = format!(\"Hello, {input}!\");\n"
" let output = env.new_string(greeting).unwrap();\n"
" output.into_inner()\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/java.md:32
#: src/android/interoperability/java.md:62
msgid "_interoperability/java/Android.bp_:"
msgstr ""
#: src/android/interoperability/java.md:34
msgid ""
"```javascript\n"
"rust_ffi_shared {\n"
" name: \"libhello_jni\",\n"
" crate_name: \"hello_jni\",\n"
" srcs: [\"src/lib.rs\"],\n"
" rustlibs: [\"libjni\"],\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/java.md:43
msgid "Finally, we can call this function from Java:"
msgstr "자바에서 이 함수를 호출 할 수 있습니다:"
#: src/android/interoperability/java.md:45
msgid "_interoperability/java/HelloWorld.java_:"
msgstr ""
#: src/android/interoperability/java.md:47
msgid ""
"```java\n"
"class HelloWorld {\n"
" private static native String hello(String name);"
msgstr ""
#: src/android/interoperability/java.md:51
msgid ""
" static {\n"
" System.loadLibrary(\"hello_jni\");\n"
" }"
msgstr ""
#: src/android/interoperability/java.md:55
msgid ""
" public static void main(String[] args) {\n"
" String output = HelloWorld.hello(\"Alice\");\n"
" System.out.println(output);\n"
" }\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/java.md:64
msgid ""
"```javascript\n"
"java_binary {\n"
" name: \"helloworld_jni\",\n"
" srcs: [\"HelloWorld.java\"],\n"
" main_class: \"HelloWorld\",\n"
" required: [\"libhello_jni\"],\n"
"}\n"
"```"
msgstr ""
#: src/android/interoperability/java.md:73
msgid "Finally, you can build, sync, and run the binary:"
msgstr "마지막으로 바이너리를 빌드, 싱크, 실행합니다: "
#: src/android/interoperability/java.md:75
msgid ""
"```shell\n"
"$ m helloworld_jni\n"
"$ adb sync # requires adb root && adb remount\n"
"$ adb shell /system/bin/helloworld_jni\n"
"```"
msgstr ""
#: src/exercises/day-4/afternoon.md:3
msgid ""
"For the last exercise, we will look at one of the projects you work with. "
"Let us\n"
"group up and do this together. Some suggestions:"
msgstr ""
"마지막 연습문제는 여러분이 작업하고 있는 프로젝트 중 하나를 FFI로 러스트와 연계 해보는 것입니"
"다. 몇 가지 예시입니다: "
#: src/exercises/day-4/afternoon.md:6
msgid "* Call your AIDL service with a client written in Rust."
msgstr "* 당신의 AIDL서비스를 러스트 클라이언트에서 호출해봅니다."
#: src/exercises/day-4/afternoon.md:8
msgid "* Move a function from your project to Rust and call it."
msgstr "* 당신의 프로젝트의 함수를 러스트로 옮기고 호출해봅니다."
#: src/exercises/day-4/afternoon.md:12
msgid ""
"No solution is provided here since this is open-ended: it relies on someone "
"in\n"
"the class having a piece of code which you can turn in to Rust on the fly."
msgstr ""
"이 연습문제는 열려있기 때문에 해답이 제공되지 않습니다. 클래스에서 제출된 코"
"드에 의존합니다."
#: src/thanks.md:1
msgid "# Thanks!"
msgstr "# 감사인사"
#: src/thanks.md:3
msgid ""
"_Thank you for taking Comprehensive Rust 🦀!_ We hope you enjoyed it and "
"that it\n"
"was useful."
msgstr ""
"Comprehensive Rust 🦀를 이용해 주셔서 감사합니다. 즐겁고 유익한 시간이었기를 "
"바랍니다."
#: src/thanks.md:6
msgid ""
"We've had a lot of fun putting the course together. The course is not "
"perfect,\n"
"so if you spotted any mistakes or have ideas for improvements, please get "
"in\n"
"[contact with us on\n"
"GitHub](https://github.com/google/comprehensive-rust/discussions). We would "
"love\n"
"to hear from you."
msgstr ""
"강의가 완벽하진 않으니 실수나 개선점이 있다면 언제든지 [깃허브](https://"
"github.com/google/comprehensive-rust/discussions)로 연락주세요"
#: src/other-resources.md:1
msgid "# Other Rust Resources"
msgstr "# 러스트 참고 자료"
#: src/other-resources.md:3
msgid ""
"The Rust community has created a wealth of high-quality and free resources\n"
"online."
msgstr "러스트 커뮤니티는 온라인에서 고품질의 무료 소스를 만들었습니다."
#: src/other-resources.md:6
msgid "## Official Documentation"
msgstr "## 공식 문서들"
#: src/other-resources.md:8
msgid "The Rust project hosts many resources. These cover Rust in general:"
msgstr ""
"러스트 프로젝트에는 참조할 만한 자료가 많습니다. 일반적인 내용을 다루는 몇가지 "
"참고 문서들입니다:"
#: src/other-resources.md:10
msgid ""
"* [The Rust Programming Language](https://doc.rust-lang.org/book/): the\n"
" canonical free book about Rust. Covers the language in detail and includes "
"a\n"
" few projects for people to build.\n"
"* [Rust By Example](https://doc.rust-lang.org/rust-by-example/): covers the "
"Rust\n"
" syntax via a series of examples which showcase different constructs. "
"Sometimes\n"
" includes small exercises where you are asked to expand on the code in the\n"
" examples.\n"
"* [Rust Standard Library](https://doc.rust-lang.org/std/): full "
"documentation of\n"
" the standard library for Rust.\n"
"* [The Rust Reference](https://doc.rust-lang.org/reference/): an incomplete "
"book\n"
" which describes the Rust grammar and memory model."
msgstr ""
"* [The Rust Programming Language](https://doc.rust-lang.org/book/): 러스트에 "
"대한 무료 표준 서적입니다. 언어에 대한 자세한 설명과 사람들이 빌드 할수 있는 "
"몇가지 프로젝트를 포함합니다.\n"
"* [Rust By Example](https://doc.rust-lang.org/rust-by-example/): 여러 예제를 "
"통해 러스트의 문법을 보여주며 때때로 코드를 확장하는 약간의 연습문제들이 포함"
"되어 있습니다.\n"
"* [Rust Standard Library](https://doc.rust-lang.org/std/): 러스트 표준 라이브"
"러리 전체 문서입니다.\n"
"* [The Rust Reference](https://doc.rust-lang.org/reference/): 메모리 모델링"
"과 러스트 문법을 설명하는 문서입니다.(아직 불완전하다함)"
#: src/other-resources.md:22
msgid "More specialized guides hosted on the official Rust site:"
msgstr "좀 더 전문적인 공식 가이드입니다:"
#: src/other-resources.md:24
msgid ""
"* [The Rustonomicon](https://doc.rust-lang.org/nomicon/): covers unsafe "
"Rust,\n"
" including working with raw pointers and interfacing with other languages\n"
" (FFI).\n"
"* [Asynchronous Programming in Rust](https://rust-lang.github.io/async-"
"book/):\n"
" covers the new asynchronous programming model which was introduced after "
"the\n"
" Rust Book was written.\n"
"* [The Embedded Rust Book](https://doc.rust-lang.org/stable/embedded-book/): "
"an\n"
" introduction to using Rust on embedded devices without an operating system."
msgstr ""
"* [The Rustonomicon](https://doc.rust-lang.org/nomicon/): 안전하지 않은 러스"
"트, FFI, raw포인터 작업을 다룹니다.\n"
"* [Asynchronous Programming in Rust](https://rust-lang.github.io/async-"
"book/): 러스트 북이 작성 된 이후 도입된 새로운 비동기 프로그래밍 모델을 다룹"
"니다.\n"
"* [The Embedded Rust Book](https://doc.rust-lang.org/stable/embedded-book/): "
"운영체제가 없는 임베디드 장치에서의 러스트 사용법을 소개합니다."
#: src/other-resources.md:33
msgid "## Unofficial Learning Material"
msgstr "## 비공식적 학습 자료"
#: src/other-resources.md:35
msgid "A small selection of other guides and tutorial for Rust:"
msgstr "러스트에 대한 기타 안내서와 튜토리얼의 일부입니다:"
#: src/other-resources.md:37
msgid ""
"* [Learn Rust the Dangerous Way](http://cliffle.com/p/dangerust/): covers "
"Rust\n"
" from the perspective of low-level C programmers.\n"
"* [Rust for Embedded C\n"
" Programmers](https://docs.opentitan.org/doc/ug/rust_for_c/): covers Rust "
"from\n"
" the perspective of developers who write firmware in C.\n"
"* [Rust for professionals](https://overexact.com/rust-for-professionals/):\n"
" covers the syntax of Rust using side-by-side comparisons with other "
"languages\n"
" such as C, C++, Java, JavaScript, and Python.\n"
"* [Rust on Exercism](https://exercism.org/tracks/rust): 100+ exercises to "
"help\n"
" you learn Rust.\n"
"* [Ferrous Teaching\n"
" Material](https://ferrous-systems.github.io/teaching-material/index.html): "
"a\n"
" series of small presentations covering both basic and advanced part of "
"the\n"
" Rust language. Other topics such as WebAssembly, and async/await are also\n"
" covered.\n"
"* [Beginner's Series to\n"
" Rust](https://docs.microsoft.com/en-us/shows/beginners-series-to-rust/) "
"and\n"
" [Take your first steps with\n"
" Rust](https://docs.microsoft.com/en-us/learn/paths/rust-first-steps/): "
"two\n"
" Rust guides aimed at new developers. The first is a set of 35 videos and "
"the\n"
" second is a set of 11 modules which covers Rust syntax and basic "
"constructs."
msgstr ""
"* [Learn Rust the Dangerous Way](http://cliffle.com/p/dangerust/): C언어 프로"
"그래머 관점에서 러스트를 다룹니다.\n"
"* [Rust for Embedded C Programmers](https://docs.opentitan.org/doc/ug/"
"rust_for_c/): 임베디드 C개발자(펌웨어 개발자)를 위한 러스트 가이드입니다.\n"
"* [Rust for professionals](https://overexact.com/rust-for-professionals/): 다"
"른 언어(C/C++, Java, Python, Javascript)와의 병렬비교를 사용하여 러스트 문법"
"을 다룹니다.\n"
"* [Rust on Exercism](https://exercism.org/tracks/rust): 러스트를 배우는데 도"
"움이 되는 100개 이상의 연습문제\n"
"* [Ferrous Teaching Material](https://ferrous-systems.github.io/teaching-"
"material/index.html): 러스트 언어의 기본부터 고급을 전부 다루는 일련의 작은 "
"프레젠테이션, 웹 어셈블리, async/await 같은 부분도 함께 다룹니다.\n"
"* [Beginner's Series to Rust](https://docs.microsoft.com/en-us/shows/"
"beginners-series-to-rust/), [Take your first steps with Rust](https://docs."
"microsoft.com/en-us/learn/paths/rust-first-steps/): 첫번째는 35개의 시리즈 영"
"상이며 두번째는 러스트의 문법과 구조를 다루는 11개의 모듈 세트입니다."
#: src/other-resources.md:59
msgid ""
"Please see the [Little Book of Rust Books](https://lborb.github.io/book/) "
"for\n"
"even more Rust books."
msgstr ""
"[Little Book of Rust Books](https://lborb.github.io/book/)에서 더 많은 러스"
"트 북을 확인해보세요."
#: src/credits.md:1
msgid "# Credits"
msgstr "# Credits"
#: src/credits.md:3
msgid ""
"The material here builds on top of the many great sources of Rust "
"documentation.\n"
"See the page on [other resources](other-resources.md) for a full list of "
"useful\n"
"resources."
msgstr ""
"이 자료는 많은 훌륭한 러스트 문서들의 도움을 받아 작성되었습니다. \n"
"유용한 자료의 전체 목록은 [other resources](other-resources.md)에서 살펴보시"
"기 바랍니다."
#: src/credits.md:7
msgid ""
"The material of Comprehensive Rust is licensed under the terms of the Apache "
"2.0\n"
"license, please see [`LICENSE.txt`](../LICENSE.txt) for details."
msgstr ""
"Comprehensive Rust의 자료는 Apache 2.0 라이선스를 따릅니다. 자세한건 "
"[`LICENSE.txt`](../LICENSE.txt) 확인해 보시기 바랍니다."
#: src/credits.md:10
msgid "## Rust by Example"
msgstr ""
#: src/credits.md:12
msgid ""
"Some examples and exercises have been copied and adapted from [Rust by\n"
"Example](https://doc.rust-lang.org/rust-by-example/). Please see the\n"
"`third_party/rust-by-example/` directory for details, including the license\n"
"terms."
msgstr ""
"일부 예제와 연습문제는 [Rust by Example](https://doc.rust-lang.org/rust-by-"
"example/)을 참조하였습니다. 라이선스 조항을 포함하여 저장소의 `third_party/"
"rust-by-example/` 폴더를 참조하시기 바랍니다."
#: src/credits.md:17
msgid "## Rust on Exercism"
msgstr ""
#: src/credits.md:19
msgid ""
"Some exercises have been copied and adapted from [Rust on\n"
"Exercism](https://exercism.org/tracks/rust). Please see the\n"
"`third_party/rust-on-exercism/` directory for details, including the "
"license\n"
"terms."
msgstr ""
"일부 연습문제는 [Rust on Exercism](https://exercism.org/tracks/rust)을 참조하"
"였습니다.\n"
"라이선스 조항을 포함하여 저장소의 `third_party/rust-on-exercism/`폴더를 참조"
"하시기 바랍니다."
#: src/credits.md:24
msgid "## CXX"
msgstr ""
#: src/credits.md:26
msgid ""
"The [Interoperability with C++](android/interoperability/cpp.md) section "
"uses an\n"
"image from [CXX](https://cxx.rs/). Please see the `third_party/cxx/` "
"directory\n"
"for details, including the license terms."
msgstr ""
"4일차 오후 강의 중 [Interoperability with C++](android/interoperability/cpp."
"md)에서는 [CXX](https://cxx.rs/)의 이미지를 사용하였습니다. \n"
"라이선스 조항을 포함하여 저장소의 `third_party/cxx/`폴더를 참조하시기 바랍니"
"다."
#: src/exercises/solutions.md:1
msgid "# Solutions"
msgstr "# 해답"
#: src/exercises/solutions.md:3
msgid "You will find solutions to the exercises on the following pages."
msgstr "연습문제의 해답은 다음 페이지에서 확인할 수 있습니다."
#: src/exercises/solutions.md:5
msgid ""
"Feel free to ask questions about the solutions [on\n"
"GitHub](https://github.com/google/comprehensive-rust/discussions). Let us "
"know\n"
"if you have a different or better solution than what is presented here."
msgstr ""
"[깃허브](https://github.com/google/comprehensive-rust/discussions)에서 이에 "
"대해 자유롭게 질문하시고 더 나은 솔루션이 있다면 알려주시기 바랍니다."
#: src/exercises/solutions.md:10
msgid ""
"> **Note:** Please ignore the `// ANCHOR: label` and `// ANCHOR_END: label`\n"
"> comments you see in the solutions. They are there to make it possible to\n"
"> re-use parts of the solutions as the exercises."
msgstr ""
"> **참고:** `// ANCHOR: label`과 `// ANCHOR_END: label` 주석은 문제를 구성하"
"기 위한 메타 주석으로 무시하시면 됩니다."
#: src/exercises/day-1/solutions-morning.md:1
msgid "# Day 1 Morning Exercises"
msgstr "# 1일차 오전 연습문제"
#: src/exercises/day-1/solutions-morning.md:3
msgid "## Arrays and `for` Loops"
msgstr "## 배열과 `for`반복문"
#: src/exercises/day-1/solutions-morning.md:5
msgid "([back to exercise](for-loops.md))"
msgstr ""
#: src/exercises/day-1/solutions-morning.md:7
#: src/exercises/day-1/solutions-afternoon.md:7
#: src/exercises/day-2/solutions-morning.md:7
#: src/exercises/day-2/solutions-afternoon.md:7
#: src/exercises/day-2/solutions-afternoon.md:102
#: src/exercises/day-3/solutions-morning.md:7
#: src/exercises/day-3/solutions-afternoon.md:7
#: src/exercises/day-4/solutions-morning.md:7
msgid ""
"```rust\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."
msgstr ""
#: src/exercises/day-1/solutions-morning.md:22
msgid ""
"// ANCHOR: transpose\n"
"fn transpose(matrix: [[i32; 3]; 3]) -> [[i32; 3]; 3] {\n"
" // ANCHOR_END: transpose\n"
" let mut result = [[0; 3]; 3];\n"
" for i in 0..3 {\n"
" for j in 0..3 {\n"
" result[j][i] = matrix[i][j];\n"
" }\n"
" }\n"
" return result;\n"
"}"
msgstr ""
#: src/exercises/day-1/solutions-morning.md:34
msgid ""
"// ANCHOR: pretty_print\n"
"fn pretty_print(matrix: &[[i32; 3]; 3]) {\n"
" // ANCHOR_END: pretty_print\n"
" for row in matrix {\n"
" println!(\"{row:?}\");\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-1/solutions-morning.md:42
msgid ""
"// ANCHOR: tests\n"
"#[test]\n"
"fn test_transpose() {\n"
" let matrix = [\n"
" [101, 102, 103], //\n"
" [201, 202, 203],\n"
" [301, 302, 303],\n"
" ];\n"
" let transposed = transpose(matrix);\n"
" assert_eq!(\n"
" transposed,\n"
" [\n"
" [101, 201, 301], //\n"
" [102, 202, 302],\n"
" [103, 203, 303],\n"
" ]\n"
" );\n"
"}\n"
"// ANCHOR_END: tests"
msgstr ""
#: src/exercises/day-1/solutions-morning.md:62
msgid ""
"// ANCHOR: main\n"
"fn main() {\n"
" let matrix = [\n"
" [101, 102, 103], // <-- the comment makes rustfmt add a newline\n"
" [201, 202, 203],\n"
" [301, 302, 303],\n"
" ];"
msgstr ""
#: src/exercises/day-1/solutions-morning.md:73
msgid ""
" let transposed = transpose(matrix);\n"
" println!(\"transposed:\");\n"
" pretty_print(&transposed);\n"
"}\n"
"```\n"
"### Bonus question"
msgstr ""
#: src/exercises/day-1/solutions-morning.md:80
msgid ""
"It honestly doesn't work so well. It might seem that we could use a slice-of-"
"slices (`&[&[i32]]`) as the input type to transpose and thus make our "
"function handle any size of matrix. However, this quickly breaks down: the "
"return type cannot be `&[&[i32]]` since it needs to own the data you return."
msgstr ""
"사실 잘 동작하진 않습니다. slice-of-slices (`&[&[i32]]`)을 입력 타입으로 사용"
"하여 모든 크기의 행렬을 처리할 수 있습니다. 하지만 리턴 값을 소유해야 하기때"
"문에 `&[&[i32]]` 타입을 사용할 순 없습니다. "
#: src/exercises/day-1/solutions-morning.md:82
msgid ""
"You can attempt to use something like `Vec<Vec<i32>>`, but this doesn't work "
"very well either: it's hard to convert from `Vec<Vec<i32>>` to `&[&[i32]]` "
"so now you cannot easily use `pretty_print` either."
msgstr ""
"`Vec<Vec<i32>>`와 같은 타입을 사용하려고 시도할 수도 있지만 역시 잘 동작하진 "
"않습니다: `Vec<Vec<i32>>` 타입을 `&[&[i32]]`로 변환하는 것이 어렵기 때문에 "
"`pretty_print`을 사용하는데 어려움이 있습니다."
#: src/exercises/day-1/solutions-morning.md:84
msgid ""
"In addition, the type itself would not enforce that the child slices are of "
"the same length, so such variable could contain an invalid matrix."
msgstr ""
"또한, 슬라이스 타입은 길이를 포함하지 않기 때문에 한 단계 아래의 슬라이스들이"
" 같은 길이(_역주: 3_)임을 보장할 수 없습니다. 때문에 슬라이스 타입의 변수에는"
" 잘못된 행렬(_역주: 각 열이나 행의 길이가 다른_)이 전달될 수 있습니다."
#: src/exercises/day-1/solutions-afternoon.md:1
msgid "# Day 1 Afternoon Exercises"
msgstr "# 1일차 오후 연습문제"
#: src/exercises/day-1/solutions-afternoon.md:3
msgid "## Designing a Library"
msgstr "## 도서관 설계"
#: src/exercises/day-1/solutions-afternoon.md:5
msgid "([back to exercise](book-library.md))"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:22
msgid ""
"// ANCHOR: setup\n"
"struct Library {\n"
" books: Vec<Book>,\n"
"}"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:42
msgid ""
"// This makes it possible to print Book values with {}.\n"
"impl std::fmt::Display for Book {\n"
" fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n"
" write!(f, \"{} ({})\", self.title, self.year)\n"
" }\n"
"}\n"
"// ANCHOR_END: setup"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:50
msgid ""
"// ANCHOR: Library_new\n"
"impl Library {\n"
" fn new() -> Library {\n"
" // ANCHOR_END: Library_new\n"
" Library { books: Vec::new() }\n"
" }"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:57
msgid ""
" // ANCHOR: Library_len\n"
" //fn len(self) -> usize {\n"
" // unimplemented!()\n"
" //}\n"
" // ANCHOR_END: Library_len\n"
" fn len(&self) -> usize {\n"
" self.books.len()\n"
" }"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:66
msgid ""
" // ANCHOR: Library_is_empty\n"
" //fn is_empty(self) -> bool {\n"
" // unimplemented!()\n"
" //}\n"
" // ANCHOR_END: Library_is_empty\n"
" fn is_empty(&self) -> bool {\n"
" self.books.is_empty()\n"
" }"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:75
msgid ""
" // ANCHOR: Library_add_book\n"
" //fn add_book(self, book: Book) {\n"
" // unimplemented!()\n"
" //}\n"
" // ANCHOR_END: Library_add_book\n"
" fn add_book(&mut self, book: Book) {\n"
" self.books.push(book)\n"
" }"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:84
msgid ""
" // ANCHOR: Library_print_books\n"
" //fn print_books(self) {\n"
" // unimplemented!()\n"
" //}\n"
" // ANCHOR_END: Library_print_books\n"
" fn print_books(&self) {\n"
" for book in &self.books {\n"
" println!(\"{}\", book);\n"
" }\n"
" }"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:95
msgid ""
" // ANCHOR: Library_oldest_book\n"
" //fn oldest_book(self) -> Option<&Book> {\n"
" // unimplemented!()\n"
" //}\n"
" // ANCHOR_END: Library_oldest_book\n"
" fn oldest_book(&self) -> Option<&Book> {\n"
" self.books.iter().min_by_key(|book| book.year)\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:105
msgid ""
"// ANCHOR: main\n"
"// This shows the desired behavior. Uncomment the code below and\n"
"// implement the missing methods. You will need to update the\n"
"// method signatures, including the \"self\" parameter! You may\n"
"// also need to update the variable bindings within main.\n"
"fn main() {\n"
" let library = Library::new();"
msgstr ""
"// 아래 소스 주석을 제거하고 누락된 메서드를 구현하세요\n"
"// 미구현 메서드도 존재하므로 메서드 시그니처를 업데이트 하세요(self 포함)\n"
"fn main() {\n"
" let library = Library::new();"
#: src/exercises/day-1/solutions-afternoon.md:113
msgid ""
" //println!(\"Our library is empty: {}\", library.is_empty());\n"
" //\n"
" //library.add_book(Book::new(\"Lord of the Rings\", 1954));\n"
" //library.add_book(Book::new(\"Alice's Adventures in Wonderland\", "
"1865));\n"
" //\n"
" //library.print_books();\n"
" //\n"
" //match library.oldest_book() {\n"
" // Some(book) => println!(\"My oldest book is {book}\"),\n"
" // None => println!(\"My library is empty!\"),\n"
" //}\n"
" //\n"
" //println!(\"Our library has {} books\", library.len());\n"
"}\n"
"// ANCHOR_END: main"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:129
msgid ""
"#[test]\n"
"fn test_library_len() {\n"
" let mut library = Library::new();\n"
" assert_eq!(library.len(), 0);\n"
" assert!(library.is_empty());"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:135
msgid ""
" library.add_book(Book::new(\"Lord of the Rings\", 1954));\n"
" library.add_book(Book::new(\"Alice's Adventures in Wonderland\", "
"1865));\n"
" assert_eq!(library.len(), 2);\n"
" assert!(!library.is_empty());\n"
"}"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:141
msgid ""
"#[test]\n"
"fn test_library_is_empty() {\n"
" let mut library = Library::new();\n"
" assert!(library.is_empty());"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:146
msgid ""
" library.add_book(Book::new(\"Lord of the Rings\", 1954));\n"
" assert!(!library.is_empty());\n"
"}"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:150
msgid ""
"#[test]\n"
"fn test_library_print_books() {\n"
" let mut library = Library::new();\n"
" library.add_book(Book::new(\"Lord of the Rings\", 1954));\n"
" library.add_book(Book::new(\"Alice's Adventures in Wonderland\", "
"1865));\n"
" // We could try and capture stdout, but let us just call the\n"
" // method to start with.\n"
" library.print_books();\n"
"}"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:160
msgid ""
"#[test]\n"
"fn test_library_oldest_book() {\n"
" let mut library = Library::new();\n"
" assert!(library.oldest_book().is_none());"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:165
msgid ""
" library.add_book(Book::new(\"Lord of the Rings\", 1954));\n"
" assert_eq!(\n"
" library.oldest_book().map(|b| b.title.as_str()),\n"
" Some(\"Lord of the Rings\")\n"
" );"
msgstr ""
#: src/exercises/day-1/solutions-afternoon.md:171
msgid ""
" library.add_book(Book::new(\"Alice's Adventures in Wonderland\", "
"1865));\n"
" assert_eq!(\n"
" library.oldest_book().map(|b| b.title.as_str()),\n"
" Some(\"Alice's Adventures in Wonderland\")\n"
" );\n"
"}\n"
"```"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:1
msgid "# Day 2 Morning Exercises"
msgstr "# 2일차 오전 연습문제"
#: src/exercises/day-2/solutions-morning.md:3
msgid "## Points and Polygons"
msgstr "## 점과 다각형"
#: src/exercises/day-2/solutions-morning.md:5
msgid "([back to exercise](points-polygons.md))"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:22
msgid ""
"#[derive(Debug, Copy, Clone, PartialEq, Eq)]\n"
"// ANCHOR: Point\n"
"pub struct Point {\n"
" // ANCHOR_END: Point\n"
" x: i32,\n"
" y: i32,\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:30
msgid ""
"// ANCHOR: Point-impl\n"
"impl Point {\n"
" // ANCHOR_END: Point-impl\n"
" pub fn new(x: i32, y: i32) -> Point {\n"
" Point { x, y }\n"
" }"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:37
msgid ""
" pub fn magnitude(self) -> f64 {\n"
" f64::from(self.x.pow(2) + self.y.pow(2)).sqrt()\n"
" }"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:41
msgid ""
" pub fn dist(self, other: Point) -> f64 {\n"
" (self - other).magnitude()\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:49
msgid ""
" fn add(self, other: Self) -> Self::Output {\n"
" Self {\n"
" x: self.x + other.x,\n"
" y: self.y + other.y,\n"
" }\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:57
msgid ""
"impl std::ops::Sub for Point {\n"
" type Output = Self;"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:60
msgid ""
" fn sub(self, other: Self) -> Self::Output {\n"
" Self {\n"
" x: self.x - other.x,\n"
" y: self.y - other.y,\n"
" }\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:68
msgid ""
"// ANCHOR: Polygon\n"
"pub struct Polygon {\n"
" // ANCHOR_END: Polygon\n"
" points: Vec<Point>,\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:74
msgid ""
"// ANCHOR: Polygon-impl\n"
"impl Polygon {\n"
" // ANCHOR_END: Polygon-impl\n"
" pub fn new() -> Polygon {\n"
" Polygon { points: Vec::new() }\n"
" }"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:81
msgid ""
" pub fn add_point(&mut self, point: Point) {\n"
" self.points.push(point);\n"
" }"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:85
msgid ""
" pub fn left_most_point(&self) -> Option<Point> {\n"
" self.points.iter().min_by_key(|p| p.x).copied()\n"
" }"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:89
msgid ""
" pub fn iter(&self) -> impl Iterator<Item = &Point> {\n"
" self.points.iter()\n"
" }"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:93
msgid ""
" pub fn length(&self) -> f64 {\n"
" if self.points.is_empty() {\n"
" return 0.0;\n"
" }"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:98
msgid ""
" let mut result = 0.0;\n"
" let mut last_point = self.points[0];\n"
" for point in &self.points[1..] {\n"
" result += last_point.dist(*point);\n"
" last_point = *point;\n"
" }\n"
" result += last_point.dist(self.points[0]);\n"
" result\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:109
msgid ""
"// ANCHOR: Circle\n"
"pub struct Circle {\n"
" // ANCHOR_END: Circle\n"
" center: Point,\n"
" radius: i32,\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:116
msgid ""
"// ANCHOR: Circle-impl\n"
"impl Circle {\n"
" // ANCHOR_END: Circle-impl\n"
" pub fn new(center: Point, radius: i32) -> Circle {\n"
" Circle { center, radius }\n"
" }"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:123
msgid ""
" pub fn circumference(&self) -> f64 {\n"
" 2.0 * std::f64::consts::PI * f64::from(self.radius)\n"
" }"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:127
msgid ""
" pub fn dist(&self, other: &Self) -> f64 {\n"
" self.center.dist(other.center)\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:132
msgid ""
"// ANCHOR: Shape\n"
"pub enum Shape {\n"
" Polygon(Polygon),\n"
" Circle(Circle),\n"
"}\n"
"// ANCHOR_END: Shape"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:139
msgid ""
"impl From<Polygon> for Shape {\n"
" fn from(poly: Polygon) -> Self {\n"
" Shape::Polygon(poly)\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:145
msgid ""
"impl From<Circle> for Shape {\n"
" fn from(circle: Circle) -> Self {\n"
" Shape::Circle(circle)\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:151
msgid ""
"impl Shape {\n"
" pub fn perimeter(&self) -> f64 {\n"
" match self {\n"
" Shape::Polygon(poly) => poly.length(),\n"
" Shape::Circle(circle) => circle.circumference(),\n"
" }\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:160
msgid ""
"// ANCHOR: unit-tests\n"
"#[cfg(test)]\n"
"mod tests {\n"
" use super::*;"
msgstr ""
#: src/exercises/day-2/solutions-morning.md:213
msgid ""
" #[test]\n"
" fn test_shape_perimeters() {\n"
" let mut poly = Polygon::new();\n"
" poly.add_point(Point::new(12, 13));\n"
" poly.add_point(Point::new(17, 11));\n"
" poly.add_point(Point::new(16, 16));\n"
" let shapes = vec![\n"
" Shape::from(poly),\n"
" Shape::from(Circle::new(Point::new(10, 20), 5)),\n"
" ];\n"
" let perimeters = shapes\n"
" .iter()\n"
" .map(Shape::perimeter)\n"
" .map(round_two_digits)\n"
" .collect::<Vec<_>>();\n"
" assert_eq!(perimeters, vec![15.48, 31.42]);\n"
" }\n"
"}\n"
"// ANCHOR_END: unit-tests"
msgstr ""
#: src/exercises/day-2/solutions-afternoon.md:1
msgid "# Day 2 Afternoon Exercises"
msgstr "# 2일차 오후 연습문제"
#: src/exercises/day-2/solutions-afternoon.md:3
msgid "## Luhn Algorithm"
msgstr "## 룬 알고리즘"
#: src/exercises/day-2/solutions-afternoon.md:5
msgid "([back to exercise](luhn.md))"
msgstr ""
#: src/exercises/day-2/solutions-afternoon.md:22
msgid ""
"// ANCHOR: luhn\n"
"pub fn luhn(cc_number: &str) -> bool {\n"
" // ANCHOR_END: luhn\n"
" let mut digits_seen = 0;\n"
" let mut sum = 0;\n"
" for (i, ch) in cc_number.chars().rev().filter(|&ch| ch != ' ')."
"enumerate() {\n"
" match ch.to_digit(10) {\n"
" Some(d) => {\n"
" sum += if i % 2 == 1 {\n"
" let dd = d * 2;\n"
" dd / 10 + dd % 10\n"
" } else {\n"
" d\n"
" };\n"
" digits_seen += 1;\n"
" }\n"
" None => return false,\n"
" }\n"
" }"
msgstr ""
#: src/exercises/day-2/solutions-afternoon.md:42
msgid ""
" if digits_seen < 2 {\n"
" return false;\n"
" }"
msgstr ""
#: src/exercises/day-2/solutions-afternoon.md:46
msgid ""
" sum % 10 == 0\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-afternoon.md:49
msgid ""
"fn main() {\n"
" let cc_number = \"1234 5678 1234 5670\";\n"
" println!(\n"
" \"Is {} a valid credit card number? {}\",\n"
" cc_number,\n"
" if luhn(cc_number) { \"yes\" } else { \"no\" }\n"
" );\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-afternoon.md:58
msgid ""
"// ANCHOR: unit-tests\n"
"#[test]\n"
"fn test_non_digit_cc_number() {\n"
" assert!(!luhn(\"foo\"));\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-afternoon.md:89
msgid ""
"#[test]\n"
"fn test_invalid_cc_number() {\n"
" assert!(!luhn(\"4223 9826 4026 9299\"));\n"
" assert!(!luhn(\"4539 3195 0343 6476\"));\n"
" assert!(!luhn(\"8273 1232 7352 0569\"));\n"
"}\n"
"// ANCHOR_END: unit-tests\n"
"```"
msgstr ""
#: src/exercises/day-2/solutions-afternoon.md:98
msgid "## Strings and Iterators"
msgstr "## 문자열과 반복자"
#: src/exercises/day-2/solutions-afternoon.md:100
msgid "([back to exercise](strings-iterators.md))"
msgstr ""
#: src/exercises/day-2/solutions-afternoon.md:117
msgid ""
"// ANCHOR: prefix_matches\n"
"pub fn prefix_matches(prefix: &str, request_path: &str) -> bool {\n"
" // ANCHOR_END: prefix_matches\n"
" let prefixes = prefix.split('/');\n"
" let request_paths = request_path\n"
" .split('/')\n"
" .map(|p| Some(p))\n"
" .chain(std::iter::once(None));"
msgstr ""
#: src/exercises/day-2/solutions-afternoon.md:126
msgid ""
" for (prefix, request_path) in prefixes.zip(request_paths) {\n"
" match request_path {\n"
" Some(request_path) => {\n"
" if (prefix != \"*\") && (prefix != request_path) {\n"
" return false;\n"
" }\n"
" }\n"
" None => return false,\n"
" }\n"
" }\n"
" true\n"
"}"
msgstr ""
#: src/exercises/day-2/solutions-afternoon.md:139
msgid ""
"// ANCHOR: unit-tests\n"
"#[test]\n"
"fn test_matches_without_wildcard() {\n"
" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers\"));\n"
" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/"
"abc-123\"));\n"
" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/abc/"
"books\"));"
msgstr ""
#: src/exercises/day-2/solutions-afternoon.md:166
msgid ""
" assert!(!prefix_matches(\"/v1/publishers/*/books\", \"/v1/"
"publishers\"));\n"
" assert!(!prefix_matches(\n"
" \"/v1/publishers/*/books\",\n"
" \"/v1/publishers/foo/booksByAuthor\"\n"
" ));\n"
"}\n"
"// ANCHOR_END: unit-tests\n"
"```"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:1
msgid "# Day 3 Morning Exercise"
msgstr "# 3일차 오전 연습문제"
#: src/exercises/day-3/solutions-morning.md:3
msgid "## A Simple GUI Library"
msgstr "## 간단한 GUI 라이브러리"
#: src/exercises/day-3/solutions-morning.md:5
msgid "([back to exercise](simple-gui.md))"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:22
msgid ""
"// ANCHOR: setup\n"
"pub trait Widget {\n"
" /// Natural width of `self`.\n"
" fn width(&self) -> usize;"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:82
msgid "// ANCHOR_END: setup"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:84
msgid ""
"// ANCHOR: Window-width\n"
"impl Widget for Window {\n"
" fn width(&self) -> usize {\n"
" // ANCHOR_END: Window-width\n"
" std::cmp::max(\n"
" self.title.chars().count(),\n"
" self.widgets.iter().map(|w| w.width()).max().unwrap_or(0),\n"
" )\n"
" }"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:94
msgid ""
" // ANCHOR: Window-draw_into\n"
" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
" // ANCHOR_END: Window-draw_into\n"
" let mut inner = String::new();\n"
" for widget in &self.widgets {\n"
" widget.draw_into(&mut inner);\n"
" }"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:102
msgid " let window_width = self.width();"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:104
msgid ""
" // TODO: after learning about error handling, you can change\n"
" // draw_into to return Result<(), std::fmt::Error>. Then use\n"
" // the ?-operator here instead of .unwrap().\n"
" writeln!(buffer, \"+-{:-<window_width$}-+\", \"\").unwrap();\n"
" writeln!(buffer, \"| {:^window_width$} |\", &self.title).unwrap();\n"
" writeln!(buffer, \"+={:=<window_width$}=+\", \"\").unwrap();\n"
" for line in inner.lines() {\n"
" writeln!(buffer, \"| {:window_width$} |\", line).unwrap();\n"
" }\n"
" writeln!(buffer, \"+-{:-<window_width$}-+\", \"\").unwrap();\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:117
msgid ""
"// ANCHOR: Button-width\n"
"impl Widget for Button {\n"
" fn width(&self) -> usize {\n"
" // ANCHOR_END: Button-width\n"
" self.label.width() + 8 // add a bit of padding\n"
" }"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:124
msgid ""
" // ANCHOR: Button-draw_into\n"
" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
" // ANCHOR_END: Button-draw_into\n"
" let width = self.width();\n"
" let mut label = String::new();\n"
" self.label.draw_into(&mut label);"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:131
msgid ""
" writeln!(buffer, \"+{:-<width$}+\", \"\").unwrap();\n"
" for line in label.lines() {\n"
" writeln!(buffer, \"|{:^width$}|\", &line).unwrap();\n"
" }\n"
" writeln!(buffer, \"+{:-<width$}+\", \"\").unwrap();\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:139
msgid ""
"// ANCHOR: Label-width\n"
"impl Widget for Label {\n"
" fn width(&self) -> usize {\n"
" // ANCHOR_END: Label-width\n"
" self.label\n"
" .lines()\n"
" .map(|line| line.chars().count())\n"
" .max()\n"
" .unwrap_or(0)\n"
" }"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:150
msgid ""
" // ANCHOR: Label-draw_into\n"
" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
" // ANCHOR_END: Label-draw_into\n"
" writeln!(buffer, \"{}\", &self.label).unwrap();\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:157
msgid ""
"// ANCHOR: main\n"
"fn main() {\n"
" let mut window = Window::new(\"Rust GUI Demo 1.23\");\n"
" window.add_widget(Box::new(Label::new(\"This is a small text GUI demo."
"\")));\n"
" window.add_widget(Box::new(Button::new(\n"
" \"Click me!\",\n"
" Box::new(|| println!(\"You clicked the button!\")),\n"
" )));\n"
" window.draw();\n"
"}\n"
"// ANCHOR_END: main\n"
"```"
msgstr ""
#: src/exercises/day-3/solutions-afternoon.md:1
msgid "# Day 3 Afternoon Exercises"
msgstr "# 3일차 오후 연습문제"
#: src/exercises/day-3/solutions-afternoon.md:3
msgid "## Safe FFI Wrapper"
msgstr "## FFI래퍼"
#: src/exercises/day-3/solutions-afternoon.md:5
msgid "([back to exercise](safe-ffi-wrapper.md))"
msgstr ""
#: src/exercises/day-3/solutions-afternoon.md:22
msgid ""
"// ANCHOR: ffi\n"
"mod ffi {\n"
" use std::os::raw::{c_char, c_int, c_long, c_ulong, c_ushort};"
msgstr ""
#: src/exercises/day-3/solutions-afternoon.md:53
msgid ""
"#[derive(Debug)]\n"
"struct DirectoryIterator {\n"
" path: CString,\n"
" dir: *mut ffi::DIR,\n"
"}\n"
"// ANCHOR_END: ffi"
msgstr ""
#: src/exercises/day-3/solutions-afternoon.md:60
msgid ""
"// ANCHOR: DirectoryIterator\n"
"impl DirectoryIterator {\n"
" fn new(path: &str) -> Result<DirectoryIterator, String> {\n"
" // Call opendir and return a Ok value if that worked,\n"
" // otherwise return Err with a message.\n"
" // ANCHOR_END: DirectoryIterator\n"
" let path = CString::new(path).map_err(|err| format!(\"Invalid path: "
"{err}\"))?;\n"
" // SAFETY: path.as_ptr() cannot be NULL.\n"
" let dir = unsafe { ffi::opendir(path.as_ptr()) };\n"
" if dir.is_null() {\n"
" Err(format!(\"Could not open {:?}\", path))\n"
" } else {\n"
" Ok(DirectoryIterator { path, dir })\n"
" }\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/solutions-afternoon.md:77
msgid ""
"// ANCHOR: Iterator\n"
"impl Iterator for DirectoryIterator {\n"
" type Item = OsString;\n"
" fn next(&mut self) -> Option<OsString> {\n"
" // Keep calling readdir until we get a NULL pointer back.\n"
" // ANCHOR_END: Iterator\n"
" // SAFETY: self.dir is never NULL.\n"
" let dirent = unsafe { ffi::readdir(self.dir) };\n"
" if dirent.is_null() {\n"
" // We have reached the end of the directory.\n"
" return None;\n"
" }\n"
" // SAFETY: dirent is not NULL and dirent.d_name is NUL\n"
" // terminated.\n"
" let d_name = unsafe { CStr::from_ptr((*dirent).d_name.as_ptr()) };\n"
" let os_str = OsStr::from_bytes(d_name.to_bytes());\n"
" Some(os_str.to_owned())\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/solutions-afternoon.md:97
msgid ""
"// ANCHOR: Drop\n"
"impl Drop for DirectoryIterator {\n"
" fn drop(&mut self) {\n"
" // Call closedir as needed.\n"
" // ANCHOR_END: Drop\n"
" if !self.dir.is_null() {\n"
" // SAFETY: self.dir is not NULL.\n"
" if unsafe { ffi::closedir(self.dir) } != 0 {\n"
" panic!(\"Could not close {:?}\", self.path);\n"
" }\n"
" }\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-3/solutions-afternoon.md:111
msgid ""
"// ANCHOR: main\n"
"fn main() -> Result<(), String> {\n"
" let iter = DirectoryIterator::new(\".\")?;\n"
" println!(\"files: {:#?}\", iter.collect::<Vec<_>>());\n"
" Ok(())\n"
"}\n"
"// ANCHOR_END: main\n"
"```"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:1
msgid "# Day 4 Morning Exercise"
msgstr "# 4일차 오전 연습문제"
#: src/exercises/day-4/solutions-morning.md:3
msgid "## Dining Philosophers"
msgstr "## 식사하는 철학자들"
#: src/exercises/day-4/solutions-morning.md:5
msgid "([back to exercise](dining-philosophers.md))"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:22
msgid ""
"// ANCHOR: Philosopher\n"
"use std::sync::mpsc;\n"
"use std::sync::{Arc, Mutex};\n"
"use std::thread;\n"
"use std::time::Duration;"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:30
msgid ""
"struct Philosopher {\n"
" name: String,\n"
" // ANCHOR_END: Philosopher\n"
" left_fork: Arc<Mutex<Fork>>,\n"
" right_fork: Arc<Mutex<Fork>>,\n"
" thoughts: mpsc::SyncSender<String>,\n"
"}"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:38
msgid ""
"// ANCHOR: Philosopher-think\n"
"impl Philosopher {\n"
" fn think(&self) {\n"
" self.thoughts\n"
" .send(format!(\"Eureka! {} has a new idea!\", &self.name))\n"
" .unwrap();\n"
" }\n"
" // ANCHOR_END: Philosopher-think"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:47
msgid ""
" // ANCHOR: Philosopher-eat\n"
" fn eat(&self) {\n"
" // ANCHOR_END: Philosopher-eat\n"
" println!(\"{} is trying to eat\", &self.name);\n"
" let left = self.left_fork.lock().unwrap();\n"
" let right = self.right_fork.lock().unwrap();"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:54
msgid ""
" // ANCHOR: Philosopher-eat-end\n"
" println!(\"{} is eating...\", &self.name);\n"
" thread::sleep(Duration::from_millis(10));\n"
" }\n"
"}"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:63
msgid ""
"fn main() {\n"
" // ANCHOR_END: Philosopher-eat-end\n"
" let (tx, rx) = mpsc::sync_channel(10);"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:67
msgid ""
" let forks = (0..PHILOSOPHERS.len())\n"
" .map(|_| Arc::new(Mutex::new(Fork)))\n"
" .collect::<Vec<_>>();"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:71
msgid ""
" for i in 0..forks.len() {\n"
" let tx = tx.clone();\n"
" let mut left_fork = forks[i].clone();\n"
" let mut right_fork = forks[(i + 1) % forks.len()].clone();"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:76
msgid ""
" // To avoid a deadlock, we have to break the symmetry\n"
" // somewhere. This will swap the forks without deinitializing\n"
" // either of them.\n"
" if i == forks.len() - 1 {\n"
" std::mem::swap(&mut left_fork, &mut right_fork);\n"
" }"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:83
msgid ""
" let philosopher = Philosopher {\n"
" name: PHILOSOPHERS[i].to_string(),\n"
" thoughts: tx,\n"
" left_fork,\n"
" right_fork,\n"
" };"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:90
msgid ""
" thread::spawn(move || {\n"
" for _ in 0..100 {\n"
" philosopher.eat();\n"
" philosopher.think();\n"
" }\n"
" });\n"
" }"
msgstr ""
#: src/exercises/day-4/solutions-morning.md:98
msgid ""
" drop(tx);\n"
" for thought in rx {\n"
" println!(\"{}\", thought);\n"
" }\n"
"}\n"
"```"
msgstr ""