mirror of
https://github.com/google/comprehensive-rust.git
synced 2024-11-25 01:16:12 +02:00
620b8a3b72
I made a small mistake during the refactor in #1492: I removed the `MDBOOK_BOOK__LANGUAGE` environment variable, which means that we ended up testing the original Rust code snippets again and again. This commit also fixes the few typos that have sneaked into the translations due to the lack of testing.
37499 lines
1.3 MiB
37499 lines
1.3 MiB
msgid ""
|
|
msgstr ""
|
|
"Project-Id-Version: [한국어]Comprehensive Rust 🦀\n"
|
|
"POT-Creation-Date: 2024-03-14T10:52:40-04:00\n"
|
|
"PO-Revision-Date: \n"
|
|
"Last-Translator: \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"
|
|
"X-Generator: Poedit 3.3.2\n"
|
|
|
|
#: src/SUMMARY.md src/index.md
|
|
msgid "Welcome to Comprehensive Rust 🦀"
|
|
msgstr "Comprehensive Rust에 오신 것을 환영합니다 🦀"
|
|
|
|
#: src/SUMMARY.md src/running-the-course.md
|
|
msgid "Running the Course"
|
|
msgstr "강의 진행"
|
|
|
|
#: src/SUMMARY.md src/running-the-course/course-structure.md
|
|
msgid "Course Structure"
|
|
msgstr "강의 구성"
|
|
|
|
#: src/SUMMARY.md src/running-the-course/keyboard-shortcuts.md
|
|
msgid "Keyboard Shortcuts"
|
|
msgstr "단축키"
|
|
|
|
#: src/SUMMARY.md src/running-the-course/translations.md
|
|
msgid "Translations"
|
|
msgstr "다른 언어들"
|
|
|
|
#: src/SUMMARY.md src/cargo.md
|
|
msgid "Using Cargo"
|
|
msgstr "카고 사용하기"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Rust Ecosystem"
|
|
msgstr "러스트 생태계"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Code Samples"
|
|
msgstr "코드 샘플"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Running Cargo Locally"
|
|
msgstr "카고(Cargo) 수행하기"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Day 1: Morning"
|
|
msgstr "1일차 오전"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Welcome"
|
|
msgstr "개요"
|
|
|
|
#: src/SUMMARY.md src/hello-world.md src/types-and-values/hello-world.md
|
|
#, fuzzy
|
|
msgid "Hello, World"
|
|
msgstr "Hello World!"
|
|
|
|
#: src/SUMMARY.md src/hello-world/what-is-rust.md
|
|
msgid "What is Rust?"
|
|
msgstr "러스트란?"
|
|
|
|
#: src/SUMMARY.md src/hello-world/benefits.md
|
|
msgid "Benefits of Rust"
|
|
msgstr "Rust의 이점"
|
|
|
|
#: src/SUMMARY.md src/hello-world/playground.md
|
|
msgid "Playground"
|
|
msgstr "플레이그라운드"
|
|
|
|
#: src/SUMMARY.md src/types-and-values.md
|
|
msgid "Types and Values"
|
|
msgstr "타입 및 값"
|
|
|
|
#: src/SUMMARY.md src/types-and-values/variables.md
|
|
msgid "Variables"
|
|
msgstr "변수"
|
|
|
|
#: src/SUMMARY.md src/types-and-values/values.md
|
|
msgid "Values"
|
|
msgstr "값"
|
|
|
|
#: src/SUMMARY.md src/types-and-values/arithmetic.md
|
|
msgid "Arithmetic"
|
|
msgstr "연산"
|
|
|
|
#: src/SUMMARY.md src/types-and-values/strings.md
|
|
msgid "Strings"
|
|
msgstr "문자열"
|
|
|
|
#: src/SUMMARY.md src/types-and-values/inference.md
|
|
msgid "Type Inference"
|
|
msgstr "타입 추론"
|
|
|
|
#: src/SUMMARY.md src/types-and-values/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Fibonacci"
|
|
msgstr "연습문제: 피보나치"
|
|
|
|
#: src/SUMMARY.md src/types-and-values/solution.md
|
|
#: src/control-flow-basics/solution.md src/tuples-and-arrays/solution.md
|
|
#: src/references/solution.md src/user-defined-types/solution.md
|
|
#: src/pattern-matching/solution.md src/methods-and-traits/solution.md
|
|
#: src/generics/solution.md src/std-types/solution.md
|
|
#: src/std-traits/solution.md src/memory-management/solution.md
|
|
#: src/smart-pointers/solution.md src/borrowing/solution.md
|
|
#: src/slices-and-lifetimes/solution.md src/iterators/solution.md
|
|
#: src/modules/solution.md src/testing/solution.md
|
|
#: src/error-handling/solution.md src/unsafe-rust/solution.md
|
|
#, fuzzy
|
|
msgid "Solution"
|
|
msgstr "해답"
|
|
|
|
#: src/SUMMARY.md src/control-flow-basics.md
|
|
#, fuzzy
|
|
msgid "Control Flow Basics"
|
|
msgstr "흐름 제어"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "`if` Expressions"
|
|
msgstr "`if` 표현식"
|
|
|
|
#: src/SUMMARY.md src/control-flow-basics/loops.md
|
|
#, fuzzy
|
|
msgid "Loops"
|
|
msgstr "배열과 `for` 반복문"
|
|
|
|
#: src/SUMMARY.md src/control-flow-basics/loops/for.md
|
|
#, fuzzy
|
|
msgid "`for`"
|
|
msgstr "배열과 `for` 반복문"
|
|
|
|
#: src/SUMMARY.md src/control-flow-basics/loops/loop.md
|
|
msgid "`loop`"
|
|
msgstr "`loop`"
|
|
|
|
#: src/SUMMARY.md src/control-flow-basics/break-continue.md
|
|
msgid "`break` and `continue`"
|
|
msgstr "`break`와 `continue`"
|
|
|
|
#: src/SUMMARY.md src/control-flow-basics/break-continue/labels.md
|
|
msgid "Labels"
|
|
msgstr ""
|
|
|
|
#: src/SUMMARY.md src/control-flow-basics/blocks-and-scopes.md
|
|
msgid "Blocks and Scopes"
|
|
msgstr "블록 및 범위"
|
|
|
|
#: src/SUMMARY.md src/control-flow-basics/blocks-and-scopes/scopes.md
|
|
msgid "Scopes and Shadowing"
|
|
msgstr "범위(Scopes)와 쉐도잉(Shadowing)"
|
|
|
|
#: src/SUMMARY.md src/control-flow-basics/functions.md
|
|
msgid "Functions"
|
|
msgstr "함수"
|
|
|
|
#: src/SUMMARY.md src/control-flow-basics/macros.md
|
|
msgid "Macros"
|
|
msgstr "매크로"
|
|
|
|
#: src/SUMMARY.md src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Collatz Sequence"
|
|
msgstr "연습문제: 콜라츠 수열"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Day 1: Afternoon"
|
|
msgstr "1일차 오후"
|
|
|
|
#: src/SUMMARY.md src/tuples-and-arrays.md
|
|
msgid "Tuples and Arrays"
|
|
msgstr "튜플 및 배열"
|
|
|
|
#: src/SUMMARY.md src/tuples-and-arrays/arrays.md
|
|
msgid "Arrays"
|
|
msgstr "배열"
|
|
|
|
#: src/SUMMARY.md src/tuples-and-arrays/tuples.md
|
|
msgid "Tuples"
|
|
msgstr "튜플"
|
|
|
|
#: src/SUMMARY.md src/tuples-and-arrays/iteration.md
|
|
#, fuzzy
|
|
msgid "Array Iteration"
|
|
msgstr "Cargo에 통합됨"
|
|
|
|
#: src/SUMMARY.md src/tuples-and-arrays/destructuring.md
|
|
#, fuzzy
|
|
msgid "Patterns and Destructuring"
|
|
msgstr "열거형 분해(역구조화)"
|
|
|
|
#: src/SUMMARY.md src/tuples-and-arrays/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Nested Arrays"
|
|
msgstr "연습문제: 중첩 배열"
|
|
|
|
#: src/SUMMARY.md src/references.md
|
|
msgid "References"
|
|
msgstr "참조"
|
|
|
|
#: src/SUMMARY.md src/references/shared.md
|
|
msgid "Shared References"
|
|
msgstr "공유 참조"
|
|
|
|
#: src/SUMMARY.md src/references/exclusive.md
|
|
#, fuzzy
|
|
msgid "Exclusive References"
|
|
msgstr "허상(dangling) 참조"
|
|
|
|
#: src/SUMMARY.md src/references/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Geometry"
|
|
msgstr "연습문제: 도형"
|
|
|
|
#: src/SUMMARY.md src/user-defined-types.md
|
|
#, fuzzy
|
|
msgid "User-Defined Types"
|
|
msgstr "사용자 정의 타입"
|
|
|
|
#: src/SUMMARY.md src/user-defined-types/named-structs.md
|
|
#, fuzzy
|
|
msgid "Named Structs"
|
|
msgstr "구조체"
|
|
|
|
#: src/SUMMARY.md src/user-defined-types/tuple-structs.md
|
|
msgid "Tuple Structs"
|
|
msgstr "튜플"
|
|
|
|
#: src/SUMMARY.md src/user-defined-types/enums.md
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid "Enums"
|
|
msgstr "열거형"
|
|
|
|
#: src/SUMMARY.md src/user-defined-types/static-and-const.md
|
|
#, fuzzy
|
|
msgid "Static and Const"
|
|
msgstr "정적변수(static)와 상수(const)"
|
|
|
|
#: src/SUMMARY.md src/user-defined-types/aliases.md
|
|
msgid "Type Aliases"
|
|
msgstr "타입 별칭"
|
|
|
|
#: src/SUMMARY.md src/user-defined-types/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Elevator Events"
|
|
msgstr "연습문제: 엘리베이터 이벤트"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Day 2: Morning"
|
|
msgstr "2일차 오전"
|
|
|
|
#: src/SUMMARY.md src/pattern-matching.md
|
|
msgid "Pattern Matching"
|
|
msgstr "패턴 매칭"
|
|
|
|
#: src/SUMMARY.md src/pattern-matching/match.md
|
|
msgid "Matching Values"
|
|
msgstr ""
|
|
|
|
#: src/SUMMARY.md src/pattern-matching/destructuring.md
|
|
#, fuzzy
|
|
msgid "Destructuring"
|
|
msgstr "열거형 분해(역구조화)"
|
|
|
|
#: src/SUMMARY.md src/pattern-matching/let-control-flow.md
|
|
#, fuzzy
|
|
msgid "Let Control Flow"
|
|
msgstr "흐름 제어"
|
|
|
|
#: src/SUMMARY.md src/pattern-matching/exercise.md
|
|
msgid "Exercise: Expression Evaluation"
|
|
msgstr "연습문제: 표현식 평가"
|
|
|
|
#: src/SUMMARY.md src/methods-and-traits.md
|
|
msgid "Methods and Traits"
|
|
msgstr "메소드와 트레이트"
|
|
|
|
#: src/SUMMARY.md src/methods-and-traits/methods.md
|
|
msgid "Methods"
|
|
msgstr "메서드"
|
|
|
|
#: src/SUMMARY.md src/methods-and-traits/traits.md
|
|
msgid "Traits"
|
|
msgstr "트레잇(Trait)"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Implmementing Traits"
|
|
msgstr "안전하지 않은 트레잇 구현하기"
|
|
|
|
#: src/SUMMARY.md src/methods-and-traits/traits/supertraits.md
|
|
#, fuzzy
|
|
msgid "Supertraits"
|
|
msgstr "트레잇(Trait)"
|
|
|
|
#: src/SUMMARY.md src/methods-and-traits/traits/associated-types.md
|
|
#, fuzzy
|
|
msgid "Associated Types"
|
|
msgstr "공유 타입"
|
|
|
|
#: src/SUMMARY.md src/methods-and-traits/deriving.md
|
|
#, fuzzy
|
|
msgid "Deriving"
|
|
msgstr "트레잇 상속하기"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Exercise: Generic Logger"
|
|
msgstr "연습문제: 일반 `min`"
|
|
|
|
#: src/SUMMARY.md src/generics.md
|
|
msgid "Generics"
|
|
msgstr "제네릭"
|
|
|
|
#: src/SUMMARY.md src/generics/generic-functions.md
|
|
#, fuzzy
|
|
msgid "Generic Functions"
|
|
msgstr "외부(다른언어) 함수들"
|
|
|
|
#: src/SUMMARY.md src/generics/generic-data.md
|
|
msgid "Generic Data Types"
|
|
msgstr "제네릭 데이터 타입"
|
|
|
|
#: src/SUMMARY.md src/generics/generic-traits.md
|
|
#, fuzzy
|
|
msgid "Generic Traits"
|
|
msgstr "제네릭"
|
|
|
|
#: src/SUMMARY.md src/generics/trait-bounds.md
|
|
msgid "Trait Bounds"
|
|
msgstr "제네릭 타입 제한(트레잇 경계)"
|
|
|
|
#: src/SUMMARY.md src/generics/impl-trait.md
|
|
msgid "`impl Trait`"
|
|
msgstr "트레잇 구현하기(`impl Trait`)"
|
|
|
|
#: src/SUMMARY.md src/generics/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Generic `min`"
|
|
msgstr "연습문제: 일반 `min`"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Day 2: Afternoon"
|
|
msgstr "2일차 오후"
|
|
|
|
#: src/SUMMARY.md src/std-types.md
|
|
#, fuzzy
|
|
msgid "Standard Library Types"
|
|
msgstr "표준 라이브러리"
|
|
|
|
#: src/SUMMARY.md src/std-types/std.md
|
|
msgid "Standard Library"
|
|
msgstr "표준 라이브러리"
|
|
|
|
#: src/SUMMARY.md src/std-types/docs.md
|
|
#, fuzzy
|
|
msgid "Documentation"
|
|
msgstr "문서화주석 테스트"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "`Option`"
|
|
msgstr "`Duration`"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "`Result`"
|
|
msgstr "`Option`, `Result`"
|
|
|
|
#: src/SUMMARY.md src/android/aidl/types/primitives.md
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`String`"
|
|
msgstr "String"
|
|
|
|
#: src/SUMMARY.md src/std-types/vec.md
|
|
msgid "`Vec`"
|
|
msgstr "`Vec`"
|
|
|
|
#: src/SUMMARY.md src/std-types/hashmap.md src/bare-metal/no_std.md
|
|
msgid "`HashMap`"
|
|
msgstr "`HashMap`"
|
|
|
|
#: src/SUMMARY.md src/std-types/exercise.md
|
|
msgid "Exercise: Counter"
|
|
msgstr "연습문제: 카운터"
|
|
|
|
#: src/SUMMARY.md src/std-traits.md
|
|
#, fuzzy
|
|
msgid "Standard Library Traits"
|
|
msgstr "표준 라이브러리"
|
|
|
|
#: src/SUMMARY.md src/std-traits/comparisons.md src/async.md
|
|
#, fuzzy
|
|
msgid "Comparisons"
|
|
msgstr "비교"
|
|
|
|
#: src/SUMMARY.md src/std-traits/operators.md
|
|
#, fuzzy
|
|
msgid "Operators"
|
|
msgstr "Iterators"
|
|
|
|
#: src/SUMMARY.md src/std-traits/from-and-into.md
|
|
msgid "`From` and `Into`"
|
|
msgstr "`From`과 `Into`"
|
|
|
|
#: src/SUMMARY.md src/std-traits/casting.md
|
|
#, fuzzy
|
|
msgid "Casting"
|
|
msgstr "테스트"
|
|
|
|
#: src/SUMMARY.md src/std-traits/read-and-write.md
|
|
msgid "`Read` and `Write`"
|
|
msgstr "`Read`와 `Write`"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "`Default`, struct update syntax"
|
|
msgstr "`Default`, 구조체 업데이트 문법"
|
|
|
|
#: src/SUMMARY.md src/std-traits/closures.md
|
|
msgid "Closures"
|
|
msgstr "클로저(Closure)"
|
|
|
|
#: src/SUMMARY.md src/std-traits/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: ROT13"
|
|
msgstr "연습문제: 바이너리 트리"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Day 3: Morning"
|
|
msgstr "3일차 오전"
|
|
|
|
#: src/SUMMARY.md src/memory-management.md
|
|
msgid "Memory Management"
|
|
msgstr "메모리 관리"
|
|
|
|
#: src/SUMMARY.md src/memory-management/review.md
|
|
msgid "Review of Program Memory"
|
|
msgstr "프로그램 메모리 검토"
|
|
|
|
#: src/SUMMARY.md src/memory-management/approaches.md
|
|
#, fuzzy
|
|
msgid "Approaches to Memory Management"
|
|
msgstr "자동 메모리 관리"
|
|
|
|
#: src/SUMMARY.md src/memory-management/ownership.md
|
|
msgid "Ownership"
|
|
msgstr "소유권"
|
|
|
|
#: src/SUMMARY.md src/memory-management/move.md
|
|
msgid "Move Semantics"
|
|
msgstr "Move 문법"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "`Clone`"
|
|
msgstr "`Clone`"
|
|
|
|
#: src/SUMMARY.md src/memory-management/copy-types.md
|
|
#, fuzzy
|
|
msgid "Copy Types"
|
|
msgstr "복합 타입"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "`Drop`"
|
|
msgstr "Drop"
|
|
|
|
#: src/SUMMARY.md src/memory-management/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Builder Type"
|
|
msgstr "연습문제: 빌드 타입"
|
|
|
|
#: src/SUMMARY.md src/smart-pointers.md
|
|
msgid "Smart Pointers"
|
|
msgstr "스마트 포인터"
|
|
|
|
#: src/SUMMARY.md src/smart-pointers/box.md
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`Box<T>`"
|
|
msgstr "`Box`"
|
|
|
|
#: src/SUMMARY.md src/smart-pointers/rc.md
|
|
msgid "`Rc`"
|
|
msgstr "`Rc`"
|
|
|
|
#: src/SUMMARY.md src/smart-pointers/trait-objects.md
|
|
msgid "Trait Objects"
|
|
msgstr "트레잇 객체"
|
|
|
|
#: src/SUMMARY.md src/smart-pointers/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Binary Tree"
|
|
msgstr "연습문제: 바이너리 트리"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Day 3: Afternoon"
|
|
msgstr "3일차 오후"
|
|
|
|
#: src/SUMMARY.md src/borrowing.md
|
|
msgid "Borrowing"
|
|
msgstr "빌림"
|
|
|
|
#: src/SUMMARY.md src/borrowing/shared.md
|
|
#, fuzzy
|
|
msgid "Borrowing a Value"
|
|
msgstr "빌림"
|
|
|
|
#: src/SUMMARY.md src/borrowing/borrowck.md
|
|
#, fuzzy
|
|
msgid "Borrow Checking"
|
|
msgstr "빌림"
|
|
|
|
#: src/SUMMARY.md src/borrowing/interior-mutability.md
|
|
#, fuzzy
|
|
msgid "Interior Mutability"
|
|
msgstr "상호운용성"
|
|
|
|
#: src/SUMMARY.md src/borrowing/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Health Statistics"
|
|
msgstr "연습문제: 엘리베이터 이벤트"
|
|
|
|
#: src/SUMMARY.md src/slices-and-lifetimes.md
|
|
#, fuzzy
|
|
msgid "Slices and Lifetimes"
|
|
msgstr "수명"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Slices: `&[T]`"
|
|
msgstr "슬라이스"
|
|
|
|
#: src/SUMMARY.md src/slices-and-lifetimes/str.md
|
|
#, fuzzy
|
|
msgid "String References"
|
|
msgstr "허상(dangling) 참조"
|
|
|
|
#: src/SUMMARY.md src/slices-and-lifetimes/lifetime-annotations.md
|
|
#, fuzzy
|
|
msgid "Lifetime Annotations"
|
|
msgstr "함수 호출에서의 수명"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Lifetime Elision"
|
|
msgstr "수명"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Struct Lifetimes"
|
|
msgstr "수명"
|
|
|
|
#: src/SUMMARY.md src/slices-and-lifetimes/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Protobuf Parsing"
|
|
msgstr "연습문제: Protobuf 파싱"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Day 4: Morning"
|
|
msgstr "1일차 오전"
|
|
|
|
#: src/SUMMARY.md src/iterators.md
|
|
msgid "Iterators"
|
|
msgstr "Iterators"
|
|
|
|
#: src/SUMMARY.md src/iterators/iterator.md src/bare-metal/no_std.md
|
|
msgid "`Iterator`"
|
|
msgstr "`Iterator`"
|
|
|
|
#: src/SUMMARY.md src/iterators/intoiterator.md
|
|
msgid "`IntoIterator`"
|
|
msgstr "`IntoIterator`"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "`FromIterator`"
|
|
msgstr "FromIterator"
|
|
|
|
#: src/SUMMARY.md src/iterators/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Iterator Method Chaining"
|
|
msgstr "연습문제: 반복자 메서드 체이닝"
|
|
|
|
#: src/SUMMARY.md src/modules.md src/modules/modules.md
|
|
msgid "Modules"
|
|
msgstr "모듈"
|
|
|
|
#: src/SUMMARY.md src/modules/filesystem.md
|
|
msgid "Filesystem Hierarchy"
|
|
msgstr "파일시스템 계층"
|
|
|
|
#: src/SUMMARY.md src/modules/visibility.md
|
|
msgid "Visibility"
|
|
msgstr "가시성"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "`use`, `super`, `self`"
|
|
msgstr "`use`, `super`, `self`"
|
|
|
|
#: src/SUMMARY.md src/modules/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Modules for a GUI Library"
|
|
msgstr "연습문제: GUI 라이브러리 모듈"
|
|
|
|
#: src/SUMMARY.md src/testing.md src/chromium/testing.md
|
|
msgid "Testing"
|
|
msgstr "테스트"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Test Modules"
|
|
msgstr "테스트 모듈"
|
|
|
|
#: src/SUMMARY.md src/testing/other.md
|
|
#, fuzzy
|
|
msgid "Other Types of Tests"
|
|
msgstr "다른 프로젝트"
|
|
|
|
#: src/SUMMARY.md src/testing/lints.md
|
|
#, fuzzy
|
|
msgid "Compiler Lints and Clippy"
|
|
msgstr "컴파일러 린트 및 Clippy"
|
|
|
|
#: src/SUMMARY.md src/testing/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Luhn Algorithm"
|
|
msgstr "룬 알고리즘"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Day 4: Afternoon"
|
|
msgstr "1일차 오후"
|
|
|
|
#: src/SUMMARY.md src/error-handling.md
|
|
msgid "Error Handling"
|
|
msgstr "오류처리"
|
|
|
|
#: src/SUMMARY.md src/error-handling/panics.md
|
|
msgid "Panics"
|
|
msgstr "패닉"
|
|
|
|
#: src/SUMMARY.md src/error-handling/try.md
|
|
#, fuzzy
|
|
msgid "Try Operator"
|
|
msgstr "Iterator"
|
|
|
|
#: src/SUMMARY.md src/error-handling/try-conversions.md
|
|
#, fuzzy
|
|
msgid "Try Conversions"
|
|
msgstr "묵시적 형변환"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "`Error` Trait"
|
|
msgstr "`Error`"
|
|
|
|
#: src/SUMMARY.md src/error-handling/thiserror-and-anyhow.md
|
|
#, fuzzy
|
|
msgid "`thiserror` and `anyhow`"
|
|
msgstr "`From`과 `Into`"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Exercise: Rewriting with `Result`"
|
|
msgstr "`Result`를 이용한 구조화된 오류처리"
|
|
|
|
#: src/SUMMARY.md src/unsafe-rust.md src/unsafe-rust/unsafe.md
|
|
msgid "Unsafe Rust"
|
|
msgstr "안전하지 않은 러스트"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Unsafe"
|
|
msgstr "안전하지 않은 러스트"
|
|
|
|
#: src/SUMMARY.md src/unsafe-rust/dereferencing.md
|
|
msgid "Dereferencing Raw Pointers"
|
|
msgstr "원시 포인터 역참조(따라가기)"
|
|
|
|
#: src/SUMMARY.md src/unsafe-rust/mutable-static.md
|
|
msgid "Mutable Static Variables"
|
|
msgstr "정적 가변 변수"
|
|
|
|
#: src/SUMMARY.md src/unsafe-rust/unions.md
|
|
msgid "Unions"
|
|
msgstr "Unions"
|
|
|
|
#: src/SUMMARY.md src/unsafe-rust/unsafe-functions.md
|
|
#, fuzzy
|
|
msgid "Unsafe Functions"
|
|
msgstr "안전하지 않은 함수 호출"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Unsafe Traits"
|
|
msgstr "안전하지 않은 트레잇 구현하기"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Exercise: FFI Wrapper"
|
|
msgstr "연습문제: FFI 래퍼(wrapper)"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/android.md
|
|
msgid "Android"
|
|
msgstr "안드로이드"
|
|
|
|
#: src/SUMMARY.md src/android/setup.md src/chromium/setup.md
|
|
msgid "Setup"
|
|
msgstr "설치"
|
|
|
|
#: src/SUMMARY.md src/android/build-rules.md
|
|
msgid "Build Rules"
|
|
msgstr "빌드 규칙"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Binary"
|
|
msgstr "바이너리"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Library"
|
|
msgstr "라이브러리"
|
|
|
|
#: src/SUMMARY.md src/android/aidl.md
|
|
msgid "AIDL"
|
|
msgstr "AIDL"
|
|
|
|
#: src/SUMMARY.md src/android/aidl/birthday-service.md
|
|
#, fuzzy
|
|
msgid "Birthday Service Tutorial"
|
|
msgstr "/** 생일 서비스 인터페이스입니다. */"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Interface"
|
|
msgstr "AIDL 인터페이스"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Service API"
|
|
msgstr ""
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Service"
|
|
msgstr "AIDL 서버"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Server"
|
|
msgstr "AIDL 서버"
|
|
|
|
#: src/SUMMARY.md src/android/aidl/example-service/deploy.md
|
|
msgid "Deploy"
|
|
msgstr "배포"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Client"
|
|
msgstr "클라이언트"
|
|
|
|
#: src/SUMMARY.md src/android/aidl/example-service/changing-definition.md
|
|
msgid "Changing API"
|
|
msgstr "API 수정"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Updating Implementations"
|
|
msgstr "서비스 구현"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "AIDL Types"
|
|
msgstr "타입"
|
|
|
|
#: src/SUMMARY.md src/android/aidl/types/primitives.md
|
|
msgid "Primitive Types"
|
|
msgstr ""
|
|
|
|
#: src/SUMMARY.md src/android/aidl/types/arrays.md
|
|
#, fuzzy
|
|
msgid "Array Types"
|
|
msgstr "배열"
|
|
|
|
#: src/SUMMARY.md src/android/aidl/types/objects.md
|
|
#, fuzzy
|
|
msgid "Sending Objects"
|
|
msgstr "트레잇 객체"
|
|
|
|
#: src/SUMMARY.md src/android/aidl/types/parcelables.md
|
|
#, fuzzy
|
|
msgid "Parcelables"
|
|
msgstr "변수"
|
|
|
|
#: src/SUMMARY.md src/android/aidl/types/file-descriptor.md
|
|
msgid "Sending Files"
|
|
msgstr ""
|
|
|
|
#: src/SUMMARY.md src/android/testing/googletest.md
|
|
msgid "GoogleTest"
|
|
msgstr "GoogleTest"
|
|
|
|
#: src/SUMMARY.md src/android/testing/mocking.md
|
|
msgid "Mocking"
|
|
msgstr "모의 처리"
|
|
|
|
#: src/SUMMARY.md src/android/logging.md src/bare-metal/aps/logging.md
|
|
msgid "Logging"
|
|
msgstr "로깅"
|
|
|
|
#: src/SUMMARY.md src/android/interoperability.md
|
|
msgid "Interoperability"
|
|
msgstr "상호운용성"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "With C"
|
|
msgstr "C와의 상호운용성"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Calling C with Bindgen"
|
|
msgstr "Bindgen을 사용한 C호출"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Calling Rust from C"
|
|
msgstr "C에서 러스트 호출"
|
|
|
|
#: src/SUMMARY.md src/android/interoperability/cpp.md
|
|
msgid "With C++"
|
|
msgstr "C++와의 상호운용성"
|
|
|
|
#: src/SUMMARY.md src/android/interoperability/cpp/bridge.md
|
|
#, fuzzy
|
|
msgid "The Bridge Module"
|
|
msgstr "테스트 모듈"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Rust Bridge"
|
|
msgstr "Rust 브리지"
|
|
|
|
#: src/SUMMARY.md src/android/interoperability/cpp/generated-cpp.md
|
|
#, fuzzy
|
|
msgid "Generated C++"
|
|
msgstr "생성된 C++"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "C++ Bridge"
|
|
msgstr "C++ 브리지"
|
|
|
|
#: src/SUMMARY.md src/android/interoperability/cpp/shared-types.md
|
|
msgid "Shared Types"
|
|
msgstr "공유 타입"
|
|
|
|
#: src/SUMMARY.md src/android/interoperability/cpp/shared-enums.md
|
|
msgid "Shared Enums"
|
|
msgstr "공유 Enum"
|
|
|
|
#: src/SUMMARY.md src/android/interoperability/cpp/rust-result.md
|
|
#, fuzzy
|
|
msgid "Rust Error Handling"
|
|
msgstr "오류처리"
|
|
|
|
#: src/SUMMARY.md src/android/interoperability/cpp/cpp-exception.md
|
|
#, fuzzy
|
|
msgid "C++ Error Handling"
|
|
msgstr "오류처리"
|
|
|
|
#: src/SUMMARY.md src/android/interoperability/cpp/type-mapping.md
|
|
msgid "Additional Types"
|
|
msgstr "추가 타입"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Building for Android: C++"
|
|
msgstr "Android용 빌드: C++"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Building for Android: Genrules"
|
|
msgstr "Android용 빌드: Genrules"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Building for Android: Rust"
|
|
msgstr "Android용 빌드: Rust"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "With Java"
|
|
msgstr "Java와의 상호운용성"
|
|
|
|
#: src/SUMMARY.md src/exercises/android/morning.md
|
|
#: src/exercises/bare-metal/morning.md src/exercises/bare-metal/afternoon.md
|
|
#: src/exercises/concurrency/morning.md src/exercises/concurrency/afternoon.md
|
|
msgid "Exercises"
|
|
msgstr "연습문제"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Chromium"
|
|
msgstr "Chromium"
|
|
|
|
#: src/SUMMARY.md src/chromium/cargo.md
|
|
#, fuzzy
|
|
msgid "Comparing Chromium and Cargo Ecosystems"
|
|
msgstr "Chromium 및 Cargo 생태계 비교"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Policy"
|
|
msgstr "정책"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Unsafe Code"
|
|
msgstr "안전하지 않은 러스트"
|
|
|
|
#: src/SUMMARY.md src/chromium/build-rules/depending.md
|
|
#, fuzzy
|
|
msgid "Depending on Rust Code from Chromium C++"
|
|
msgstr "Chromium C++의 Rust 코드에 의존"
|
|
|
|
#: src/SUMMARY.md src/chromium/build-rules/vscode.md
|
|
#, fuzzy
|
|
msgid "Visual Studio Code"
|
|
msgstr "Visual Studio Code"
|
|
|
|
#: src/SUMMARY.md src/exercises/chromium/third-party.md
|
|
#, fuzzy
|
|
msgid "Exercise"
|
|
msgstr "연습문제"
|
|
|
|
#: src/SUMMARY.md src/chromium/testing/rust-gtest-interop.md
|
|
msgid "`rust_gtest_interop` Library"
|
|
msgstr ""
|
|
|
|
#: src/SUMMARY.md src/chromium/testing/build-gn.md
|
|
msgid "GN Rules for Rust Tests"
|
|
msgstr ""
|
|
|
|
#: src/SUMMARY.md src/chromium/testing/chromium-import-macro.md
|
|
msgid "`chromium::import!` Macro"
|
|
msgstr ""
|
|
|
|
#: src/SUMMARY.md src/chromium/interoperability-with-cpp.md
|
|
#, fuzzy
|
|
msgid "Interoperability with C++"
|
|
msgstr "C와의 상호운용성"
|
|
|
|
#: src/SUMMARY.md src/chromium/interoperability-with-cpp/example-bindings.md
|
|
#, fuzzy
|
|
msgid "Example Bindings"
|
|
msgstr "예제"
|
|
|
|
#: src/SUMMARY.md src/chromium/interoperability-with-cpp/limitations-of-cxx.md
|
|
msgid "Limitations of CXX"
|
|
msgstr "CXX 제한사항"
|
|
|
|
#: src/SUMMARY.md src/chromium/interoperability-with-cpp/error-handling.md
|
|
#, fuzzy
|
|
msgid "CXX Error Handling"
|
|
msgstr "오류처리"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Error Handling: QR Example"
|
|
msgstr "오류처리"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Error Handling: PNG Example"
|
|
msgstr "오류처리"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Using CXX in Chromium"
|
|
msgstr "Chromium에서 CXX 사용"
|
|
|
|
#: src/SUMMARY.md src/chromium/adding-third-party-crates.md
|
|
#, fuzzy
|
|
msgid "Adding Third Party Crates"
|
|
msgstr "서드 파티 크레이트 추가"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Configuring Cargo.toml"
|
|
msgstr "Cargo.toml 구성"
|
|
|
|
#: src/SUMMARY.md
|
|
#: src/chromium/adding-third-party-crates/configuring-gnrt-config-toml.md
|
|
#, fuzzy
|
|
msgid "Configuring `gnrt_config.toml`"
|
|
msgstr "gnrt_config.toml 구성"
|
|
|
|
#: src/SUMMARY.md src/chromium/adding-third-party-crates/downloading-crates.md
|
|
#, fuzzy
|
|
msgid "Downloading Crates"
|
|
msgstr "크레이트 다운로드"
|
|
|
|
#: src/SUMMARY.md
|
|
#: src/chromium/adding-third-party-crates/generating-gn-build-rules.md
|
|
#, fuzzy
|
|
msgid "Generating `gn` Build Rules"
|
|
msgstr "gn 빌드 규칙 생성"
|
|
|
|
#: src/SUMMARY.md src/chromium/adding-third-party-crates/resolving-problems.md
|
|
#, fuzzy
|
|
msgid "Resolving Problems"
|
|
msgstr "문제 해결"
|
|
|
|
#: src/SUMMARY.md
|
|
#: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-generate-code.md
|
|
#, fuzzy
|
|
msgid "Build Scripts Which Generate Code"
|
|
msgstr "코드를 생성하는 스크립트 빌드"
|
|
|
|
#: src/SUMMARY.md
|
|
#: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-take-arbitrary-actions.md
|
|
#, fuzzy
|
|
msgid "Build Scripts Which Build C++ or Take Arbitrary Actions"
|
|
msgstr "C++를 빌드하거나 임의의 작업을 실행하는 스크립트 빌드"
|
|
|
|
#: src/SUMMARY.md
|
|
#: src/chromium/adding-third-party-crates/depending-on-a-crate.md
|
|
#, fuzzy
|
|
msgid "Depending on a Crate"
|
|
msgstr "크레이트에 따라 다름"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Reviews and Audits"
|
|
msgstr "검토 및 분석"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Checking into Chromium Source Code"
|
|
msgstr "Chromium 소스 코드에 체크인"
|
|
|
|
#: src/SUMMARY.md src/chromium/adding-third-party-crates/keeping-up-to-date.md
|
|
#, fuzzy
|
|
msgid "Keeping Crates Up to Date"
|
|
msgstr "크레이트를 최신 상태로 유지"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "Bringing It Together - Exercise"
|
|
msgstr "총정리 - 연습문제"
|
|
|
|
#: src/SUMMARY.md src/exercises/chromium/solutions.md
|
|
msgid "Exercise Solutions"
|
|
msgstr "연습문제 해답"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Bare Metal: Morning"
|
|
msgstr "Bare Metal 오전"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/no_std.md
|
|
msgid "`no_std`"
|
|
msgstr "`no_std`"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "A Minimal Example"
|
|
msgstr "작은 예제"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/no_std.md src/bare-metal/alloc.md
|
|
msgid "`alloc`"
|
|
msgstr "`alloc`"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/microcontrollers.md
|
|
msgid "Microcontrollers"
|
|
msgstr "마이크로컨트롤러"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/microcontrollers/mmio.md
|
|
msgid "Raw MMIO"
|
|
msgstr "원시 MMIO"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "PACs"
|
|
msgstr "PAC"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "HAL Crates"
|
|
msgstr "HAL 크레이트"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Board Support Crates"
|
|
msgstr "보드 지원 크레이트"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "The Type State Pattern"
|
|
msgstr "Type State 패턴"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/microcontrollers/embedded-hal.md
|
|
msgid "`embedded-hal`"
|
|
msgstr "`embedded-hal`"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/microcontrollers/probe-rs.md
|
|
#, fuzzy
|
|
msgid "`probe-rs` and `cargo-embed`"
|
|
msgstr "`probe-rs`, `cargo-embed`"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/microcontrollers/debugging.md
|
|
msgid "Debugging"
|
|
msgstr "디버깅"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Other Projects"
|
|
msgstr "다른 프로젝트"
|
|
|
|
#: src/SUMMARY.md src/exercises/bare-metal/compass.md
|
|
#: src/exercises/bare-metal/solutions-morning.md
|
|
msgid "Compass"
|
|
msgstr "나침반"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Solutions"
|
|
msgstr "해답"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Bare Metal: Afternoon"
|
|
msgstr "Bare Metal 오후"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Application Processors"
|
|
msgstr "애플리케이션 프로세서"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/aps/entry-point.md
|
|
msgid "Getting Ready to Rust"
|
|
msgstr "Rust 수행 준비"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Inline Assembly"
|
|
msgstr "인라인 어셈블리"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "MMIO"
|
|
msgstr "MMIO"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Let's Write a UART Driver"
|
|
msgstr "UART 드라이버 작성"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "More Traits"
|
|
msgstr "더 많은 트레잇"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "A Better UART Driver"
|
|
msgstr "더 나은 UART 드라이버"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid "Bitflags"
|
|
msgstr "비트플래그"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Multiple Registers"
|
|
msgstr "더 많은 레지스터"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/aps/better-uart/driver.md
|
|
msgid "Driver"
|
|
msgstr "드라이버"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Using It"
|
|
msgstr "사용해 보기"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/aps/exceptions.md
|
|
msgid "Exceptions"
|
|
msgstr "예외"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Useful Crates"
|
|
msgstr "유용한 크레이트"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/useful-crates/zerocopy.md
|
|
msgid "`zerocopy`"
|
|
msgstr "`zerocopy`"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/useful-crates/aarch64-paging.md
|
|
msgid "`aarch64-paging`"
|
|
msgstr "`aarch64-paging`"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/useful-crates/buddy_system_allocator.md
|
|
msgid "`buddy_system_allocator`"
|
|
msgstr "`buddy_system_allocator`"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/useful-crates/tinyvec.md
|
|
msgid "`tinyvec`"
|
|
msgstr "`tinyvec`"
|
|
|
|
#: src/SUMMARY.md src/bare-metal/useful-crates/spin.md
|
|
#, fuzzy
|
|
msgid "`spin`"
|
|
msgstr "회전"
|
|
|
|
#: src/SUMMARY.md
|
|
#, fuzzy
|
|
msgid "`vmbase`"
|
|
msgstr "vmbase"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "RTC Driver"
|
|
msgstr "RTC 드라이버"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Concurrency: Morning"
|
|
msgstr "동시성 오전"
|
|
|
|
#: src/SUMMARY.md src/concurrency/threads.md
|
|
msgid "Threads"
|
|
msgstr "스레드"
|
|
|
|
#: src/SUMMARY.md src/concurrency/scoped-threads.md
|
|
msgid "Scoped Threads"
|
|
msgstr "범위 스레드(Scoped Threads)"
|
|
|
|
#: src/SUMMARY.md src/concurrency/channels.md
|
|
msgid "Channels"
|
|
msgstr "채널"
|
|
|
|
#: src/SUMMARY.md src/concurrency/channels/unbounded.md
|
|
msgid "Unbounded Channels"
|
|
msgstr "무경계 채널"
|
|
|
|
#: src/SUMMARY.md src/concurrency/channels/bounded.md
|
|
msgid "Bounded Channels"
|
|
msgstr "경계 채널"
|
|
|
|
#: src/SUMMARY.md src/concurrency/send-sync.md
|
|
msgid "`Send` and `Sync`"
|
|
msgstr "`Send`와 `Sync`"
|
|
|
|
#: src/SUMMARY.md src/concurrency/send-sync/send.md
|
|
msgid "`Send`"
|
|
msgstr "`Send`"
|
|
|
|
#: src/SUMMARY.md src/concurrency/send-sync/sync.md
|
|
msgid "`Sync`"
|
|
msgstr "`Sync`"
|
|
|
|
#: src/SUMMARY.md src/concurrency/send-sync/examples.md
|
|
msgid "Examples"
|
|
msgstr "예제"
|
|
|
|
#: src/SUMMARY.md src/concurrency/shared_state.md
|
|
msgid "Shared State"
|
|
msgstr "상태 공유"
|
|
|
|
#: src/SUMMARY.md src/concurrency/shared_state/arc.md
|
|
msgid "`Arc`"
|
|
msgstr "`Arc`"
|
|
|
|
#: src/SUMMARY.md src/concurrency/shared_state/mutex.md
|
|
msgid "`Mutex`"
|
|
msgstr "`Mutex`"
|
|
|
|
#: src/SUMMARY.md src/memory-management/review.md
|
|
#: src/error-handling/try-conversions.md
|
|
#: src/concurrency/shared_state/example.md
|
|
msgid "Example"
|
|
msgstr "예제"
|
|
|
|
#: src/SUMMARY.md src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "Dining Philosophers"
|
|
msgstr "식사하는 철학자들"
|
|
|
|
#: src/SUMMARY.md src/exercises/concurrency/link-checker.md
|
|
msgid "Multi-threaded Link Checker"
|
|
msgstr "멀티스레드 링크 검사기"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Concurrency: Afternoon"
|
|
msgstr "동시성 오후"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Async Basics"
|
|
msgstr "비동기 관련 기본사항"
|
|
|
|
#: src/SUMMARY.md src/async/async-await.md
|
|
msgid "`async`/`await`"
|
|
msgstr "`async`/`await`"
|
|
|
|
#: src/SUMMARY.md src/async/futures.md
|
|
msgid "Futures"
|
|
msgstr "Future"
|
|
|
|
#: src/SUMMARY.md src/async/runtimes.md
|
|
msgid "Runtimes"
|
|
msgstr "비동기 런타임들"
|
|
|
|
#: src/SUMMARY.md src/async/runtimes/tokio.md
|
|
msgid "Tokio"
|
|
msgstr "Tokio"
|
|
|
|
#: src/SUMMARY.md src/exercises/concurrency/link-checker.md src/async/tasks.md
|
|
#: src/exercises/concurrency/chat-app.md
|
|
msgid "Tasks"
|
|
msgstr "태스크"
|
|
|
|
#: src/SUMMARY.md src/async/channels.md
|
|
msgid "Async Channels"
|
|
msgstr "비동기 채널"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Control Flow"
|
|
msgstr "흐름 제어"
|
|
|
|
#: src/SUMMARY.md src/async/control-flow/join.md
|
|
msgid "Join"
|
|
msgstr "Join"
|
|
|
|
#: src/SUMMARY.md src/async/control-flow/select.md
|
|
msgid "Select"
|
|
msgstr "Select"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Pitfalls"
|
|
msgstr "함정"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Blocking the Executor"
|
|
msgstr "Executor 블로킹 하기"
|
|
|
|
#: src/SUMMARY.md src/async/pitfalls/pin.md
|
|
msgid "`Pin`"
|
|
msgstr "`Pin`"
|
|
|
|
#: src/SUMMARY.md src/async/pitfalls/async-traits.md
|
|
msgid "Async Traits"
|
|
msgstr "비동기 트레잇"
|
|
|
|
#: src/SUMMARY.md src/async/pitfalls/cancellation.md
|
|
msgid "Cancellation"
|
|
msgstr "취소"
|
|
|
|
#: src/SUMMARY.md src/exercises/concurrency/chat-app.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "Broadcast Chat Application"
|
|
msgstr "채팅 애플리케이션"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Final Words"
|
|
msgstr "끝으로..."
|
|
|
|
#: src/SUMMARY.md src/thanks.md
|
|
msgid "Thanks!"
|
|
msgstr "감사인사"
|
|
|
|
#: src/SUMMARY.md src/glossary.md
|
|
msgid "Glossary"
|
|
msgstr "용어집"
|
|
|
|
#: src/SUMMARY.md
|
|
msgid "Other Resources"
|
|
msgstr "러스트 참고 자료"
|
|
|
|
#: src/SUMMARY.md src/credits.md
|
|
msgid "Credits"
|
|
msgstr "도와주신 분들"
|
|
|
|
#: src/index.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[![Build workflow](https://img.shields.io/github/actions/workflow/status/"
|
|
"google/comprehensive-rust/build.yml?style=flat-square)](https://github.com/"
|
|
"google/comprehensive-rust/actions/workflows/build.yml?query=branch%3Amain) [!"
|
|
"[GitHub contributors](https://img.shields.io/github/contributors/google/"
|
|
"comprehensive-rust?style=flat-square)](https://github.com/google/"
|
|
"comprehensive-rust/graphs/contributors) [![GitHub stars](https://img.shields."
|
|
"io/github/stars/google/comprehensive-rust?style=flat-square)](https://github."
|
|
"com/google/comprehensive-rust/stargazers)"
|
|
msgstr ""
|
|
"[![Build workflow](https://img.shields.io/github/actions/workflow/status/"
|
|
"google/comprehensive-rust/build.yml?style=flat-square)](https://github.com/"
|
|
"google/comprehensive-rust/actions/workflows/build.yml?query=branch%3Amain) [!"
|
|
"[GitHub contributors](https://img.shields.io/github/contributors/google/"
|
|
"comprehensive-rust?style=flat-square)](https://github.com/google/"
|
|
"comprehensive-rust/graphs/contributors)"
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"This is a free Rust course developed by the Android team at Google. The "
|
|
"course covers the full spectrum of Rust, from basic syntax to advanced "
|
|
"topics like generics and error handling."
|
|
msgstr ""
|
|
"이 강의는 무료이며, Google의 Android 팀이 만들었습니다. 기본 문법부터 제네"
|
|
"릭, 에러 핸들링과 같은 고급주제까지 러스트의 모든 것을 포함합니다."
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"The latest version of the course can be found at <https://google.github.io/"
|
|
"comprehensive-rust/>. If you are reading somewhere else, please check there "
|
|
"for updates."
|
|
msgstr ""
|
|
"이 과정의 최신 버전은 <https://google.github.io/comprehensive-rust/>에서 확인"
|
|
"할 수 있습니다. 다른 곳에서 읽고 있는 경우 이곳에서 업데이트를 확인하시기 바"
|
|
"랍니다."
|
|
|
|
#: src/index.md
|
|
msgid "The course is also available [as a PDF](comprehensive-rust.pdf)."
|
|
msgstr ""
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"The goal of the course is to teach you Rust. We assume you don't know "
|
|
"anything about Rust and hope to:"
|
|
msgstr ""
|
|
"강의는 당신이 러스트에 대해서 아무것도 모른다고 가정하고 아래의 목표를 가지"
|
|
"고 있습니다:"
|
|
|
|
#: src/index.md
|
|
msgid "Give you a comprehensive understanding of the Rust syntax and language."
|
|
msgstr "러스트 구문과 언어에 대한 포괄적인 이해를 제공합니다."
|
|
|
|
#: src/index.md
|
|
msgid "Enable you to modify existing programs and write new programs in Rust."
|
|
msgstr "기존 프로그램을 수정하고 러스트에서 새 프로그램을 작성할 수 있습니다."
|
|
|
|
#: src/index.md
|
|
msgid "Show you common Rust idioms."
|
|
msgstr "일반적인 러스트 관용구를 보여줍니다."
|
|
|
|
#: src/index.md
|
|
#, fuzzy
|
|
msgid "We call the first four course days Rust Fundamentals."
|
|
msgstr "강의의 첫 3일 동안에는 Rust의 기초를 다집니다."
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"Building on this, you're invited to dive into one or more specialized topics:"
|
|
msgstr "그 후에는, 아래와 같은 개별 주제를 심화해서 공부할 수 있습니다:"
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"[Android](android.md): a half-day course on using Rust for Android platform "
|
|
"development (AOSP). This includes interoperability with C, C++, and Java."
|
|
msgstr ""
|
|
"[Android](android.md): Android 플랫폼 개발(AOSP) 시 Rust 사용에 관한 반나절 "
|
|
"과정입니다. 여기에는 C, C++, Java와의 상호 운용성이 포함됩니다."
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"[Chromium](chromium.md): a half-day course on using Rust within Chromium "
|
|
"based browsers. This includes interoperability with C++ and how to include "
|
|
"third-party crates in Chromium."
|
|
msgstr ""
|
|
"[Chromium의 Rust](../chromium.md) 심층 분석은 Chromium 브라우저의 일부로 Rust"
|
|
"를 사용하는 방법에 관한 반나절 과정입니다. 여기에는 Chromium의 'gn' 빌드 시스"
|
|
"템에서 Rust를 사용하여 서드 파티 라이브러리(\"crates\")와 C++ 상호 운용성을 "
|
|
"가져오는 방법이 포함되어 있습니다."
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"[Bare-metal](bare-metal.md): a whole-day class on using Rust for bare-metal "
|
|
"(embedded) development. Both microcontrollers and application processors are "
|
|
"covered."
|
|
msgstr ""
|
|
"[Bare-metal](bare-metal.md): bare-metal(임베디드) 개발 시 Rust 사용에 관한 종"
|
|
"일 과정입니다. 마이크로컨트롤러와 애플리케이션 프로세서를 모두 다룹니다."
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"[Concurrency](concurrency.md): a whole-day class on concurrency in Rust. We "
|
|
"cover both classical concurrency (preemptively scheduling using threads and "
|
|
"mutexes) and async/await concurrency (cooperative multitasking using "
|
|
"futures)."
|
|
msgstr ""
|
|
"[동시성](concurrency.md): Rust의 동시성에 관한 종일 과정입니다. 여기서는 고전"
|
|
"적인 동시성(스레드와 뮤텍스를 사용하여 선점형 스케줄링을 하는 것)과 async/"
|
|
"await 동시성(future를 사용하는 협력적인 멀티태스킹)을 모두 다룹니다."
|
|
|
|
#: src/index.md
|
|
msgid "Non-Goals"
|
|
msgstr "제외사항"
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"Rust is a large language and we won't be able to cover all of it in a few "
|
|
"days. Some non-goals of this course are:"
|
|
msgstr ""
|
|
"러스트는 며칠만에 모든 것을 다루기에는 너무 큰 언어입니다. 그래서 아래와 같은"
|
|
"것을 목표로 하지 않습니다:"
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"Learning how to develop macros: please see [Chapter 19.5 in the Rust Book]"
|
|
"(https://doc.rust-lang.org/book/ch19-06-macros.html) and [Rust by Example]"
|
|
"(https://doc.rust-lang.org/rust-by-example/macros.html) instead."
|
|
msgstr ""
|
|
"매크로 만들기: 매크로와 관련한 자세한 내용은 [러스트 프로그래밍 언어, 19.1절]"
|
|
"(https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html)과 [Rustonomicon]"
|
|
"(https://doc.rust-lang.org/nomicon/)를 참조하세요."
|
|
|
|
#: src/index.md
|
|
msgid "Assumptions"
|
|
msgstr "독자 수준에 대한 가정"
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"The course assumes that you already know how to program. Rust is a "
|
|
"statically-typed language and we will sometimes make comparisons with C and "
|
|
"C++ to better explain or contrast the Rust approach."
|
|
msgstr ""
|
|
"본 강의는 여러분이 프로그래밍 자체에 대해서는 알고 있다고 가정합니다. 러스트"
|
|
"는 정적타입 언어이며, 강좌에서는 C/C++ 와의 비교, 대조를 통해 러스트를 설명"
|
|
"할 것입니다."
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"If you know how to program in a dynamically-typed language such as Python or "
|
|
"JavaScript, then you will be able to follow along just fine too."
|
|
msgstr ""
|
|
"C/C++을 모르더라도 동적 타입 언어(Python이나 JavaScript 등) 프로그래밍 경험"
|
|
"이 있다면 따라오는데 큰 문제는 없을 것입니다."
|
|
|
|
#: src/index.md
|
|
msgid ""
|
|
"This is an example of a _speaker note_. We will use these to add additional "
|
|
"information to the slides. This could be key points which the instructor "
|
|
"should cover as well as answers to typical questions which come up in class."
|
|
msgstr ""
|
|
"이것은 \"발표자 노트\"의 예제입니다. 이 부분을 이용해서 추가 정보를 제공합니"
|
|
"다. 주로 강의실에서 제기되는 일반적인 질문에 대한 답변과 강사가 다루어야 할 "
|
|
"키 포인트일 수 있습니다."
|
|
|
|
#: src/running-the-course.md src/running-the-course/course-structure.md
|
|
msgid "This page is for the course instructor."
|
|
msgstr "강사를 위한 안내 페이지입니다."
|
|
|
|
#: src/running-the-course.md
|
|
msgid ""
|
|
"Here is a bit of background information about how we've been running the "
|
|
"course internally at Google."
|
|
msgstr ""
|
|
"다음은 구글 내부에서 이 과정을 어떤식으로 운영해왔는지에 대한 배경 정보입니"
|
|
"다."
|
|
|
|
#: src/running-the-course.md
|
|
msgid ""
|
|
"We typically run classes from 9:00 am to 4:00 pm, with a 1 hour lunch break "
|
|
"in the middle. This leaves 3 hours for the morning class and 3 hours for the "
|
|
"afternoon class. Both sessions contain multiple breaks and time for students "
|
|
"to work on exercises."
|
|
msgstr ""
|
|
"수업은 보통 오전 9시부터 오후 4시까지 진행되며, 중간에 1시간의 점심시간을 제"
|
|
"공합니다. 따라서 오전 수업이 3시간, 오후 수업이 3시간입니다. 두 세션에는 여"
|
|
"러 번의 휴식 시간 및 학생들이 연습문제를 풀 수 있는 시간이 포함되어 있습니다."
|
|
|
|
#: src/running-the-course.md
|
|
msgid "Before you run the course, you will want to:"
|
|
msgstr "강의를 실행하기 위한 준비:"
|
|
|
|
#: src/running-the-course.md
|
|
msgid ""
|
|
"Make yourself familiar with the course material. We've included speaker "
|
|
"notes to help highlight the key points (please help us by contributing more "
|
|
"speaker notes!). When presenting, you should make sure to open the speaker "
|
|
"notes in a popup (click the link with a little arrow next to \"Speaker "
|
|
"Notes\"). This way you have a clean screen to present to the class."
|
|
msgstr ""
|
|
"강의 자료를 숙지합니다. 주요 요점을 강조하기 위해 강의 참조 노트를 포함하였습"
|
|
"니다. (추가적인 노트를 작성하여 제공해 주시면 감사하겠습니다.) 강의 참조 노트"
|
|
"의 링크를 누르면 별도의 팝업으로 분리가 되며, 메인 화면에서는 사라집니다. 깔"
|
|
"끔한 화면으로 강의를 진행할 수 있습니다."
|
|
|
|
#: src/running-the-course.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Decide on the dates. Since the course takes four days, we recommend that you "
|
|
"schedule the days over two weeks. Course participants have said that they "
|
|
"find it helpful to have a gap in the course since it helps them process all "
|
|
"the information we give them."
|
|
msgstr ""
|
|
"강의 날짜를 정합니다. 최소 3일에 걸쳐서 진행이 되기 때문에, 두 주에 걸쳐서 스"
|
|
"케줄을 잡는 것을 권합니다. 기존 강의 수강생들의 피드백에 따르면, 연달아서 강"
|
|
"의를 진행하는 것 보다, 강의를 띄엄띄엄 하는 것이 강의 내용을 소화하는데 더 도"
|
|
"움이 되었다고 합니다."
|
|
|
|
#: src/running-the-course.md
|
|
msgid ""
|
|
"Find a room large enough for your in-person participants. We recommend a "
|
|
"class size of 15-25 people. That's small enough that people are comfortable "
|
|
"asking questions --- it's also small enough that one instructor will have "
|
|
"time to answer the questions. Make sure the room has _desks_ for yourself "
|
|
"and for the students: you will all need to be able to sit and work with your "
|
|
"laptops. In particular, you will be doing a lot of live-coding as an "
|
|
"instructor, so a lectern won't be very helpful for you."
|
|
msgstr ""
|
|
"충분한 공간을 확보합니다. 15에서 20명 규모의 공간을 추천합니다. 수강생과 강사"
|
|
"가 질의를 하기에 충분한 시간과 공간이어야 합니다. 강사나 수강생 모두 \\_책상_"
|
|
"을 사용할 수 있는 강의실이면 좋습니다. 강의 중에 강사가 라이브 코딩을 하게 "
|
|
"될 경우가 많으며, 이때 자리에 앉아 노트북을 사용하는 것이 도움이 됩니다."
|
|
|
|
#: src/running-the-course.md
|
|
msgid ""
|
|
"On the day of your course, show up to the room a little early to set things "
|
|
"up. We recommend presenting directly using `mdbook serve` running on your "
|
|
"laptop (see the [installation instructions](https://github.com/google/"
|
|
"comprehensive-rust#building)). This ensures optimal performance with no lag "
|
|
"as you change pages. Using your laptop will also allow you to fix typos as "
|
|
"you or the course participants spot them."
|
|
msgstr ""
|
|
"강의 당일 조금 일찍 와서 준비합니다. 강사 노트북에서 `mdbook serve`를 이용해 "
|
|
"직접 프레젠테이션 하면 페이지 이동 시의 지연이 없습니다.([설치 방법](https://"
|
|
"github.com/google/comprehensive-rust#building)을 참조하세요.) 또한, 그렇게 하"
|
|
"면 강의 도중 오타를 발견했을 때 그 자리에서 바로 수정 가능하다는 장점도 있습"
|
|
"니다."
|
|
|
|
#: src/running-the-course.md
|
|
msgid ""
|
|
"Let people solve the exercises by themselves or in small groups. We "
|
|
"typically spend 30-45 minutes on exercises in the morning and in the "
|
|
"afternoon (including time to review the solutions). Make sure to ask people "
|
|
"if they're stuck or if there is anything you can help with. When you see "
|
|
"that several people have the same problem, call it out to the class and "
|
|
"offer a solution, e.g., by showing people where to find the relevant "
|
|
"information in the standard library."
|
|
msgstr ""
|
|
"수강생들이 직접 (개별 혹은 그룹으로) 연습문제를 풀도록 합니다. 대체로 오전, "
|
|
"오후에 각각 30-45분 정도를 연습문제에 할당합니다 (이는 해답을 보고 설명하는 "
|
|
"시간까지 포함합니다). 막혀 도움을 필요로 하는 수강생이 없는지 수시로 확인합니"
|
|
"다. 만약 같은 문제를 여러 사람이 겪고 있다면, 그 문제를 강의실 전체 인원에게 "
|
|
"알리고 해결책을 제시합니다. 예를 들어 표준 라이브러리 어디에 가면 그 문제에 "
|
|
"대한 해답을 찾을 수 있는지 알려 줍니다."
|
|
|
|
#: src/running-the-course.md
|
|
msgid ""
|
|
"That is all, good luck running the course! We hope it will be as much fun "
|
|
"for you as it has been for us!"
|
|
msgstr ""
|
|
"이제 준비는 끝났습니다. 우리가 그랬듯이 여러분들도 이 강의를 즐기시길 바랍니"
|
|
"다!"
|
|
|
|
#: src/running-the-course.md
|
|
msgid ""
|
|
"Please [provide feedback](https://github.com/google/comprehensive-rust/"
|
|
"discussions/86) afterwards so that we can keep improving the course. We "
|
|
"would love to hear what worked well for you and what can be made better. "
|
|
"Your students are also very welcome to [send us feedback](https://github.com/"
|
|
"google/comprehensive-rust/discussions/100)!"
|
|
msgstr ""
|
|
"강의를 계속 개선할 수 있도록 [피드백](https://github.com/google/"
|
|
"comprehensive-rust/discussions/86)을 제공해 주십시오. 우리는 무엇이 좋았고, "
|
|
"무엇이 모자랐는지 듣고 싶습니다. 수강생들로 부터의 [피드백](https://github."
|
|
"com/google/comprehensive-rust/discussions/100)도 환영합니다!"
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "Rust Fundamentals"
|
|
msgstr "Rust 기초"
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid ""
|
|
"The first four days make up [Rust Fundamentals](../welcome-day-1.md). The "
|
|
"days are fast paced and we cover a lot of ground!"
|
|
msgstr ""
|
|
"첫 4일은 [Rust 기초](../welcome-day-1.md)로 이루어지며 짧은 시간 안에 많은 내"
|
|
"용을 다루게 됩니다."
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
#, fuzzy
|
|
msgid "Course schedule:"
|
|
msgstr "강의 구성"
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "Day 1 Morning (2 hours and 10 minutes, including breaks)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Welcome](../welcome-day-1.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Hello, World](../hello-world.md) (15 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Types and Values](../types-and-values.md) (45 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Control Flow Basics](../control-flow-basics.md) (40 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "Day 1 Afternoon (2 hours and 15 minutes, including breaks)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Tuples and Arrays](../tuples-and-arrays.md) (35 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[References](../references.md) (35 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[User-Defined Types](../user-defined-types.md) (50 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "Day 2 Morning (2 hours and 55 minutes, including breaks)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Welcome](../welcome-day-2.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
#, fuzzy
|
|
msgid "[Pattern Matching](../pattern-matching.md) (1 hour)"
|
|
msgstr "패턴에 관한 설명은 [패턴 매칭](../pattern-matching.md)을 참조하세요."
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Methods and Traits](../methods-and-traits.md) (50 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Generics](../generics.md) (40 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "Day 2 Afternoon (3 hours and 10 minutes, including breaks)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Standard Library Types](../std-types.md) (1 hour and 20 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Standard Library Traits](../std-traits.md) (1 hour and 40 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "Day 3 Morning (2 hours and 20 minutes, including breaks)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Welcome](../welcome-day-3.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Memory Management](../memory-management.md) (1 hour)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Smart Pointers](../smart-pointers.md) (55 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "Day 3 Afternoon (2 hours and 10 minutes, including breaks)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Borrowing](../borrowing.md) (50 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid ""
|
|
"[Slices and Lifetimes](../slices-and-lifetimes.md) (1 hour and 10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "Day 4 Morning (2 hours and 40 minutes, including breaks)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Welcome](../welcome-day-4.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Iterators](../iterators.md) (45 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Modules](../modules.md) (40 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Testing](../testing.md) (45 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "Day 4 Afternoon (2 hours and 10 minutes, including breaks)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Error Handling](../error-handling.md) (55 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "[Unsafe Rust](../unsafe-rust.md) (1 hour and 5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "Deep Dives"
|
|
msgstr "심화 학습"
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"In addition to the 4-day class on Rust Fundamentals, we cover some more "
|
|
"specialized topics:"
|
|
msgstr "Rust 기초에 관한 3일 과정 이후에는, 다음과 같은 전문 주제를 다룹니다:"
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
#, fuzzy
|
|
msgid "Rust in Android"
|
|
msgstr "1일차 개요"
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The [Rust in Android](../android.md) deep dive is a half-day course on using "
|
|
"Rust for Android platform development. This includes interoperability with "
|
|
"C, C++, and Java."
|
|
msgstr ""
|
|
"[Android 심화 학습](../android.md)는 Android 플랫폼 개발 시 Rust 사용에 관한 "
|
|
"반나절 과정입니다. 여기에는 C, C++, Java와의 상호 운용성이 포함됩니다."
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid ""
|
|
"You will need an [AOSP checkout](https://source.android.com/docs/setup/"
|
|
"download/downloading). Make a checkout of the [course repository](https://"
|
|
"github.com/google/comprehensive-rust) on the same machine and move the `src/"
|
|
"android/` directory into the root of your AOSP checkout. This will ensure "
|
|
"that the Android build system sees the `Android.bp` files in `src/android/`."
|
|
msgstr ""
|
|
"[AOSP 코드](https://source.android.com/docs/setup/download/downloading)를 여"
|
|
"러분의 컴퓨터에 체크아웃해야 합니다. 그런 다음, 그 컴퓨터에서 [과정 저장소]"
|
|
"(https://github.com/google/comprehensive-rust)를 체크아웃하고 `src/android/` "
|
|
"디렉터리를 AOSP 코드의 루트로 이동합니다. 이렇게 하면 안드로이드 빌드 시스템"
|
|
"에서 과제용으로 추가된 `Android.bp`파일을 인식할 수 있습니다."
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid ""
|
|
"Ensure that `adb sync` works with your emulator or real device and pre-build "
|
|
"all Android examples using `src/android/build_all.sh`. Read the script to "
|
|
"see the commands it runs and make sure they work when you run them by hand."
|
|
msgstr ""
|
|
"`adb sync` 명렁어가 에뮬레이터 혹은 실제 장치와 작동하는지 확인합니다. 그리"
|
|
"고 `src/android/build_all.sh`를 수행해서 모든 안드로이드 예제를 미리 빌드해 "
|
|
"보세요. 그 쉘 스크립트를 읽고, 그 안에서 수행되는 명령어들을 확인한 후 각 명"
|
|
"령어들을 수동으로 실행해도 잘 되는지 확인하세요."
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "Rust in Chromium"
|
|
msgstr "Chromium에서 Rust 사용"
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid ""
|
|
"The [Rust in Chromium](../chromium.md) deep dive is a half-day course on "
|
|
"using Rust as part of the Chromium browser. It includes using Rust in "
|
|
"Chromium's `gn` build system, bringing in third-party libraries (\"crates\") "
|
|
"and C++ interoperability."
|
|
msgstr ""
|
|
"[Chromium에서 Rust 사용](../chromium.md) 이 과정은 Chromium 브라우저의 일부"
|
|
"로 Rust를 사용하는 방법에 관한 반나절 과정입니다. 여기에는 Chromium의 gn 빌"
|
|
"드 시스템에서 Rust를 사용하는 방법과 서드 파티 라이브러리 (\"crates\")를 가져"
|
|
"오는 방법, C++ 상호 운용성 등이 포함되어 있습니다."
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid ""
|
|
"You will need to be able to build Chromium --- a debug, component build is "
|
|
"[recommended](../chromium/setup.md) for speed but any build will work. "
|
|
"Ensure that you can run the Chromium browser that you've built."
|
|
msgstr ""
|
|
"Chromium을 빌드할 수 있어야 합니다. 디버그, 구성요소 빌드는 속도를 높이기 위"
|
|
"해 [권장](../chromium/setup.md)되지만 모든 빌드가 작동합니다. 빌드한 "
|
|
"Chromium 브라우저를 실행할 수 있는지 확인합니다."
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
#, fuzzy
|
|
msgid "Bare-Metal Rust"
|
|
msgstr "Bare-Metal"
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The [Bare-Metal Rust](../bare-metal.md) deep dive is a full day class on "
|
|
"using Rust for bare-metal (embedded) development. Both microcontrollers and "
|
|
"application processors are covered."
|
|
msgstr ""
|
|
"[Bare-Metal 심화 학습](../bare-metal.md): bare-metal(임베디드) 개발 시 Rust "
|
|
"사용에 관한 종일 과정입니다. 마이크로컨트롤러와 애플리케이션 프로세서를 모두 "
|
|
"다룹니다."
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid ""
|
|
"For the microcontroller part, you will need to buy the [BBC micro:bit]"
|
|
"(https://microbit.org/) v2 development board ahead of time. Everybody will "
|
|
"need to install a number of packages as described on the [welcome page](../"
|
|
"bare-metal.md)."
|
|
msgstr ""
|
|
"마이크로컨트롤러 파트를 진행하기 위해서는 [BBC micro:bit](https://microbit."
|
|
"org/) v2 개발 보드를 미리 구매해야 합니다. 모든 사용자는 [시작 페이지](../"
|
|
"bare-metal.md)에 설명된 대로 각종 패키지를 설치해야 합니다."
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
#, fuzzy
|
|
msgid "Concurrency in Rust"
|
|
msgstr "Welcome to Comprehensive Rust 🦀"
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The [Concurrency in Rust](../concurrency.md) deep dive is a full day class "
|
|
"on classical as well as `async`/`await` concurrency."
|
|
msgstr ""
|
|
"[동시성 심화학습](../concurrency.md)은 고전적인 동시성 및 `async`/`await` 동"
|
|
"시성을 다루는 종일 과정입니다."
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid ""
|
|
"You will need a fresh crate set up and the dependencies downloaded and ready "
|
|
"to go. You can then copy/paste the examples into `src/main.rs` to experiment "
|
|
"with them:"
|
|
msgstr ""
|
|
"새 크레이트를 설정하고 몇 가지 의존성을 다운로드해 두어야 합니다. 그런 다음 "
|
|
"예제를 `src/main.rs`에 복사/붙여넣기 하여 테스트 해 볼 수 있습니다:"
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid "Format"
|
|
msgstr "강의 형식"
|
|
|
|
#: src/running-the-course/course-structure.md
|
|
msgid ""
|
|
"The course is meant to be very interactive and we recommend letting the "
|
|
"questions drive the exploration of Rust!"
|
|
msgstr ""
|
|
"이 강의는 강사와 수강생이 양방향으로 소통하면서 진행하도록 디자인 되었습니"
|
|
"다. 다양한 질문을 통해 러스트의 여러 부분을 탐험할 수 있도록 하세요!"
|
|
|
|
#: src/running-the-course/keyboard-shortcuts.md
|
|
msgid "There are several useful keyboard shortcuts in mdBook:"
|
|
msgstr "다음은, mdBook 시스템(현 사이트)에서 유용한 단축키들 입니다:"
|
|
|
|
#: src/running-the-course/keyboard-shortcuts.md
|
|
msgid "Arrow-Left"
|
|
msgstr "왼쪽 화살표"
|
|
|
|
#: src/running-the-course/keyboard-shortcuts.md
|
|
msgid ": Navigate to the previous page."
|
|
msgstr ": 이전 페이지로 이동합니다."
|
|
|
|
#: src/running-the-course/keyboard-shortcuts.md
|
|
msgid "Arrow-Right"
|
|
msgstr "오른쪽 화살표"
|
|
|
|
#: src/running-the-course/keyboard-shortcuts.md
|
|
msgid ": Navigate to the next page."
|
|
msgstr ": 다음 페이지로 이동합니다."
|
|
|
|
#: src/running-the-course/keyboard-shortcuts.md src/cargo/code-samples.md
|
|
msgid "Ctrl + Enter"
|
|
msgstr "Ctrl + Enter"
|
|
|
|
#: src/running-the-course/keyboard-shortcuts.md
|
|
msgid ": Execute the code sample that has focus."
|
|
msgstr ": 현재 포커스를 받은 코드 샘플 블록을 실행합니다."
|
|
|
|
#: src/running-the-course/keyboard-shortcuts.md
|
|
msgid "s"
|
|
msgstr "s"
|
|
|
|
#: src/running-the-course/keyboard-shortcuts.md
|
|
msgid ": Activate the search bar."
|
|
msgstr ""
|
|
": 검색창을 활성화합니다.(mdBook 문제로 23.01.19 기준 영어로만 가능합니다.)"
|
|
|
|
#: src/running-the-course/translations.md
|
|
msgid ""
|
|
"The course has been translated into other languages by a set of wonderful "
|
|
"volunteers:"
|
|
msgstr ""
|
|
"이 과정은 다른 언어로도 제공됩니다. 괄호 안은 번역에 도움 주신 분들입니다:"
|
|
|
|
#: src/running-the-course/translations.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[Brazilian Portuguese](https://google.github.io/comprehensive-rust/pt-BR/) "
|
|
"by [@rastringer](https://github.com/rastringer), [@hugojacob](https://github."
|
|
"com/hugojacob), [@joaovicmendes](https://github.com/joaovicmendes), and "
|
|
"[@henrif75](https://github.com/henrif75)."
|
|
msgstr ""
|
|
"[브라질 포르투갈어](https://google.github.io/comprehensive-rust/pt-BR/): "
|
|
"[@rastringer](https://github.com/rastringer), [@hugojacob](https://github."
|
|
"com/hugojacob), [@joaovicmendes](https://github.com/joaovicmendes) 그리고 "
|
|
"[@henrif75](https://github.com/henrif75)가 제공."
|
|
|
|
#: src/running-the-course/translations.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[Chinese (Simplified)](https://google.github.io/comprehensive-rust/zh-CN/) "
|
|
"by [@suetfei](https://github.com/suetfei), [@wnghl](https://github.com/"
|
|
"wnghl), [@anlunx](https://github.com/anlunx), [@kongy](https://github.com/"
|
|
"kongy), [@noahdragon](https://github.com/noahdragon), [@superwhd](https://"
|
|
"github.com/superwhd), [@SketchK](https://github.com/SketchK), and [@nodmp]"
|
|
"(https://github.com/nodmp)."
|
|
msgstr ""
|
|
"[중국어(간체)](https://google.github.io/comprehensive-rust/zh-CN/): "
|
|
"[@suetfei](https://github.com/suetfei), [@wnghl](https://github.com/wnghl), "
|
|
"[@anlunx](https://github.com/anlunx), [@kongy](https://github.com/kongy), "
|
|
"[@noahdragon](https://github.com/noahdragon), [@superwhd](https://github.com/"
|
|
"superwhd), [@SketchK](https://github.com/SketchK), [@nodmp](https://github."
|
|
"com/nodmp) 제공"
|
|
|
|
#: src/running-the-course/translations.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[Chinese (Traditional)](https://google.github.io/comprehensive-rust/zh-TW/) "
|
|
"by [@hueich](https://github.com/hueich), [@victorhsieh](https://github.com/"
|
|
"victorhsieh), [@mingyc](https://github.com/mingyc), [@kuanhungchen](https://"
|
|
"github.com/kuanhungchen), and [@johnathan79717](https://github.com/"
|
|
"johnathan79717)."
|
|
msgstr ""
|
|
"[중국어(간체)](https://google.github.io/comprehensive-rust/zh-CN/): "
|
|
"[@suetfei](https://github.com/suetfei), [@wnghl](https://github.com/wnghl), "
|
|
"[@anlunx](https://github.com/anlunx), [@kongy](https://github.com/kongy), "
|
|
"[@noahdragon](https://github.com/noahdragon), [@superwhd](https://github.com/"
|
|
"superwhd), [@SketchK](https://github.com/SketchK), [@nodmp](https://github."
|
|
"com/nodmp) 제공"
|
|
|
|
#: src/running-the-course/translations.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[Korean](https://google.github.io/comprehensive-rust/ko/) by [@keispace]"
|
|
"(https://github.com/keispace), [@jiyongp](https://github.com/jiyongp), "
|
|
"[@jooyunghan](https://github.com/jooyunghan), and [@namhyung](https://github."
|
|
"com/namhyung)."
|
|
msgstr ""
|
|
"[한국어](https://google.github.io/comprehensive-rust/ko/): [@keispace]"
|
|
"(https://github.com/keispace), [@jiyongp](https://github.com/jiyongp) 그리고 "
|
|
"[@jooyunghan](https://github.com/jooyunghan)가 제공."
|
|
|
|
#: src/running-the-course/translations.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[Spanish](https://google.github.io/comprehensive-rust/es/) by [@deavid]"
|
|
"(https://github.com/deavid)."
|
|
msgstr ""
|
|
"[벵갈어](https://google.github.io/comprehensive-rust/bn/): [@raselmandol]"
|
|
"(https://github.com/raselmandol) 제공."
|
|
|
|
#: src/running-the-course/translations.md
|
|
msgid ""
|
|
"Use the language picker in the top-right corner to switch between languages."
|
|
msgstr "페이지 오른쪽 위의 메뉴를 통해 다른 언어로 전환할 수 있습니다."
|
|
|
|
#: src/running-the-course/translations.md
|
|
msgid "Incomplete Translations"
|
|
msgstr "번역 문제"
|
|
|
|
#: src/running-the-course/translations.md
|
|
msgid ""
|
|
"There is a large number of in-progress translations. We link to the most "
|
|
"recently updated translations:"
|
|
msgstr ""
|
|
"진행 중인 번역이 많습니다. 최근에 업데이트된 번역본으로 연결되는 링크는 다음"
|
|
"과 같습니다:"
|
|
|
|
#: src/running-the-course/translations.md
|
|
msgid ""
|
|
"[Bengali](https://google.github.io/comprehensive-rust/bn/) by [@raselmandol]"
|
|
"(https://github.com/raselmandol)."
|
|
msgstr ""
|
|
"[벵갈어](https://google.github.io/comprehensive-rust/bn/): [@raselmandol]"
|
|
"(https://github.com/raselmandol) 제공."
|
|
|
|
#: src/running-the-course/translations.md
|
|
msgid ""
|
|
"[French](https://google.github.io/comprehensive-rust/fr/) by [@KookaS]"
|
|
"(https://github.com/KookaS) and [@vcaen](https://github.com/vcaen)."
|
|
msgstr ""
|
|
"[프랑스어](https://google.github.io/comprehensive-rust/fr/): [@KookaS]"
|
|
"(https://github.com/KookaS) 및 [@vcaen](https://github.com/vcaen) 제공."
|
|
|
|
#: src/running-the-course/translations.md
|
|
msgid ""
|
|
"[German](https://google.github.io/comprehensive-rust/de/) by [@Throvn]"
|
|
"(https://github.com/Throvn) and [@ronaldfw](https://github.com/ronaldfw)."
|
|
msgstr ""
|
|
"[독일어](https://google.github.io/comprehensive-rust/de/): [@Throvn](https://"
|
|
"github.com/Throvn) 및 [@ronaldfw](https://github.com/ronaldfw) 제공."
|
|
|
|
#: src/running-the-course/translations.md
|
|
msgid ""
|
|
"[Japanese](https://google.github.io/comprehensive-rust/ja/) by [@CoinEZ-JPN]"
|
|
"(https://github.com/CoinEZ) and [@momotaro1105](https://github.com/"
|
|
"momotaro1105)."
|
|
msgstr ""
|
|
"[일본어](https://google.github.io/comprehensive-rust/ja/): [@CoinEZ-JPN]"
|
|
"(https://github.com/CoinEZ) 및 [@momotaro1105](https://github.com/"
|
|
"momotaro1105) 제공."
|
|
|
|
#: src/running-the-course/translations.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[Italian](https://google.github.io/comprehensive-rust/it/) by "
|
|
"[@henrythebuilder](https://github.com/henrythebuilder) and [@detro](https://"
|
|
"github.com/detro)."
|
|
msgstr ""
|
|
"[독일어](https://google.github.io/comprehensive-rust/de/): [@Throvn](https://"
|
|
"github.com/Throvn) 및 [@ronaldfw](https://github.com/ronaldfw) 제공."
|
|
|
|
#: src/running-the-course/translations.md
|
|
msgid ""
|
|
"If you want to help with this effort, please see [our instructions](https://"
|
|
"github.com/google/comprehensive-rust/blob/main/TRANSLATIONS.md) for how to "
|
|
"get going. Translations are coordinated on the [issue tracker](https://"
|
|
"github.com/google/comprehensive-rust/issues/282)."
|
|
msgstr ""
|
|
"이 과정의 번역 작업에 도움을 주고 싶다면 [여기](https://github.com/google/"
|
|
"comprehensive-rust/blob/main/TRANSLATIONS.md) 설명된 내용을 참고하세요. 진행 "
|
|
"중인 번역 작업에 대한 내용은 [이슈 트래커](https://github.com/google/"
|
|
"comprehensive-rust/issues/282)를 참고하세요."
|
|
|
|
#: src/cargo.md
|
|
msgid ""
|
|
"When you start reading about Rust, you will soon meet [Cargo](https://doc."
|
|
"rust-lang.org/cargo/), the standard tool used in the Rust ecosystem to build "
|
|
"and run Rust applications. Here we want to give a brief overview of what "
|
|
"Cargo is and how it fits into the wider ecosystem and how it fits into this "
|
|
"training."
|
|
msgstr ""
|
|
"러스트를 시작하려고하면 당신은 곧 [Cargo](https://doc.rust-lang.org/cargo/)라"
|
|
"는, 러스트 생태계에서 사용하는 표준 빌드/실행 도구를 만날 것 입니다. 여기서"
|
|
"는 카고가 무엇인지, 그리고 카고가 러스트 생태계에서 어떤 역할을 하는지, 그리"
|
|
"고 이 강의에서 어떻게 사용될 지에 대해 간략히 설명하겠습니다."
|
|
|
|
#: src/cargo.md
|
|
msgid "Installation"
|
|
msgstr "설치하기"
|
|
|
|
#: src/cargo.md
|
|
msgid "**Please follow the instructions on <https://rustup.rs/>.**"
|
|
msgstr "**<https://rustup.rs/>의 설치 방법을 따르세요.**"
|
|
|
|
#: src/cargo.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"This will give you the Cargo build tool (`cargo`) and the Rust compiler "
|
|
"(`rustc`). You will also get `rustup`, a command line utility that you can "
|
|
"use to install to different compiler versions."
|
|
msgstr ""
|
|
"위 설치 방법을 따르면, 빌드 시스템인 카고(`cargo`)와 러스트 컴파일러(`rustc`)"
|
|
"가 설치됩니다. 이와 함께, `rustup`도 설치되는데 이 툴은 툴체인을 설치하고, 다"
|
|
"른 툴체인으로 전환하고, 크로스 컴파일 설정을 하는 일을 담당하는 커맨드 라인 "
|
|
"유틸리티 입니다."
|
|
|
|
#: src/cargo.md
|
|
msgid ""
|
|
"After installing Rust, you should configure your editor or IDE to work with "
|
|
"Rust. Most editors do this by talking to [rust-analyzer](https://rust-"
|
|
"analyzer.github.io/), which provides auto-completion and jump-to-definition "
|
|
"functionality for [VS Code](https://code.visualstudio.com/), [Emacs](https://"
|
|
"rust-analyzer.github.io/manual.html#emacs), [Vim/Neovim](https://rust-"
|
|
"analyzer.github.io/manual.html#vimneovim), and many others. There is also a "
|
|
"different IDE available called [RustRover](https://www.jetbrains.com/rust/)."
|
|
msgstr ""
|
|
"Rust를 설치한 후에는 Rust와 호환되도록 편집기나 IDE를 구성해야 합니다. 대부분"
|
|
"의 편집기는 [VS Code](https://code.visualstudio.com/), [Emacs](https://rust-"
|
|
"analyzer.github.io/manual.html#emacs), [Vim/Neovim](https://rust-analyzer."
|
|
"github.io/manual.html#vimneovim) 등에 자동 완성 및 정의로 이동 기능을 제공하"
|
|
"는 [rust-analyzer](https://rust-analyzer.github.io/)와 통신하여 이를 실행합니"
|
|
"다. [RustRover](https://www.jetbrains.com/rust/)라는 다른 IDE도 사용할 수 있"
|
|
"습니다."
|
|
|
|
#: src/cargo.md
|
|
msgid ""
|
|
"On Debian/Ubuntu, you can also install Cargo, the Rust source and the [Rust "
|
|
"formatter](https://github.com/rust-lang/rustfmt) via `apt`. However, this "
|
|
"gets you an outdated rust version and may lead to unexpected behavior. The "
|
|
"command would be:"
|
|
msgstr ""
|
|
"데비안/우분투 시스템에서는 `apt`를 이용해서 카고, 러스트 소스, [러스트 포매"
|
|
"터](https://github.com/rust-lang/rustfmt)를 설치할 수 있습니다. 그러나 이 방"
|
|
"법을 따를 경우 최신 버전이 아닌 러스트를 사용게되며, 그 결과 예상치 못한 문제"
|
|
"를 겪을 수도 있습니다. 설치 명령어는 아래와 같습니다:"
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid "The Rust Ecosystem"
|
|
msgstr "러스트 생태계"
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"The Rust ecosystem consists of a number of tools, of which the main ones are:"
|
|
msgstr ""
|
|
"러스트의 생태계는 여러가지 도구들로 구성되어 있으며, 그 중 중요한 것들은 아래"
|
|
"와 같습니다:"
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"`rustc`: the Rust compiler which turns `.rs` files into binaries and other "
|
|
"intermediate formats."
|
|
msgstr ""
|
|
"`rustc`: `.rs` 확장자 파일을 바이너리 혹은 다른 중간 형식으로 변환해주는 "
|
|
"Rust 컴파일러입니다."
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"`cargo`: the Rust dependency manager and build tool. Cargo knows how to "
|
|
"download dependencies, usually hosted on <https://crates.io>, and it will "
|
|
"pass them to `rustc` when building your project. Cargo also comes with a "
|
|
"built-in test runner which is used to execute unit tests."
|
|
msgstr ""
|
|
"`cargo`: 러스트 의존성 관리자이자 빌드 시스템 입니다. 여러분의 프로젝트에 명"
|
|
"시된 의존성들을 <https://crates.io>에서 자동으로 다운로드 받고, 그 소스코드"
|
|
"를 `rustc`로 전달하여 빌드를 시킵니다. 또한 유닛 테스트를 실행하는 테스트 러"
|
|
"너를 내장하고 있습니다."
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`rustup`: the Rust toolchain installer and updater. This tool is used to "
|
|
"install and update `rustc` and `cargo` when new versions of Rust are "
|
|
"released. In addition, `rustup` can also download documentation for the "
|
|
"standard library. You can have multiple versions of Rust installed at once "
|
|
"and `rustup` will let you switch between them as needed."
|
|
msgstr ""
|
|
"`rustup`: 러스트 툴체인 설치 프로그램이자 업데이트 프로그램 입니다. 이 도구"
|
|
"는 새 버전의 러스트가 출시될 때 `rustc` 및 `cargo` 설치하고 업데이트하는 데 "
|
|
"사용됩니다. 또한 `rustup`은 표준 라이브러리에 대한 문서를 다운로드할 수도 있"
|
|
"습니다. 한 번에 여러 버전의 러스트를 설치할 수 있으며 `rustup`을 이용해서 실"
|
|
"제로 사용할 버전을 변경할 수 있습니다."
|
|
|
|
#: src/cargo/rust-ecosystem.md src/types-and-values/hello-world.md
|
|
#: src/references/exclusive.md src/pattern-matching/destructuring.md
|
|
#: src/memory-management/move.md src/error-handling/try.md src/android/setup.md
|
|
#: src/async/async-await.md
|
|
msgid "Key points:"
|
|
msgstr "키 포인트:"
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"Rust has a rapid release schedule with a new release coming out every six "
|
|
"weeks. New releases maintain backwards compatibility with old releases --- "
|
|
"plus they enable new functionality."
|
|
msgstr ""
|
|
"러스트는 6주마다 새로운 릴리즈가 발표되며 이전 릴리즈와의 호환성을 유지하고 "
|
|
"있습니다."
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"There are three release channels: \"stable\", \"beta\", and \"nightly\"."
|
|
msgstr ""
|
|
"릴리즈는 3가지 버전으로 제공됩니다: \"stable\", \"beta\" 그리고 \"nightly\"."
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"New features are being tested on \"nightly\", \"beta\" is what becomes "
|
|
"\"stable\" every six weeks."
|
|
msgstr ""
|
|
"새로운 기능은 \"nightly\" -> \"beta\" -(6주 후)-> \"stable\" 로 변경됩니다."
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"Dependencies can also be resolved from alternative [registries](https://doc."
|
|
"rust-lang.org/cargo/reference/registries.html), git, folders, and more."
|
|
msgstr ""
|
|
"의존성은 다양한 [저장소](registries), git 프로젝트, 디렉터리 등에서 제공될 "
|
|
"수 있습니다."
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"Rust also has [editions](https://doc.rust-lang.org/edition-guide/): the "
|
|
"current edition is Rust 2021. Previous editions were Rust 2015 and Rust 2018."
|
|
msgstr ""
|
|
"러스트는 [에디션](https://doc.rust-lang.org/edition-guide/)으로 구분됩니다. "
|
|
"현재는 Rust 2021 에디션입니다. 이 전 에디션으로 Rust 2015와 Rust 2018이 있습"
|
|
"니다."
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"The editions are allowed to make backwards incompatible changes to the "
|
|
"language."
|
|
msgstr "에디션은 이전 에디션과 호환이 되지 않을 수 있습니다."
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"To prevent breaking code, editions are opt-in: you select the edition for "
|
|
"your crate via the `Cargo.toml` file."
|
|
msgstr ""
|
|
"에디션이 바뀌면서 프로그램이 의도치 않게 깨지는 문제를 막기 위해, 각 프로그램"
|
|
"은 자신이 빌드될 에디션을 명시적으로 `Cargo.toml`에 지정해야 합니다."
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"To avoid splitting the ecosystem, Rust compilers can mix code written for "
|
|
"different editions."
|
|
msgstr ""
|
|
"러스트 생태계가 에디션 별로 파편회 되는 것을 막기 위해, 러스트 컴파일러는 서"
|
|
"로 다른 에디션에서 작성된 코드들을 하나의 바이너리로 묶을 수 있습니다."
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
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
|
|
#, fuzzy
|
|
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:"
|
|
msgstr ""
|
|
"카고 자체가 매우 강력하고 포괄적인 도구임을 적극적으로 알리세요. 카고는 다음"
|
|
"과 같은 다양한 고급 기능을 제공합니다: "
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid "Project/package structure"
|
|
msgstr "프로젝트/패키지 구조화"
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid "[workspaces](https://doc.rust-lang.org/cargo/reference/workspaces.html)"
|
|
msgstr ""
|
|
"[워크스페이스](https://doc.rust-lang.org/cargo/reference/workspaces.html)"
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid "Dev Dependencies and Runtime Dependency management/caching"
|
|
msgstr "개발/런타임 종속성 관리 및 캐싱"
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"[build scripting](https://doc.rust-lang.org/cargo/reference/build-scripts."
|
|
"html)"
|
|
msgstr ""
|
|
"[빌드 스크립트](https://doc.rust-lang.org/cargo/reference/build-scripts.html)"
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"[global installation](https://doc.rust-lang.org/cargo/commands/cargo-install."
|
|
"html)"
|
|
msgstr ""
|
|
"[전역 설치](https://doc.rust-lang.org/cargo/commands/cargo-install.html)"
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"It is also extensible with sub command plugins as well (such as [cargo "
|
|
"clippy](https://github.com/rust-lang/rust-clippy))."
|
|
msgstr ""
|
|
"[cargo clippy](https://github.com/rust-lang/rust-clippy)와 같은 하위 플러그인"
|
|
"으로 확장 가능."
|
|
|
|
#: src/cargo/rust-ecosystem.md
|
|
msgid ""
|
|
"Read more from the [official Cargo Book](https://doc.rust-lang.org/cargo/)"
|
|
msgstr ""
|
|
"[공식 Cargo Book](https://doc.rust-lang.org/cargo/)에서 자세한 사항을 확인하"
|
|
"시기 바랍니다."
|
|
|
|
#: src/cargo/code-samples.md
|
|
msgid "Code Samples in This Training"
|
|
msgstr "강의에서의 코드 샘플"
|
|
|
|
#: src/cargo/code-samples.md
|
|
msgid ""
|
|
"For this training, we will mostly explore the Rust language through examples "
|
|
"which can be executed through your browser. This makes the setup much easier "
|
|
"and ensures a consistent experience for everyone."
|
|
msgstr ""
|
|
"이 강의자료에 있는 모든 예제는 브라우저에서 바로 수행 가능합니다. 이렇게 한 "
|
|
"이유는, 준비 과정을 단순화 시키고, 모두가 같은 환경에서 작업할 수 있도록 하"
|
|
"기 위함입니다."
|
|
|
|
#: src/cargo/code-samples.md
|
|
msgid ""
|
|
"Installing Cargo is still encouraged: it will make it easier for you to do "
|
|
"the exercises. On the last day, we will do a larger exercise which shows you "
|
|
"how to work with dependencies and for that you need Cargo."
|
|
msgstr ""
|
|
"그럼에도 불구하고, 카고(cargo)를 직접 설치하는 것을 강력 권장합니다. 이게 과"
|
|
"제 작성에 더 도움이 될겁니다. 또한, 마지막 날에는 의존성이 있는 예제를 작업하"
|
|
"게 될 텐데, 그 때에는 어차피 카고가 필요합니다."
|
|
|
|
#: src/cargo/code-samples.md
|
|
msgid "The code blocks in this course are fully interactive:"
|
|
msgstr "이 강의 자료의 코드 블록들은 전부 인터엑티브 합니다:"
|
|
|
|
#: src/cargo/code-samples.md src/cargo/running-locally.md
|
|
msgid "\"Edit me!\""
|
|
msgstr "\"수정해 주세요!\""
|
|
|
|
#: src/cargo/code-samples.md
|
|
msgid "You can use "
|
|
msgstr "코드 블록에 포커스를 두고 "
|
|
|
|
#: src/cargo/code-samples.md
|
|
msgid " to execute the code when focus is in the text box."
|
|
msgstr " 를 눌러 실행해 볼 수 있습니다."
|
|
|
|
#: src/cargo/code-samples.md
|
|
msgid ""
|
|
"Most code samples are editable like shown above. A few code samples are not "
|
|
"editable for various reasons:"
|
|
msgstr ""
|
|
"강의에서 대부분의 코드 샘플은 위와 같이 수정할수 있지만 일부 코드는 다음과 같"
|
|
"은 이유로 수정할 수 없습니다:"
|
|
|
|
#: src/cargo/code-samples.md
|
|
msgid ""
|
|
"The embedded playgrounds cannot execute unit tests. Copy-paste the code and "
|
|
"open it in the real Playground to demonstrate unit tests."
|
|
msgstr ""
|
|
"유닛 테스트는 내장 플레이그라운드에서 실행이 안됩니다. 외부 플레이그라운드 사"
|
|
"이트에 붙여넣어 테스트를 실행하시기 바랍니다."
|
|
|
|
#: src/cargo/code-samples.md
|
|
msgid ""
|
|
"The embedded playgrounds lose their state the moment you navigate away from "
|
|
"the page! This is the reason that the students should solve the exercises "
|
|
"using a local Rust installation or via the Playground."
|
|
msgstr ""
|
|
"내장된 플레이그라운드에서는 페이지 이동시 작성된 모든 내용이 사라집니다. 따라"
|
|
"서 로컬 환경이나 외부 플레이그라운드 사이트에서 연습문제를 해결하는 것이 좋습"
|
|
"니다."
|
|
|
|
#: src/cargo/running-locally.md
|
|
msgid "Running Code Locally with Cargo"
|
|
msgstr "로컬 환경의 카고"
|
|
|
|
#: src/cargo/running-locally.md
|
|
msgid ""
|
|
"If you want to experiment with the code on your own system, then you will "
|
|
"need to first install Rust. Do this by following the [instructions in the "
|
|
"Rust Book](https://doc.rust-lang.org/book/ch01-01-installation.html). This "
|
|
"should give you a working `rustc` and `cargo`. At the time of writing, the "
|
|
"latest stable Rust release has these version numbers:"
|
|
msgstr ""
|
|
"만약 개인용 컴퓨터에서 코드를 실행해보려면 먼저 러스트를 설치해야 합니다. "
|
|
"[Rust Book](https://doc.rust-lang.org/book/ch01-01-installation.html)의 지침"
|
|
"에 따라 `rustc`와 `cargo`를 함께 설치 하시기 바랍니다. 설치 후 아래 커맨드를 "
|
|
"통해 각 툴의 버전을 확인 할 수 있습니다:"
|
|
|
|
#: src/cargo/running-locally.md
|
|
msgid ""
|
|
"You can use any later version too since Rust maintains backwards "
|
|
"compatibility."
|
|
msgstr ""
|
|
"이 버전보다 더 최신의 버전이어도 상관 없습니다. 러스트는 하위 호환성을 지원합"
|
|
"니다."
|
|
|
|
#: src/cargo/running-locally.md
|
|
msgid ""
|
|
"With this in place, follow these steps to build a Rust binary from one of "
|
|
"the examples in this training:"
|
|
msgstr ""
|
|
"정상적으로 설치가 되었으면, 강의 예제중 하나를 러스트 바이너리로 빌드해 봅시"
|
|
"다:"
|
|
|
|
#: src/cargo/running-locally.md
|
|
msgid "Click the \"Copy to clipboard\" button on the example you want to copy."
|
|
msgstr "예시 블록에 있는 \"Copy to clipboard\" 버튼을 클릭해서 복사합니다."
|
|
|
|
#: src/cargo/running-locally.md
|
|
msgid ""
|
|
"Use `cargo new exercise` to create a new `exercise/` directory for your code:"
|
|
msgstr ""
|
|
"터미널에서 `cargo new exercise`를 입력해서 새로운 `exercise/` 폴더를 만듭니"
|
|
"다:"
|
|
|
|
#: src/cargo/running-locally.md
|
|
msgid ""
|
|
"Navigate into `exercise/` and use `cargo run` to build and run your binary:"
|
|
msgstr "`exercise/` 폴더로 이동한 후, `cargo run` 커맨드로 코드를 실행합니다:"
|
|
|
|
#: src/cargo/running-locally.md
|
|
msgid ""
|
|
"Replace the boiler-plate code in `src/main.rs` with your own code. For "
|
|
"example, using the example on the previous page, make `src/main.rs` look like"
|
|
msgstr ""
|
|
"`src/main.rs`에 코드를 작성합니다. 예를 들어 이전 페이지의 소스를 아래와 같"
|
|
"이 `src/main.rs`에 작성합니다"
|
|
|
|
#: src/cargo/running-locally.md
|
|
msgid "Use `cargo run` to build and run your updated binary:"
|
|
msgstr "`cargo run`커맨드로 소스를 빌드하고 실행합니다:"
|
|
|
|
#: src/cargo/running-locally.md
|
|
msgid ""
|
|
"Use `cargo check` to quickly check your project for errors, use `cargo "
|
|
"build` to compile it without running it. You will find the output in `target/"
|
|
"debug/` for a normal debug build. Use `cargo build --release` to produce an "
|
|
"optimized release build in `target/release/`."
|
|
msgstr ""
|
|
"`cargo check`커맨드는 빠르게 에러를 확인할 수 있습니다. `cargo build`는 실행"
|
|
"없이 컴파일만 합니다. 이 경우에 `target/debug/`폴더에서 output을 확인 할 수 "
|
|
"있습니다. `cargo build --release`커맨드는 릴리즈 버전용 최적화를 켜서 컴파일"
|
|
"하며 `target/release/`폴더에서 확인 할 수 있습니다."
|
|
|
|
#: src/cargo/running-locally.md
|
|
msgid ""
|
|
"You can add dependencies for your project by editing `Cargo.toml`. When you "
|
|
"run `cargo` commands, it will automatically download and compile missing "
|
|
"dependencies for you."
|
|
msgstr ""
|
|
"`Cargo.toml`파일에는 의존성 패키지를 추가할 수 있습니다. `cargo`커맨드를 실행"
|
|
"하면 자동으로 의존성 패키지를 다운로드하고 컴파일 까지 해 줍니다."
|
|
|
|
#: src/cargo/running-locally.md
|
|
msgid ""
|
|
"Try to encourage the class participants to install Cargo and use a local "
|
|
"editor. It will make their life easier since they will have a normal "
|
|
"development environment."
|
|
msgstr ""
|
|
"수강생들이 카고를 설치하고 로컬 편집기를 이용하도록 독려하세요. 조금 귀찮을 "
|
|
"수도 있지만, 이렇게 해야만 좀 더 실제와 가까운 개발환경을 갖추게 되는 것입니"
|
|
"다."
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid "Welcome to Day 1"
|
|
msgstr "1일차 개요"
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid ""
|
|
"This is the first day of Rust Fundamentals. We will cover a lot of ground "
|
|
"today:"
|
|
msgstr "강의 첫 날입니다. 오늘 배울 것이 참 많습니다:"
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid ""
|
|
"Basic Rust syntax: variables, scalar and compound types, enums, structs, "
|
|
"references, functions, and methods."
|
|
msgstr ""
|
|
"러스트 기본 문법: 변수, 스칼라 / 복합 타입, 열거형, 구조체, 참조형, 함수와 메"
|
|
"서드."
|
|
|
|
#: src/welcome-day-1.md
|
|
#, fuzzy
|
|
msgid "Types and type inference."
|
|
msgstr "타입 추론"
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid "Control flow constructs: loops, conditionals, and so on."
|
|
msgstr "제어 흐름은 루프, 조건문 등으로 구성됩니다."
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid "User-defined types: structs and enums."
|
|
msgstr "사용자 정의 타입: 구조체 및 enum"
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid "Pattern matching: destructuring enums, structs, and arrays."
|
|
msgstr "패턴 매칭: 열거형, 구조체 그리고 배열 분해."
|
|
|
|
#: src/welcome-day-1.md src/welcome-day-2.md src/welcome-day-3.md
|
|
#: src/welcome-day-4.md
|
|
msgid "Schedule"
|
|
msgstr "일정 예약"
|
|
|
|
#: src/welcome-day-1.md src/welcome-day-1-afternoon.md src/welcome-day-2.md
|
|
#: src/welcome-day-2-afternoon.md src/welcome-day-3.md
|
|
#: src/welcome-day-3-afternoon.md src/welcome-day-4.md
|
|
#: src/welcome-day-4-afternoon.md
|
|
msgid "In this session:"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid "[Welcome](./welcome-day-1.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid "[Hello, World](./hello-world.md) (15 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid "[Types and Values](./types-and-values.md) (45 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid "[Control Flow Basics](./control-flow-basics.md) (40 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-1.md src/welcome-day-3-afternoon.md
|
|
#: src/welcome-day-4-afternoon.md
|
|
msgid ""
|
|
"Including 10 minute breaks, this session should take about 2 hours and 10 "
|
|
"minutes"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid "Please remind the students that:"
|
|
msgstr "학생들에게 다음을 상기시켜 주시기 바랍니다:"
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid ""
|
|
"They should ask questions when they get them, don't save them to the end."
|
|
msgstr "궁금한 점이 있으면 주저하지 말고 질문 해야 합니다."
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid ""
|
|
"The class is meant to be interactive and discussions are very much "
|
|
"encouraged!"
|
|
msgstr "이 수업은 상호작용이 요합니다. 토론을 망설이지 마세요!"
|
|
|
|
#: src/welcome-day-1.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"As an instructor, you should try to keep the discussions relevant, i.e., "
|
|
"keep the discussions related to how Rust does things vs some other language. "
|
|
"It can be hard to find the right balance, but err on the side of allowing "
|
|
"discussions since they engage people much more than one-way communication."
|
|
msgstr ""
|
|
"강사로서 토론이 옆길로 새지 않게 주의하세요. 예를 들어 러스트와 다른 언어들"
|
|
"을 비교한다든지 하는 것은 좋습니다. 적절한 균형을 찾기 애매한 경우라면 토론"
|
|
"을 허용하는 쪽이 일방적인 강의보다는 더 많은 사람들의 참여를 이끌어 낼 수 있"
|
|
"습니다."
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid ""
|
|
"The questions will likely mean that we talk about things ahead of the slides."
|
|
msgstr "질문이 슬라이드보다 앞서가도 괜찮습니다."
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid ""
|
|
"This is perfectly okay! Repetition is an important part of learning. "
|
|
"Remember that the slides are just a support and you are free to skip them as "
|
|
"you like."
|
|
msgstr ""
|
|
"학습에 있어서 반복은 매우 중요합니다. 슬라이드는 그저 도움을 줄 뿐, 원하는 대"
|
|
"로 건너띄어도 됩니다."
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid ""
|
|
"The idea for the first day is to show the \"basic\" things in Rust that "
|
|
"should have immediate parallels in other languages. The more advanced parts "
|
|
"of Rust come on the subsequent days."
|
|
msgstr ""
|
|
"첫날에는 다른 언어에서도 직접적인 관련이 있는 Rust의 '기본사항'을 보여드리고"
|
|
"자 합니다. Rust의 고급 부분은 그다음에 제공됩니다."
|
|
|
|
#: src/welcome-day-1.md
|
|
msgid ""
|
|
"If you're teaching this in a classroom, this is a good place to go over the "
|
|
"schedule. Note that there is an exercise at the end of each segment, "
|
|
"followed by a break. Plan to cover the exercise solution after the break. "
|
|
"The times listed here are a suggestion in order to keep the course on "
|
|
"schedule. Feel free to be flexible and adjust as necessary!"
|
|
msgstr ""
|
|
"교실에서 가르치는 경우 여기에서 일정을 검토하는 것이 좋습니다. 각 세그먼트가 "
|
|
"끝나면 연습문제가 있고 그 뒤에 휴식이 이어집니다. 휴식 후 연습문제 해답을 다"
|
|
"룰 계획입니다. 여기에 표시된 시간은 과정을 일정에 맞게 진행하기 위한 권장 시"
|
|
"간입니다. 필요에 따라 유연하게 조정하시기 바랍니다."
|
|
|
|
#: src/hello-world.md src/types-and-values.md src/control-flow-basics.md
|
|
#: src/tuples-and-arrays.md src/references.md src/user-defined-types.md
|
|
#: src/pattern-matching.md src/methods-and-traits.md src/generics.md
|
|
#: src/std-types.md src/std-traits.md src/memory-management.md
|
|
#: src/smart-pointers.md src/borrowing.md src/slices-and-lifetimes.md
|
|
#: src/iterators.md src/modules.md src/testing.md src/error-handling.md
|
|
#: src/unsafe-rust.md
|
|
msgid "In this segment:"
|
|
msgstr ""
|
|
|
|
#: src/hello-world.md
|
|
msgid "[What is Rust?](./hello-world/what-is-rust.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/hello-world.md
|
|
msgid "[Benefits of Rust](./hello-world/benefits.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/hello-world.md
|
|
msgid "[Playground](./hello-world/playground.md) (2 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/hello-world.md
|
|
msgid "This segment should take about 15 minutes"
|
|
msgstr ""
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid ""
|
|
"Rust is a new programming language which had its [1.0 release in 2015]"
|
|
"(https://blog.rust-lang.org/2015/05/15/Rust-1.0.html):"
|
|
msgstr ""
|
|
"러스트는 2015년에 [버전 1.0](https://blog.rust-lang.org/2015/05/15/Rust-1.0."
|
|
"html)을 릴리즈 한 새로운 프로그램 언어입니다:"
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "Rust is a statically compiled language in a similar role as C++"
|
|
msgstr "러스트는 C++와 유사한 정적 컴파일 언어입니다"
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "`rustc` uses LLVM as its backend."
|
|
msgstr "`rustc`는 LLVM을 백엔드로 사용합니다."
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid ""
|
|
"Rust supports many [platforms and architectures](https://doc.rust-lang.org/"
|
|
"nightly/rustc/platform-support.html):"
|
|
msgstr "러스트는 다양한 플랫폼과 아키텍쳐를 지원합니다:"
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "x86, ARM, WebAssembly, ..."
|
|
msgstr "x86, ARM, WebAssembly, ..."
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "Linux, Mac, Windows, ..."
|
|
msgstr "Linux, Mac, Windows, ..."
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "Rust is used for a wide range of devices:"
|
|
msgstr "러스트는 다양한 장치에서 사용될 수 있습니다:"
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "firmware and boot loaders,"
|
|
msgstr "펌웨어와 부트로더(임베디드)"
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "smart displays,"
|
|
msgstr "스마트 디스플레이,"
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "mobile phones,"
|
|
msgstr "스마트폰,"
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "desktops,"
|
|
msgstr "데스크탑,"
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "servers."
|
|
msgstr "서버."
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "Rust fits in the same area as C++:"
|
|
msgstr "러스트는 C++가 사용되는 대부분의 곳에서 사용 가능합니다:"
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "High flexibility."
|
|
msgstr "높은 유연성."
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "High level of control."
|
|
msgstr "높은 수준의 제어."
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid ""
|
|
"Can be scaled down to very constrained devices such as microcontrollers."
|
|
msgstr "마이크로컨트롤러 같은 매우 제한된 장치로 스케일 다운 가능."
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "Has no runtime or garbage collection."
|
|
msgstr "별도의 런타임을 필요로 하지 않으며, 가비지 컬렉션도 없음."
|
|
|
|
#: src/hello-world/what-is-rust.md
|
|
msgid "Focuses on reliability and safety without sacrificing performance."
|
|
msgstr "성능을 타협하지 않으면서도 안정성과 안전에 중점을 둠."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "Some unique selling points of Rust:"
|
|
msgstr "러스트만의 독특한 세일즈 포인트(장점):"
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid ""
|
|
"_Compile time memory safety_ - whole classes of memory bugs are prevented at "
|
|
"compile time"
|
|
msgstr ""
|
|
"_컴파일 시간 메모리 안전_ - 메모리 버그의 전체 클래스가 컴파일 시간에 방지됩"
|
|
"니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "No uninitialized variables."
|
|
msgstr "초기화되지 않는 변수가 없습니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "No double-frees."
|
|
msgstr "메모리 이중 해제가 원천적으로 불가능 합니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "No use-after-free."
|
|
msgstr "메모리 해제 후 사용이 원천적으로 불가능 합니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "No `NULL` pointers."
|
|
msgstr "`NULL`포인터는 없습니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "No forgotten locked mutexes."
|
|
msgstr "뮤텍스를 잠궈 놓고 여는 것을 잊는 실수를 할 수 없습니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "No data races between threads."
|
|
msgstr "스레드간 데이터 레이스를 막아줍니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "No iterator invalidation."
|
|
msgstr "반복자가 갑자기 무효화 되는 경우가 없습니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid ""
|
|
"_No undefined runtime behavior_ - what a Rust statement does is never left "
|
|
"unspecified"
|
|
msgstr ""
|
|
"_정의되지 않은 런타임 동작 없음_ - Rust 문이 실행하는 작업은 지정되지 않은 상"
|
|
"태로 두지 않습니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "Array access is bounds checked."
|
|
msgstr "배열 접근시 경계 체크."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "Integer overflow is defined (panic or wrap-around)."
|
|
msgstr "정수형 타입의 변수에서 오버플로우 발생시 동작이 잘 정의되어있습니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid ""
|
|
"_Modern language features_ - as expressive and ergonomic as higher-level "
|
|
"languages"
|
|
msgstr ""
|
|
"_최신 언어 기능_ - 상위 수준 언어만큼 표현력이 뛰어나고 인체공학적입니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "Enums and pattern matching."
|
|
msgstr "열거형과 패턴 매칭."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "Generics."
|
|
msgstr "제네릭."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "No overhead FFI."
|
|
msgstr "FFI 런타임 오버헤드 없음."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "Zero-cost abstractions."
|
|
msgstr "비용이 들지 않는 추상화."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "Great compiler errors."
|
|
msgstr "친절한 컴파일러 오류메시지."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "Built-in dependency manager."
|
|
msgstr "내장 종속성 관리자."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "Built-in support for testing."
|
|
msgstr "내장 테스트 지원."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid "Excellent Language Server Protocol support."
|
|
msgstr "LSP (Language Server Protocol, 언어 서버 프로토콜) 지원이 잘되어 있음."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid ""
|
|
"Do not spend much time here. All of these points will be covered in more "
|
|
"depth later."
|
|
msgstr ""
|
|
"여기에서 많은 시간을 보내지 마세요. 이 모든 사항은 나중에 자세히 다룹니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid ""
|
|
"Make sure to ask the class which languages they have experience with. "
|
|
"Depending on the answer you can highlight different features of Rust:"
|
|
msgstr ""
|
|
"수강생들에게 어떤 프로그래밍 언어를 사용했는지 물어보시기 바랍니다. 어떤 언어"
|
|
"를 사용했느냐에 따라 러스트에서 어떤 점을 강조해야 할지를 고민해 보세요:"
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid ""
|
|
"Experience with C or C++: Rust eliminates a whole class of _runtime errors_ "
|
|
"via the borrow checker. You get performance like in C and C++, but you don't "
|
|
"have the memory unsafety issues. In addition, you get a modern language with "
|
|
"constructs like pattern matching and built-in dependency management."
|
|
msgstr ""
|
|
"C/C++: 러스트는 '빌림'검사기를 통해서 수행중에 발생할 수 있는 모든 에러를 제"
|
|
"거합니다. 러스트는 C와 C++과 비슷한 수준의 성능을 보여주면서도, 그 언어들에"
|
|
"서 종종 발생하는 메모리 관련 오류가 없습니다. 또한, 패턴 매칭이나, 기본적으"
|
|
"로 제공되는 종속성 관리와 같은 현대적인 언어의 기능들을 제공합니다."
|
|
|
|
#: src/hello-world/benefits.md
|
|
msgid ""
|
|
"Experience with Java, Go, Python, JavaScript...: You get the same memory "
|
|
"safety as in those languages, plus a similar high-level language feeling. In "
|
|
"addition you get fast and predictable performance like C and C++ (no garbage "
|
|
"collector) as well as access to low-level hardware (should you need it)"
|
|
msgstr ""
|
|
"Java, Go, Python, JavaScript: 이 언어들과 동일한 메모리 안정성과 함께, '하이"
|
|
"레벨'언어의 느낌을 느낄 수 있습니다. 거기에 더해, 가비지 컬렉터가 없는 C/C+"
|
|
"+와 유사한 수준의 빠르고 예측 가능한 성능을 기대할 수 있습니다. 그리고 필요"
|
|
"한 경우 저수준 하드웨어를 다루는 코드로 작성할 수 있습니다."
|
|
|
|
#: src/hello-world/playground.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The [Rust Playground](https://play.rust-lang.org/) provides an easy way to "
|
|
"run short Rust programs, and is the basis for the examples and exercises in "
|
|
"this course. Try running the \"hello-world\" program it starts with. It "
|
|
"comes with a few handy features:"
|
|
msgstr ""
|
|
"[Rust 플레이그라운드](https://play.rust-lang.org/)는 짧은 Rust 프로그램을 쉽"
|
|
"게 실행할 수 있는 방법을 제공하며, 이 과정의 예시와 연습문제의 기초가 됩니"
|
|
"다. 먼저 'hello-world' 프로그램을 실행해 봅니다. 다음과 같은 몇 가지 편리한 "
|
|
"기능이 제공됩니다."
|
|
|
|
#: src/hello-world/playground.md
|
|
msgid ""
|
|
"Under \"Tools\", use the `rustfmt` option to format your code in the "
|
|
"\"standard\" way."
|
|
msgstr ""
|
|
"'도구'에서 `rustfmt` 옵션을 사용하여 '표준' 방식으로 코드 형식을 지정합니다."
|
|
|
|
#: src/hello-world/playground.md
|
|
msgid ""
|
|
"Rust has two main \"profiles\" for generating code: Debug (extra runtime "
|
|
"checks, less optimization) and Release (fewer runtime checks, lots of "
|
|
"optimization). These are accessible under \"Debug\" at the top."
|
|
msgstr ""
|
|
"Rust에는 코드를 생성하기 위한 두 가지 기본 '프로필'이 있습니다. 디버그(추가 "
|
|
"런타임 검사, 최적화 감소) 및 출시(더 적은 런타임 검사, 최적화 증가)입니다. 상"
|
|
"단의 '디버그'에서 액세스할 수 있습니다."
|
|
|
|
#: src/hello-world/playground.md
|
|
msgid ""
|
|
"If you're interested, use \"ASM\" under \"...\" to see the generated "
|
|
"assembly code."
|
|
msgstr ""
|
|
"관심이 있으시면 '...' 아래의 'ASM'을 사용해 생성된 어셈블리 코드를 확인하세"
|
|
"요."
|
|
|
|
#: src/hello-world/playground.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"As students head into the break, encourage them to open up the playground "
|
|
"and experiment a little. Encourage them to keep the tab open and try things "
|
|
"out during the rest of the course. This is particularly helpful for advanced "
|
|
"students who want to know more about Rust's optimizations or generated "
|
|
"assembly."
|
|
msgstr ""
|
|
"학생들이 휴식을 취할 때 플레이그라운드를 열고 약간의 실험을 해보도록 격려합니"
|
|
"다. 학생들이 탭을 계속 열어두고 나머지 과정을 진행하면서 여러 가지를 시도해 "
|
|
"보도록 권장하세요. 이는 Rust 최적화 또는 생성된 어셈블리에 관해 자세히 알고 "
|
|
"싶어하는 고급 수준의 학생에게 특히 유용합니다."
|
|
|
|
#: src/types-and-values.md
|
|
msgid "[Hello, World](./types-and-values/hello-world.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/types-and-values.md
|
|
msgid "[Variables](./types-and-values/variables.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/types-and-values.md
|
|
msgid "[Values](./types-and-values/values.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/types-and-values.md
|
|
msgid "[Arithmetic](./types-and-values/arithmetic.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/types-and-values.md
|
|
msgid "[Strings](./types-and-values/strings.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/types-and-values.md
|
|
msgid "[Type Inference](./types-and-values/inference.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/types-and-values.md
|
|
msgid "[Exercise: Fibonacci](./types-and-values/exercise.md) (15 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/types-and-values.md src/iterators.md src/testing.md
|
|
msgid "This segment should take about 45 minutes"
|
|
msgstr ""
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
msgid ""
|
|
"Let us jump into the simplest possible Rust program, a classic Hello World "
|
|
"program:"
|
|
msgstr ""
|
|
"가장 간단한 러스트 프로그램으로써, 고전적인 Hello World 를 작성해 보겠습니다:"
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
#, fuzzy
|
|
msgid "\"Hello 🌍!\""
|
|
msgstr "\"Hello 🌍!\""
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
msgid "What you see:"
|
|
msgstr "확인할 수 있는 것들:"
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
msgid "Functions are introduced with `fn`."
|
|
msgstr "함수는 `fn`으로 선언합니다."
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
msgid "Blocks are delimited by curly braces like in C and C++."
|
|
msgstr "C/C++ 와 마찬가지로 중괄호`{}`로 블록을 표시합니다."
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
msgid "The `main` function is the entry point of the program."
|
|
msgstr "`main` 함수는 프로그램 진입점입니다."
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
msgid "Rust has hygienic macros, `println!` is an example of this."
|
|
msgstr ""
|
|
"러스트는 똑똑한 매크로(hygienic macros) 시스템을 가지고 있습니다. `println!`"
|
|
"는 그 예시입니다."
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
msgid "Rust strings are UTF-8 encoded and can contain any Unicode character."
|
|
msgstr ""
|
|
"러스트의 문자열은 UTF-8로 인코딩되며 이모지와 같은 유니코드 문자를 포함할 수 "
|
|
"있습니다."
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"This slide tries to make the students comfortable with Rust code. They will "
|
|
"see a ton of it over the next four days so we start small with something "
|
|
"familiar."
|
|
msgstr ""
|
|
"이 슬라이드는 학생들이 러스트 코드에 익숙해지기 위해 작성되었습니다. 앞으로 3"
|
|
"일 동안 많은 코드를 접할 것이기 때문에 우선 친숙한 코드부터 시작합니다."
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
msgid ""
|
|
"Rust is very much like other languages in the C/C++/Java tradition. It is "
|
|
"imperative and it doesn't try to reinvent things unless absolutely necessary."
|
|
msgstr ""
|
|
"러스트는 C/C++/Java와 같은 전통적인 다른 언어와 매우 유사합니다. 러스트는 절"
|
|
"차적 언어입니다. 정말로 필요한 경우가 아니라면, 러스트는 이미 존재하는 것을 "
|
|
"새로 구현하려고 하지 않습니다."
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
msgid "Rust is modern with full support for things like Unicode."
|
|
msgstr "러스트는 유니코드 지원과 같은 현대 언어의 특징을 전부 지원합니다."
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Rust uses macros for situations where you want to have a variable number of "
|
|
"arguments (no function [overloading](../control-flow-basics/functions.md))."
|
|
msgstr ""
|
|
"러스트는 인자의 개수를 사전에 지정할 수 없는 상황에서 함수 [오버로딩](basic-"
|
|
"syntax/functions-interlude.md)대신 매크로를 사용합니다."
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
msgid ""
|
|
"Macros being 'hygienic' means they don't accidentally capture identifiers "
|
|
"from the scope they are used in. Rust macros are actually only [partially "
|
|
"hygienic](https://veykril.github.io/tlborm/decl-macros/minutiae/hygiene."
|
|
"html)."
|
|
msgstr ""
|
|
"똑똑한 매크로(hygienic macro)는 매크로가 사용되는 스코프에서 의도치 않게 변수"
|
|
"를 가로채지 않습니다. 사실 러스트 매크로는 완전히 hygenic하지는 않습니다. [링"
|
|
"크](https://veykril.github.io/tlborm/decl-macros/minutiae/hygiene.html)를 참"
|
|
"고하세요."
|
|
|
|
#: src/types-and-values/hello-world.md
|
|
msgid ""
|
|
"Rust is multi-paradigm. For example, it has powerful [object-oriented "
|
|
"programming features](https://doc.rust-lang.org/book/ch17-00-oop.html), and, "
|
|
"while it is not a functional language, it includes a range of [functional "
|
|
"concepts](https://doc.rust-lang.org/book/ch13-00-functional-features.html)."
|
|
msgstr ""
|
|
"러스트는 멀티 패러다임 언어입니다. 예를 들어 강력한 [객체 지향 프로그래밍 기"
|
|
"능](https://doc.rust-lang.org/book/ch17-00-oop.html)을 지원하기도 하며, 함수"
|
|
"형 언어로 분류되지는 않지만 폭넓은 범위의 [함수형 컨셉](https://doc.rust-"
|
|
"lang.org/book/ch13-00-functional-features.html)을 지원합니다."
|
|
|
|
#: src/types-and-values/variables.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Rust provides type safety via static typing. Variable bindings are made with "
|
|
"`let`:"
|
|
msgstr ""
|
|
"러스트는 정적 타이핑을 통해 타입 안전성을 제공합니다. 변수는 기본적으로 불변"
|
|
"(immutable)합니다:"
|
|
|
|
#: src/types-and-values/variables.md src/control-flow-basics/loops/for.md
|
|
#: src/control-flow-basics/blocks-and-scopes.md
|
|
msgid "\"x: {x}\""
|
|
msgstr "\"x: {x}\""
|
|
|
|
#: src/types-and-values/variables.md
|
|
msgid ""
|
|
"// x = 20;\n"
|
|
" // println!(\"x: {x}\");\n"
|
|
msgstr ""
|
|
"// x = 20;\n"
|
|
" // println!(\"x: {x}\");\n"
|
|
|
|
#: src/types-and-values/variables.md
|
|
msgid ""
|
|
"Uncomment the `x = 20` to demonstrate that variables are immutable by "
|
|
"default. Add the `mut` keyword to allow changes."
|
|
msgstr ""
|
|
"`x = 20`의 주석 처리를 삭제하여 변수가 기본적으로 불변임을 보여줍니다. `mut` "
|
|
"키워드를 추가하여 변경을 허용합니다."
|
|
|
|
#: src/types-and-values/variables.md
|
|
msgid ""
|
|
"The `i32` here is the type of the variable. This must be known at compile "
|
|
"time, but type inference (covered later) allows the programmer to omit it in "
|
|
"many cases."
|
|
msgstr ""
|
|
"여기서 'i32'는 변수의 타입입니다. 이는 컴파일 시간에 알려져야 하지만, 타입 추"
|
|
"론(나중에 설명)을 사용하면 프로그래머가 이를 생략할 수 있는 경우가 많습니다."
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid ""
|
|
"Here are some basic built-in types, and the syntax for literal values of "
|
|
"each type."
|
|
msgstr "다음은 몇 가지 기본 내장 타입과 각 타입의 리터럴 값 문법입니다."
|
|
|
|
#: src/types-and-values/values.md src/unsafe-rust/exercise.md
|
|
msgid "Types"
|
|
msgstr "타입"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "Literals"
|
|
msgstr "리터럴 값"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "Signed integers"
|
|
msgstr "부호있는 정수"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "`i8`, `i16`, `i32`, `i64`, `i128`, `isize`"
|
|
msgstr "`i8`, `i16`, `i32`, `i64`, `i128`, `isize`"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "`-10`, `0`, `1_000`, `123_i64`"
|
|
msgstr "`-10`, `0`, `1_000`, `123_i64`"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "Unsigned integers"
|
|
msgstr "부호없는 정수"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "`u8`, `u16`, `u32`, `u64`, `u128`, `usize`"
|
|
msgstr "`u8`, `u16`, `u32`, `u64`, `u128`, `usize`"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "`0`, `123`, `10_u16`"
|
|
msgstr "`0`, `123`, `10_u16`"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "Floating point numbers"
|
|
msgstr "부동소수"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "`f32`, `f64`"
|
|
msgstr "`f32`, `f64`"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "`3.14`, `-10.0e20`, `2_f32`"
|
|
msgstr "`3.14`, `-10.0e20`, `2_f32`"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "Unicode scalar values"
|
|
msgstr "유니코드 문자"
|
|
|
|
#: src/types-and-values/values.md src/android/aidl/types/primitives.md
|
|
msgid "`char`"
|
|
msgstr "`char`"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "`'a'`, `'α'`, `'∞'`"
|
|
msgstr "`'a'`, `'α'`, `'∞'`"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "Booleans"
|
|
msgstr "불리언"
|
|
|
|
#: src/types-and-values/values.md src/android/aidl/types/primitives.md
|
|
msgid "`bool`"
|
|
msgstr "`bool`"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "`true`, `false`"
|
|
msgstr "`true`, `false`"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "The types have widths as follows:"
|
|
msgstr "각 타입의 크기는 다음과 같습니다:"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "`iN`, `uN`, and `fN` are _N_ bits wide,"
|
|
msgstr "`iN`, `uN`, `fN`은 모두 _N_비트 입니다."
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "`isize` and `usize` are the width of a pointer,"
|
|
msgstr "`isize` 와 `usize` 는 포인터와 같은 크기입니다,"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "`char` is 32 bits wide,"
|
|
msgstr "`char` 32 비트 입니다,"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "`bool` is 8 bits wide."
|
|
msgstr "`bool`은 8 비트 입니다."
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid "There are a few syntaxes which are not shown above:"
|
|
msgstr "위에 표시되지 않은 몇 가지 문법이 있습니다:"
|
|
|
|
#: src/types-and-values/values.md
|
|
msgid ""
|
|
"All underscores in numbers can be left out, they are for legibility only. So "
|
|
"`1_000` can be written as `1000` (or `10_00`), and `123_i64` can be written "
|
|
"as `123i64`."
|
|
msgstr ""
|
|
"All underscores in numbers can be left out, they are for legibility only. So "
|
|
"`1_000` can be written as `1000` (or `10_00`), and `123_i64` can be written "
|
|
"as `123i64`."
|
|
|
|
#: src/types-and-values/arithmetic.md
|
|
msgid "\"result: {}\""
|
|
msgstr "\"결과: {}\""
|
|
|
|
#: src/types-and-values/arithmetic.md
|
|
msgid ""
|
|
"This is the first time we've seen a function other than `main`, but the "
|
|
"meaning should be clear: it takes three integers, and returns an integer. "
|
|
"Functions will be covered in more detail later."
|
|
msgstr ""
|
|
"`main` 이외의 함수는 이번이 처음이지만 의미는 명확합니다. 세 개의 정수를 사용"
|
|
"하고 정수를 반환합니다. 함수는 나중에 더 자세히 다루겠습니다."
|
|
|
|
#: src/types-and-values/arithmetic.md
|
|
msgid "Arithmetic is very similar to other languages, with similar precedence."
|
|
msgstr "산술연산은 다른 언어와 매우 유사하며 우선순위가 비슷합니다."
|
|
|
|
#: src/types-and-values/arithmetic.md
|
|
msgid ""
|
|
"What about integer overflow? In C and C++ overflow of _signed_ integers is "
|
|
"actually undefined, and might do different things on different platforms or "
|
|
"compilers. In Rust, it's defined."
|
|
msgstr ""
|
|
"정수 오버플로는 어떻게 되나요? C 및 C++에서 _부호있는_ 정수의 오버플로는 실제"
|
|
"로 정의되지 않으며, 다른 플랫폼이나 컴파일러에서 다른 작업을 실행할 수 있습니"
|
|
"다. Rust에서는 정수 오버플로 시의 동작이 정의되어 있습니다."
|
|
|
|
#: src/types-and-values/arithmetic.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Change the `i32`'s to `i16` to see an integer overflow, which panics "
|
|
"(checked) in a debug build and wraps in a release build. There are other "
|
|
"options, such as overflowing, saturating, and carrying. These are accessed "
|
|
"with method syntax, e.g., `(a * b).saturating_add(b * c).saturating_add(c * "
|
|
"a)`."
|
|
msgstr ""
|
|
"`i32`를 `i16`으로 변경하여 정수 오버플로 시의 동작을 확인해 봅니다. 디버그 빌"
|
|
"드에서는 패닉(확인됨)이 발생하고 출시 빌드에서는 래핑(wrap)이 일어납니다. 오"
|
|
"버플로(overflowing), 포화(saturating), 이동(carrying)과 같은 다른 옵션도 있습"
|
|
"니다. 이는 메서드 문법을 사용하여 액세스합니다. 예: `(a * b)."
|
|
"saturating_add(b * c).saturating_add(c * a)`"
|
|
|
|
#: src/types-and-values/arithmetic.md
|
|
msgid ""
|
|
"In fact, the compiler will detect overflow of constant expressions, which is "
|
|
"why the example requires a separate function."
|
|
msgstr ""
|
|
"사실 컴파일러는 상수 표현식의 오버플로를 감지하므로 이 예에서는 별도의 함수"
|
|
"가 필요합니다."
|
|
|
|
#: src/types-and-values/strings.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Rust has two types to represent strings, both of which will be covered in "
|
|
"more depth later. Both _always_ store UTF-8 encoded strings."
|
|
msgstr ""
|
|
"Rust에는 문자열을 나타내는 두 가지 타입이 있습니다. 두 타입 모두 나중에 자세"
|
|
"히 다룹니다. 둘 다 _항상_ UTF-8로 인코딩된 문자열을 저장합니다."
|
|
|
|
#: src/types-and-values/strings.md
|
|
#, fuzzy
|
|
msgid "`String` - a modifiable, owned string."
|
|
msgstr "`String`은 문자열을 담을 수 있는 버퍼입니다."
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid "`&str` - a read-only string. String literals have this type."
|
|
msgstr "`&str` - 읽기 전용 문자열입니다. 문자열 리터럴은 이 타입을 가집니다."
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid "\"Greetings\""
|
|
msgstr "\" 인사말\""
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid "\"🪐\""
|
|
msgstr "\"🪐\""
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid "\", \""
|
|
msgstr "\", \""
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid "\"final sentence: {}\""
|
|
msgstr "\"마지막 문장: {}\""
|
|
|
|
#: src/types-and-values/strings.md
|
|
#: src/methods-and-traits/traits/associated-types.md
|
|
#: src/async/control-flow/join.md
|
|
msgid "\"{:?}\""
|
|
msgstr "\"{:?}\""
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid "//println!(\"{:?}\", &sentence[12..13]);\n"
|
|
msgstr "//println!(\"{:?}\", &sentence[12..13]);\n"
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid ""
|
|
"This slide introduces strings. Everything here will be covered in more depth "
|
|
"later, but this is enough for subsequent slides and exercises to use strings."
|
|
msgstr ""
|
|
"이 슬라이드는 문자열을 소개합니다. 여기에 있는 모든 내용은 나중에 자세히 다루"
|
|
"겠지만 후속 슬라이드와 연습문제에서 문자열을 사용하는 데는 이것으로 충분합니"
|
|
"다."
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid "Invalid UTF-8 in a string is UB, and this not allowed in safe Rust."
|
|
msgstr ""
|
|
"문자열 내에 잘못된 UTF-8 인코딩이 있는 것은 정의되지 않은 동작이며, 이는 안전"
|
|
"한 Rust에서는 허용되지 않습니다."
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid ""
|
|
"`String` is a user-defined type with a constructor (`::new()`) and methods "
|
|
"like `s.push_str(..)`."
|
|
msgstr ""
|
|
"`String`은 생성자(`::new()`) 및 `s.push_str(..)`과 같은 메서드가 포함된 사용"
|
|
"자 정의 타입입니다."
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid ""
|
|
"The `&` in `&str` indicates that this is a reference. We will cover "
|
|
"references later, so for now just think of `&str` as a unit meaning \"a read-"
|
|
"only string\"."
|
|
msgstr ""
|
|
"`&str`의 `&`는 참조임을 나타냅니다. 참조는 나중에 다루므로 지금은 `&str`을 "
|
|
"'읽기 전용 문자열'을 의미하는 단위로 생각하세요."
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid ""
|
|
"The commented-out line is indexing into the string by byte position. "
|
|
"`12..13` does not end on a character boundary, so the program panics. Adjust "
|
|
"it to a range that does, based on the error message."
|
|
msgstr ""
|
|
"주석 처리된 줄은 바이트 위치별로 문자열의 색인을 생성합니다. `12..13`은 문자 "
|
|
"경계에서 끝나지 않으므로 프로그램이 패닉 상태가 됩니다. 오류 메시지에 따라 문"
|
|
"자 경계에서 끝나는 범위로 조정합니다."
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid ""
|
|
"Raw strings allow you to create a `&str` value with escapes disabled: "
|
|
"`r\"\\n\" == \"\\\\n\"`. You can embed double-quotes by using an equal "
|
|
"amount of `#` on either side of the quotes:"
|
|
msgstr ""
|
|
"Raw strings allow you to create a `&str` value with escapes disabled: "
|
|
"`r\"\\n\" == \"\\\\n\"`. You can embed double-quotes by using an equal "
|
|
"amount of `#` on either side of the quotes:"
|
|
|
|
#: src/types-and-values/strings.md
|
|
msgid ""
|
|
"Using `{:?}` is a convenient way to print array/vector/struct of values for "
|
|
"debugging purposes, and it's commonly used in code."
|
|
msgstr ""
|
|
|
|
#: src/types-and-values/inference.md
|
|
msgid "Rust will look at how the variable is _used_ to determine the type:"
|
|
msgstr "러스트는 변수가 어떻게 사용되는지를 보고 그 변수의 타입을 추론합니다:"
|
|
|
|
#: src/types-and-values/inference.md
|
|
msgid ""
|
|
"This slide demonstrates how the Rust compiler infers types based on "
|
|
"constraints given by variable declarations and usages."
|
|
msgstr ""
|
|
"이 슬라이드는, 러스트 컴파일러가 변수가 어떻게 선언되어 있고, 어떻게 사용되는"
|
|
"지를 제약 조건으로 삼아서 변수의 타입을 추론하는 모습을 보여줍니다."
|
|
|
|
#: src/types-and-values/inference.md
|
|
msgid ""
|
|
"It is very important to emphasize that variables declared like this are not "
|
|
"of some sort of dynamic \"any type\" that can hold any data. The machine "
|
|
"code generated by such declaration is identical to the explicit declaration "
|
|
"of a type. The compiler does the job for us and helps us write more concise "
|
|
"code."
|
|
msgstr ""
|
|
"여기서 중요한 것은, 이렇게 명시적인 타입을 생략하고 선언되었다고 해서 \"어떤 "
|
|
"타입\"이라도 다 담을 수 있는 타입이 되는 것은 아니라는 점입니다. 명시적인 타"
|
|
"입 선언이 있던 없던, 컴파일러가 생성한 머신코드는 동일합니다. 컴파일러는 단"
|
|
"지 타입 선언을 생략할 수 있도록 해서 프로그래머가 더 간결한 코드를 쓸 수 있도"
|
|
"록 도와줄 뿐입니다."
|
|
|
|
#: src/types-and-values/inference.md
|
|
msgid ""
|
|
"When nothing constrains the type of an integer literal, Rust defaults to "
|
|
"`i32`. This sometimes appears as `{integer}` in error messages. Similarly, "
|
|
"floating-point literals default to `f64`."
|
|
msgstr ""
|
|
"아무것도 정수 리터럴의 타입을 제한하지 않는 경우 Rust는 기본적으로 `i32`를 사"
|
|
"용합니다. 그러면 오류 메시지에 `{integer}`로 표시될 수 있습니다. 마찬가지로 "
|
|
"부동 소수점 리터럴의 기본값은 `f64`입니다."
|
|
|
|
#: src/types-and-values/inference.md
|
|
msgid "// ERROR: no implementation for `{float} == {integer}`\n"
|
|
msgstr "// ERROR: `{float} == {integer}` 구현이 없음\n"
|
|
|
|
#: src/types-and-values/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The first and second Fibonacci numbers are both `1`. For n>2, the n'th "
|
|
"Fibonacci number is calculated recursively as the sum of the n-1'th and "
|
|
"n-2'th Fibonacci numbers."
|
|
msgstr ""
|
|
"첫 번째와 두 번째 피보나치 수는 모두 '1'입니다. n>2인 경우 n번째 피보나치 수"
|
|
"는 n-1번째 피보나치 수와 n-2번째 피보나치 수의 합으로 재귀적으로 계산됩니다."
|
|
|
|
#: src/types-and-values/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Write a function `fib(n)` that calculates the n'th Fibonacci number. When "
|
|
"will this function panic?"
|
|
msgstr ""
|
|
"n번째 피보나치 수를 계산하는 `fib(n)` 함수를 작성합니다. 이 함수는 언제 패"
|
|
"닉 상태가 되나요?"
|
|
|
|
#: src/types-and-values/exercise.md
|
|
msgid "// The base case.\n"
|
|
msgstr "// 기본 사례입니다.\n"
|
|
|
|
#: src/types-and-values/exercise.md src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "\"Implement this\""
|
|
msgstr "서비스 구현"
|
|
|
|
#: src/types-and-values/exercise.md
|
|
msgid "// The recursive case.\n"
|
|
msgstr "// 재귀 사례입니다.\n"
|
|
|
|
#: src/types-and-values/exercise.md src/types-and-values/solution.md
|
|
#, fuzzy
|
|
msgid "\"fib({n}) = {}\""
|
|
msgstr "\"fib(n) = {}\""
|
|
|
|
#: src/control-flow-basics.md
|
|
msgid "[if Expressions](./control-flow-basics/if.md) (4 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/control-flow-basics.md
|
|
msgid "[Loops](./control-flow-basics/loops.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/control-flow-basics.md
|
|
msgid ""
|
|
"[break and continue](./control-flow-basics/break-continue.md) (4 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/control-flow-basics.md
|
|
msgid ""
|
|
"[Blocks and Scopes](./control-flow-basics/blocks-and-scopes.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/control-flow-basics.md
|
|
msgid "[Functions](./control-flow-basics/functions.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/control-flow-basics.md
|
|
msgid "[Macros](./control-flow-basics/macros.md) (2 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/control-flow-basics.md
|
|
msgid ""
|
|
"[Exercise: Collatz Sequence](./control-flow-basics/exercise.md) (15 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/control-flow-basics.md src/generics.md src/modules.md
|
|
msgid "This segment should take about 40 minutes"
|
|
msgstr ""
|
|
|
|
#: src/control-flow-basics/if.md
|
|
msgid "`if` expressions"
|
|
msgstr "`if` 표현식"
|
|
|
|
#: src/control-flow-basics/if.md
|
|
msgid ""
|
|
"You use [`if` expressions](https://doc.rust-lang.org/reference/expressions/"
|
|
"if-expr.html#if-expressions) exactly like `if` statements in other languages:"
|
|
msgstr ""
|
|
"다른 언어의 `if` 문과 똑같이 [`if` 표현식](https://doc.rust-lang.org/"
|
|
"reference/expressions/if-expr.html#if-expressions)을 사용합니다:"
|
|
|
|
#: src/control-flow-basics/if.md
|
|
msgid "\"zero!\""
|
|
msgstr ""
|
|
|
|
#: src/control-flow-basics/if.md
|
|
msgid "\"biggish\""
|
|
msgstr "\"큰\""
|
|
|
|
#: src/control-flow-basics/if.md
|
|
msgid "\"huge\""
|
|
msgstr "\"거대한\""
|
|
|
|
#: src/control-flow-basics/if.md
|
|
msgid ""
|
|
"In addition, you can use `if` as an expression. The last expression of each "
|
|
"block becomes the value of the `if` expression:"
|
|
msgstr ""
|
|
"게다가 `if`는 표현식으로 사용할 수도 있습니다. 아래 코드는 위와 동일합니다:"
|
|
|
|
#: src/control-flow-basics/if.md
|
|
msgid "\"small\""
|
|
msgstr "\"작은\""
|
|
|
|
#: src/control-flow-basics/if.md
|
|
msgid "\"large\""
|
|
msgstr "\"대형\""
|
|
|
|
#: src/control-flow-basics/if.md
|
|
msgid "\"number size: {}\""
|
|
msgstr "\"숫자 크기: {}\""
|
|
|
|
#: src/control-flow-basics/if.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Because `if` is an expression and must have a particular type, both of its "
|
|
"branch blocks must have the same type. Show what happens if you add `;` "
|
|
"after `\"small\"` in the second example."
|
|
msgstr ""
|
|
"`if`는 표현식이고 타입을 가져야 하므로 분기 블록은 모두 같은 타입을 가져야 합"
|
|
"니다. 두번째 예시의 `x / 2` 뒤에 `;`를 추가하여 어떻게 되는지 확인해 보시기 "
|
|
"바랍니다."
|
|
|
|
#: src/control-flow-basics/if.md
|
|
msgid ""
|
|
"When `if` is used in an expression, the expression must have a `;` to "
|
|
"separate it from the next statement. Remove the `;` before `println!` to see "
|
|
"the compiler error."
|
|
msgstr ""
|
|
"표현식에 'if'가 사용된 경우 다음 문과 구분하기 위해 표현식에 `;`이 있어야 합"
|
|
"니다. 컴파일러 오류를 보려면 `println!` 앞의 `;`을 삭제하세요."
|
|
|
|
#: src/control-flow-basics/loops.md
|
|
msgid "There are three looping keywords in Rust: `while`, `loop`, and `for`:"
|
|
msgstr "Rust에는 `while`, `loop`, `for`라는 세 가지 반복 키워드가 있습니다."
|
|
|
|
#: src/control-flow-basics/loops.md
|
|
#, fuzzy
|
|
msgid "`while`"
|
|
msgstr "`while` 반복문"
|
|
|
|
#: src/control-flow-basics/loops.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The [`while` keyword](https://doc.rust-lang.org/reference/expressions/loop-"
|
|
"expr.html#predicate-loops) works much like in other languages, executing the "
|
|
"loop body as long as the condition is true."
|
|
msgstr ""
|
|
"[`while` 키워드](https://doc.rust-lang.org/reference/expressions/loop-expr."
|
|
"html#predicate-loops)는 다른 언어와 매우 비슷하게 작동합니다:"
|
|
|
|
#: src/control-flow-basics/loops.md
|
|
msgid "\"Final x: {x}\""
|
|
msgstr "\"최종 x: {x}\""
|
|
|
|
#: src/control-flow-basics/loops/for.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The [`for` loop](https://doc.rust-lang.org/std/keyword.for.html) iterates "
|
|
"over ranges of values or the items in a collection:"
|
|
msgstr ""
|
|
"[`Drop`](https://doc.rust-lang.org/std/ops/trait.Drop.html) 트레잇은 소멸자 "
|
|
"정의에 사용됩니다."
|
|
|
|
#: src/control-flow-basics/loops/for.md
|
|
msgid "\"elem: {elem}\""
|
|
msgstr ""
|
|
|
|
#: src/control-flow-basics/loops/for.md
|
|
msgid ""
|
|
"Under the hood `for` loops use a concept called \"iterators\" to handle "
|
|
"iterating over different kinds of ranges/collections. Iterators will be "
|
|
"discussed in more detail later."
|
|
msgstr ""
|
|
|
|
#: src/control-flow-basics/loops/for.md
|
|
msgid ""
|
|
"Note that the `for` loop only iterates to `4`. Show the `1..=5` syntax for "
|
|
"an inclusive range."
|
|
msgstr ""
|
|
"`for` 반복문은 `4`까지만 실행됩니다. 마지막 값을 포함시키는 방법으로 `1..=5`"
|
|
"와 같은 문법을 보여주세요."
|
|
|
|
#: src/control-flow-basics/loops/loop.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The [`loop` statement](https://doc.rust-lang.org/std/keyword.loop.html) just "
|
|
"loops forever, until a `break`."
|
|
msgstr ""
|
|
"[`Drop`](https://doc.rust-lang.org/std/ops/trait.Drop.html) 트레잇은 소멸자 "
|
|
"정의에 사용됩니다."
|
|
|
|
#: src/control-flow-basics/loops/loop.md
|
|
msgid "\"{i}\""
|
|
msgstr "\"{i}\""
|
|
|
|
#: src/control-flow-basics/break-continue.md
|
|
msgid ""
|
|
"If you want to immediately start the next iteration use [`continue`](https://"
|
|
"doc.rust-lang.org/reference/expressions/loop-expr.html#continue-expressions)."
|
|
msgstr ""
|
|
"다음 반복을 즉시 시작하려면 [`continue`](https://doc.rust-lang.org/reference/"
|
|
"expressions/loop-expr.html#continue-expressions)를 사용합니다."
|
|
|
|
#: src/control-flow-basics/break-continue.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"If you want to exit any kind of loop early, use [`break`](https://doc.rust-"
|
|
"lang.org/reference/expressions/loop-expr.html#break-expressions). For "
|
|
"`loop`, this can take an optional expression that becomes the value of the "
|
|
"`loop` expression."
|
|
msgstr ""
|
|
"루프를 조기에 종료하려면 [`break`](https://doc.rust-lang.org/reference/"
|
|
"expressions/loop-expr.html#break-expressions)를 사용합니다,"
|
|
|
|
#: src/control-flow-basics/break-continue.md src/std-traits/exercise.md
|
|
#: src/std-traits/solution.md src/smart-pointers/trait-objects.md
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
#: src/android/build-rules/library.md
|
|
#: src/android/interoperability/cpp/rust-bridge.md
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid "\"{}\""
|
|
msgstr "\"{}\""
|
|
|
|
#: src/control-flow-basics/break-continue/labels.md
|
|
msgid ""
|
|
"Both `continue` and `break` can optionally take a label argument which is "
|
|
"used to break out of nested loops:"
|
|
msgstr "사용합니다. 중첩 루프에서는 레이블과 함께 사용할 수 있습니다:"
|
|
|
|
#: src/control-flow-basics/break-continue/labels.md
|
|
msgid "\"elements searched: {elements_searched}\""
|
|
msgstr ""
|
|
|
|
#: src/control-flow-basics/break-continue/labels.md
|
|
msgid ""
|
|
"Note that `loop` is the only looping construct which returns a non-trivial "
|
|
"value. This is because it's guaranteed to be entered at least once (unlike "
|
|
"`while` and `for` loops)."
|
|
msgstr ""
|
|
"`loop`는 non-trivial 값을 반환하는 유일한 반복문입니다. 이는 `while` 및 "
|
|
"`for` 반복문과 달리 최소한 한 번은 루프문을 수행하는 것이 보장되기 때문입니"
|
|
"다."
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes.md
|
|
msgid "Blocks"
|
|
msgstr "블록"
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"A block in Rust contains a sequence of expressions, enclosed by braces `{}`. "
|
|
"Each block has a value and a type, which are those of the last expression of "
|
|
"the block:"
|
|
msgstr ""
|
|
"러스트에서 블록은 값과 타입을 갖습니다. 블록의 마지막 표현식이 블록의 값이 됩"
|
|
"니다:"
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes.md
|
|
msgid "\"y: {y}\""
|
|
msgstr "\"y: {y}\""
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes.md
|
|
msgid ""
|
|
"If the last expression ends with `;`, then the resulting value and type is "
|
|
"`()`."
|
|
msgstr ""
|
|
"위의 `main` 함수는 마지막 표현식이 `;`로 끝나기 때문에 반환되는 값과 타입이 "
|
|
"`()`입니다."
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes.md
|
|
msgid ""
|
|
"You can show how the value of the block changes by changing the last line in "
|
|
"the block. For instance, adding/removing a semicolon or using a `return`."
|
|
msgstr ""
|
|
"블록 마지막 줄을 수정하면서 블록의 값이 어떻게 바뀌는지 보여주세요. 예를 들"
|
|
"어, 세미콜론을 넣거나 뺀다든지, 아니면 `return`을 사용해 보세요."
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes/scopes.md
|
|
msgid "A variable's scope is limited to the enclosing block."
|
|
msgstr "변수의 범위는 자신을 포함하는 블록으로 제한됩니다."
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes/scopes.md
|
|
msgid ""
|
|
"You can shadow variables, both those from outer scopes and variables from "
|
|
"the same scope:"
|
|
msgstr ""
|
|
"현재 범위에 있는 변수와, 바깥 범위에 있는 변수 모두 가릴(쉐도잉)수 있습니다:"
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes/scopes.md
|
|
msgid "\"before: {a}\""
|
|
msgstr "\"이전: {a}\""
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes/scopes.md src/generics/exercise.md
|
|
#: src/generics/solution.md src/std-traits/from-and-into.md
|
|
#: src/slices-and-lifetimes/solution.md
|
|
#, fuzzy
|
|
msgid "\"hello\""
|
|
msgstr "\"안녕하세요\""
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes/scopes.md
|
|
msgid "\"inner scope: {a}\""
|
|
msgstr "\"내부 범위: {a}\""
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes/scopes.md
|
|
msgid "\"shadowed in inner scope: {a}\""
|
|
msgstr "\"내부 범위 섀도 처리됨: {a}\""
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes/scopes.md
|
|
msgid "\"after: {a}\""
|
|
msgstr "\"이후: {a}\""
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes/scopes.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Show that a variable's scope is limited by adding a `b` in the inner block "
|
|
"in the last example, and then trying to access it outside that block."
|
|
msgstr ""
|
|
"변수의 범위가 제한된다는 것을 보여주기 위해 마지막 예제의 안쪽 블록에 `b` 라"
|
|
"는 변수를 추가하고 블록의 밖에서 이를 사용하도록 해 봅니다."
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes/scopes.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"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."
|
|
msgstr ""
|
|
"쉐도잉은 기존 변수에 새로운 값을 할당하는 것이 아닙니다. 쉐도잉을 하면 새로"
|
|
"운 변수가 생기며, 이전 변수와 새 변수는 메모리의 서로 다른 위치에 존재합니"
|
|
"다. 그 두 변수는 단지 이름이 같은 뿐이며, 코드 중 어디에서 그 이름이 사용되었"
|
|
"느냐에 따라 어떤 변수를 지칭하는 지가 결정됩니다. "
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes/scopes.md
|
|
#, fuzzy
|
|
msgid "A shadowing variable can have a different type."
|
|
msgstr "쉐도잉 시 타입을 바꿀 수 있습니다. "
|
|
|
|
#: src/control-flow-basics/blocks-and-scopes/scopes.md
|
|
msgid ""
|
|
"Shadowing looks obscure at first, but is convenient for holding on to values "
|
|
"after `.unwrap()`."
|
|
msgstr ""
|
|
"처음에 쉐도잉을 보면 코드를 더 모호하게 만든다고 생각할 수 도 있습니다. 그러"
|
|
"나 실제로 쉐도잉을 이용하면, 어떤 변수에서 `.unwrap()` 된 값을 새로운 변수에 "
|
|
"담을 경우 새로운 이름을 지을 필요 없이 기존 이름을 유지할 수 있어서 편리합니"
|
|
"다."
|
|
|
|
#: src/control-flow-basics/functions.md
|
|
msgid ""
|
|
"Declaration parameters are followed by a type (the reverse of some "
|
|
"programming languages), then a return type."
|
|
msgstr ""
|
|
"매개변수를 선언할 때에는 이름을 먼저 쓰고, 타입을 나중에 씁니다. 이름과 타입"
|
|
"은 `:` 로 구분합니다. 이는 일부 언어(예를 들어 C)와 반대임에 유의하시기 바랍"
|
|
"니다. 마찬가지로, 리턴 타입도 함수의 시작이 아닌 가장 뒷부분에 선언합니다."
|
|
|
|
#: src/control-flow-basics/functions.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The last expression in a function body (or any block) becomes the return "
|
|
"value. Simply omit the `;` at the end of the expression. The `return` "
|
|
"keyword can be used for early return, but the \"bare value\" form is "
|
|
"idiomatic at the end of a function (refactor `gcd` to use a `return`)."
|
|
msgstr ""
|
|
"함수 본문의 마지막 표현식은 반환 값이 됩니다. 간단히, 식 끝에 있는 `;`를 생략"
|
|
"하면 됩니다."
|
|
|
|
#: src/control-flow-basics/functions.md
|
|
msgid ""
|
|
"Some functions have no return value, and return the 'unit type', `()`. The "
|
|
"compiler will infer this if the `-> ()` return type is omitted."
|
|
msgstr ""
|
|
"반환값이 없는 함수의 경우, 유닛 타입 `()`을 반환합니다. `-> ()`가 생략된 경"
|
|
"우 컴파일러는 이를 추론합니다."
|
|
|
|
#: src/control-flow-basics/functions.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Overloading is not supported -- each function has a single implementation."
|
|
msgstr "개별함수는 단일 구현만 갖습니다:"
|
|
|
|
#: src/control-flow-basics/functions.md
|
|
msgid ""
|
|
"Always takes a fixed number of parameters. Default arguments are not "
|
|
"supported. Macros can be used to support variadic functions."
|
|
msgstr ""
|
|
"항상 고정된 개수의 매개변수를 사용합니다. 기본 인수는 지원되지 않습니다. 매크"
|
|
"로는 가변 함수를 지원하는 데 사용할 수 있습니다."
|
|
|
|
#: src/control-flow-basics/functions.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Always takes a single set of parameter types. These types can be generic, "
|
|
"which will be covered later."
|
|
msgstr "파라매터들의 타입은 항상 고정되어 있습니다."
|
|
|
|
#: src/control-flow-basics/macros.md
|
|
msgid ""
|
|
"Macros are expanded into Rust code during compilation, and can take a "
|
|
"variable number of arguments. They are distinguished by a `!` at the end. "
|
|
"The Rust standard library includes an assortment of useful macros."
|
|
msgstr ""
|
|
"매크로는 컴파일 중에 Rust 코드로 확장되며 다양한 수의 인수를 사용할 수 있습니"
|
|
"다. 끝에 `!`로 구분됩니다. Rust 표준 라이브러리에는 여러 가지 유용한 매크로"
|
|
"가 포함되어 있습니다."
|
|
|
|
#: src/control-flow-basics/macros.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`println!(format, ..)` prints a line to standard output, applying formatting "
|
|
"described in [`std::fmt`](https://doc.rust-lang.org/std/fmt/index.html)."
|
|
msgstr "연산자 오버로드는 `std::ops`에 있는 다양한 트레잇들을 통해 구현됩니다:"
|
|
|
|
#: src/control-flow-basics/macros.md
|
|
msgid ""
|
|
"`format!(format, ..)` works just like `println!` but returns the result as a "
|
|
"string."
|
|
msgstr ""
|
|
"`format!(format, ..)`은 `println!`처럼 작동하지만 결과를 문자열로 반환합니다."
|
|
|
|
#: src/control-flow-basics/macros.md
|
|
msgid "`dbg!(expression)` logs the value of the expression and returns it."
|
|
msgstr "`dbg!(expression)`은 표현식의 값을 기록하고 반환합니다."
|
|
|
|
#: src/control-flow-basics/macros.md
|
|
msgid ""
|
|
"`todo!()` marks a bit of code as not-yet-implemented. If executed, it will "
|
|
"panic."
|
|
msgstr ""
|
|
"`todo!()`는 일부 코드를 아직 구현되지 않은 것으로 표시합니다. 실행하면 패닉"
|
|
"이 발생합니다."
|
|
|
|
#: src/control-flow-basics/macros.md
|
|
msgid ""
|
|
"`unreachable!()` marks a bit of code as unreachable. If executed, it will "
|
|
"panic."
|
|
msgstr ""
|
|
"`unreachable!()`은 일부 코드를 연결할 수 없다고 표시합니다. 실행하면 패닉이 "
|
|
"발생합니다."
|
|
|
|
#: src/control-flow-basics/macros.md
|
|
msgid "\"{n}! = {}\""
|
|
msgstr "\"{n}! = {}\""
|
|
|
|
#: src/control-flow-basics/macros.md
|
|
msgid ""
|
|
"The takeaway from this section is that these common conveniences exist, and "
|
|
"how to use them. Why they are defined as macros, and what they expand to, is "
|
|
"not especially critical."
|
|
msgstr ""
|
|
"이 섹션에서는 이러한 일반적인 편의 기능이 있으며 이를 사용하는 방법을 기억해"
|
|
"야 합니다. 매크로로 정의되는 이유와 확장 대상은 특별히 중요하지 않습니다."
|
|
|
|
#: src/control-flow-basics/macros.md
|
|
msgid ""
|
|
"The course does not cover defining macros, but a later section will describe "
|
|
"use of derive macros."
|
|
msgstr ""
|
|
"이 과정에서는 매크로 정의를 다루지 않지만 이후 섹션에서는 파생 매크로의 사용"
|
|
"에 관해 설명합니다."
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid ""
|
|
"The [Collatz Sequence](https://en.wikipedia.org/wiki/Collatz_conjecture) is "
|
|
"defined as follows, for an arbitrary n"
|
|
msgstr ""
|
|
"[콜라츠 수열](https://en.wikipedia.org/wiki/Collatz_conjecture)은 임의의 n에 "
|
|
"대해 다음과 같이 정의됩니다."
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "1"
|
|
msgstr "12"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid " greater than zero:"
|
|
msgstr " 0보다 큰 경우:"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "If _n"
|
|
msgstr "_n"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "i"
|
|
msgstr "i"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "_ is 1, then the sequence terminates at _n"
|
|
msgstr "_이 1이면 수열은 _n에서 종료됩니다."
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "_."
|
|
msgstr "_."
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "_ is even, then _n"
|
|
msgstr "_이(가) 짝수면 _n"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "i+1"
|
|
msgstr "i+1"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid " = n"
|
|
msgstr " = n"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid " / 2_."
|
|
msgstr " / 2_입니다."
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "_ is odd, then _n"
|
|
msgstr "_이(가) 홀수이면 _n"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid " = 3 * n"
|
|
msgstr " = 3 * n"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid " + 1_."
|
|
msgstr " + 1_입니다."
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "For example, beginning with _n"
|
|
msgstr "예를 들어 _n"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "_ = 3:"
|
|
msgstr "_ = 3:으로 시작하면"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "3 is odd, so _n"
|
|
msgstr "3이 홀수이므로 _n"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "2"
|
|
msgstr "12"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "_ = 3 * 3 + 1 = 10;"
|
|
msgstr "_ = 3 * 3 + 1 = 10이며"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "10 is even, so _n"
|
|
msgstr "10은 짝수이므로 _n"
|
|
|
|
#: src/control-flow-basics/exercise.md src/bare-metal/aps/better-uart.md
|
|
msgid "3"
|
|
msgstr "3"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "_ = 10 / 2 = 5;"
|
|
msgstr "_ = 10 / 2 = 5이며"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "5 is odd, so _n"
|
|
msgstr "5는 홀수이므로 _n"
|
|
|
|
#: src/control-flow-basics/exercise.md src/bare-metal/aps/better-uart.md
|
|
msgid "4"
|
|
msgstr "4"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "_ = 3 * 5 + 1 = 16;"
|
|
msgstr "_ = 3 * 15 + 1 = 16이며"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "16 is even, so _n"
|
|
msgstr "16은 짝수이므로 _n"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "5"
|
|
msgstr "5"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "_ = 16 / 2 = 8;"
|
|
msgstr "_ = 16 / 2 = 8이고"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "8 is even, so _n"
|
|
msgstr "8은 짝수이므로 _n"
|
|
|
|
#: src/control-flow-basics/exercise.md src/bare-metal/aps/better-uart.md
|
|
msgid "6"
|
|
msgstr "6"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "_ = 8 / 2 = 4;"
|
|
msgstr "_ = 8 / 2 = 4이고"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "4 is even, so _n"
|
|
msgstr "4는 짝수이므로 _n"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "7"
|
|
msgstr "7"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "_ = 4 / 2 = 2;"
|
|
msgstr "_ = 4 / 2 = 2이며"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
#, fuzzy
|
|
msgid "2 is even, so _n"
|
|
msgstr "2는 짝수이므로 _n"
|
|
|
|
#: src/control-flow-basics/exercise.md src/bare-metal/aps/better-uart.md
|
|
msgid "8"
|
|
msgstr "8"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "_ = 1; and"
|
|
msgstr "_ = 1이 되어"
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid "the sequence terminates."
|
|
msgstr "수열이 종료됩니다."
|
|
|
|
#: src/control-flow-basics/exercise.md
|
|
msgid ""
|
|
"Write a function to calculate the length of the collatz sequence for a given "
|
|
"initial `n`."
|
|
msgstr ""
|
|
"주어진 첫 번째 `n`에 대해 콜라츠 수열의 길이를 계산하는 함수를 작성합니다."
|
|
|
|
#: src/control-flow-basics/exercise.md src/control-flow-basics/solution.md
|
|
msgid "/// Determine the length of the collatz sequence beginning at `n`.\n"
|
|
msgstr "/// `n`에서 시작하는 콜라츠 수열의 길이를 결정합니다.\n"
|
|
|
|
#: src/control-flow-basics/solution.md src/concurrency/scoped-threads.md
|
|
msgid "\"Length: {}\""
|
|
msgstr "\"길이: {}\""
|
|
|
|
#: src/welcome-day-1-afternoon.md src/welcome-day-2-afternoon.md
|
|
#: src/welcome-day-3-afternoon.md src/welcome-day-4-afternoon.md
|
|
#, fuzzy
|
|
msgid "Welcome Back"
|
|
msgstr "개요"
|
|
|
|
#: src/welcome-day-1-afternoon.md
|
|
msgid "[Tuples and Arrays](./tuples-and-arrays.md) (35 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-1-afternoon.md
|
|
msgid "[References](./references.md) (35 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-1-afternoon.md
|
|
msgid "[User-Defined Types](./user-defined-types.md) (50 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-1-afternoon.md
|
|
msgid ""
|
|
"Including 10 minute breaks, this session should take about 2 hours and 15 "
|
|
"minutes"
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays.md
|
|
msgid "[Arrays](./tuples-and-arrays/arrays.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays.md
|
|
msgid "[Tuples](./tuples-and-arrays/tuples.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays.md
|
|
msgid "[Array Iteration](./tuples-and-arrays/iteration.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays.md
|
|
msgid ""
|
|
"[Patterns and Destructuring](./tuples-and-arrays/destructuring.md) (5 "
|
|
"minutes)"
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays.md
|
|
msgid "[Exercise: Nested Arrays](./tuples-and-arrays/exercise.md) (15 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays.md src/references.md
|
|
msgid "This segment should take about 35 minutes"
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays/arrays.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"A value of the array type `[T; N]` holds `N` (a compile-time constant) "
|
|
"elements of the same type `T`. Note that the length of the array is _part of "
|
|
"its type_, which means that `[u8; 3]` and `[u8; 4]` are considered two "
|
|
"different types. Slices, which have a size determined at runtime, are "
|
|
"covered later."
|
|
msgstr ""
|
|
"배열은, 같은 타입 `T`의 값이 `N`개 있는 것입니다. 여기서 `N`은 컴파일 타임에 "
|
|
"결정된 값이어야 합니다. 이 길이도 타입의 일부입니다. 따라서, `[u8; 3]`와 "
|
|
"`[u8; 4]`은 서로 다른 타입입니다."
|
|
|
|
#: src/tuples-and-arrays/arrays.md
|
|
msgid ""
|
|
"Try accessing an out-of-bounds array element. Array accesses are checked at "
|
|
"runtime. Rust can usually optimize these checks away, and they can be "
|
|
"avoided using unsafe Rust."
|
|
msgstr ""
|
|
"범위를 벗어난 배열 요소에 액세스해 보세요. 배열 액세스는 런타임에 확인됩니"
|
|
"다. Rust는 일반적으로 이러한 확인을 최적화할 수 있으며, 안전하지 않은 Rust를 "
|
|
"사용하면 범위 확인을 하지 않을 수도 있습니다."
|
|
|
|
#: src/tuples-and-arrays/arrays.md
|
|
msgid "We can use literals to assign values to arrays."
|
|
msgstr "리터럴을 사용하여 배열에 값을 할당할 수 있습니다."
|
|
|
|
#: src/tuples-and-arrays/arrays.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The `println!` macro asks for the debug implementation with the `?` format "
|
|
"parameter: `{}` gives the default output, `{:?}` gives the debug output. "
|
|
"Types such as integers and strings implement the default output, but arrays "
|
|
"only implement the debug output. This means that we must use debug output "
|
|
"here."
|
|
msgstr ""
|
|
"포매팅 문자열에서 `?`는 디버깅 출력을 의미합니다. `{}`는 기본 출력이며, `{:?}"
|
|
"`는 디버깅 출력입니다. `{a}`, `{a:?}`와 같이 출력할 변수 이름을 포매팅 문자열"
|
|
"에 포함시킬 수도 있으며, 이 경우 인자 `a`는 별도의 인자로 추가하지 않습니다."
|
|
|
|
#: src/tuples-and-arrays/arrays.md
|
|
msgid ""
|
|
"Adding `#`, eg `{a:#?}`, invokes a \"pretty printing\" format, which can be "
|
|
"easier to read."
|
|
msgstr ""
|
|
"`#`을 추가하면(`{a:#?}`) 좀 더 읽기 쉬운 \"이쁜\" 형태로 출력이 됩니다."
|
|
|
|
#: src/tuples-and-arrays/tuples.md
|
|
msgid "Like arrays, tuples have a fixed length."
|
|
msgstr "배열과 마찬가지로 튜플은 고정 길이를 갖습니다."
|
|
|
|
#: src/tuples-and-arrays/tuples.md
|
|
msgid "Tuples group together values of different types into a compound type."
|
|
msgstr "튜플은 서로 다른 타입의 값들을 하나의 복합 타입으로 묶습니다."
|
|
|
|
#: src/tuples-and-arrays/tuples.md
|
|
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/tuples-and-arrays/tuples.md
|
|
msgid ""
|
|
"The empty tuple `()` is referred to as the \"unit type\" and signifies "
|
|
"absence of a return value, akin to `void` in other languages."
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays/iteration.md
|
|
msgid "The `for` statement supports iterating over arrays (but not tuples)."
|
|
msgstr "`for` 문은 배열 반복을 지원하지만 튜플은 지원하지 않습니다."
|
|
|
|
#: src/tuples-and-arrays/iteration.md
|
|
msgid ""
|
|
"This functionality uses the `IntoIterator` trait, but we haven't covered "
|
|
"that yet."
|
|
msgstr ""
|
|
"이 기능은 `IntoIterator` 트레잇을 사용하지만 여기서는 아직 다루지 않았습니다."
|
|
|
|
#: src/tuples-and-arrays/iteration.md
|
|
msgid ""
|
|
"The `assert_ne!` macro is new here. There are also `assert_eq!` and `assert!"
|
|
"` macros. These are always checked while, debug-only variants like "
|
|
"`debug_assert!` compile to nothing in release builds."
|
|
msgstr ""
|
|
"`assert_ne!` 매크로가 여기에 새로 추가되었습니다. `assert_eq!` 및 `assert!` "
|
|
"매크로도 있습니다. 이 매크로들은 항상 값을 확인하지만, `debug_assert!`와 같"
|
|
"은 디버그 전용 매크로는 출시 빌드에서 컴파일되지 않고 사라집니다."
|
|
|
|
#: src/tuples-and-arrays/destructuring.md
|
|
msgid ""
|
|
"When working with tuples and other structured values it's common to want to "
|
|
"extract the inner values into local variables. This can be done manually by "
|
|
"directly accessing the inner values:"
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays/destructuring.md
|
|
msgid "\"left: {left}, right: {right}\""
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays/destructuring.md
|
|
msgid ""
|
|
"However, Rust also supports using pattern matching to destructure a larger "
|
|
"value into its constituent parts:"
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays/destructuring.md
|
|
msgid "This works with any kind of structured value:"
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays/destructuring.md
|
|
#, fuzzy
|
|
msgid "\"a: {a}, b: {b}\""
|
|
msgstr "\"a = {}, b = {}\""
|
|
|
|
#: src/tuples-and-arrays/destructuring.md
|
|
msgid ""
|
|
"The patterns used here are \"irrefutable\", meaning that the compiler can "
|
|
"statically verify that the value on the right of `=` has the same structure "
|
|
"as the pattern."
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays/destructuring.md
|
|
msgid ""
|
|
"A variable name is an irrefutable pattern that always matches any value, "
|
|
"hence why we can also use `let` to declare a single variable."
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays/destructuring.md
|
|
msgid ""
|
|
"Rust also supports using patterns in conditionals, allowing for equality "
|
|
"comparison and destructuring to happen at the same time. This form of "
|
|
"pattern matching will be discussed in more detail later."
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays/destructuring.md
|
|
msgid ""
|
|
"Edit the examples above to show the compiler error when the pattern doesn't "
|
|
"match the value being matched on."
|
|
msgstr ""
|
|
|
|
#: src/tuples-and-arrays/exercise.md
|
|
msgid "Arrays can contain other arrays:"
|
|
msgstr "배열에는 다음과 같은 다른 배열이 포함될 수 있습니다."
|
|
|
|
#: src/tuples-and-arrays/exercise.md
|
|
#, fuzzy
|
|
msgid "What is the type of this variable?"
|
|
msgstr "매 루프에서 `word`의 타입은 무엇입니까?"
|
|
|
|
#: src/tuples-and-arrays/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Use an array such as the above to write a function `transpose` which will "
|
|
"transpose a matrix (turn rows into columns):"
|
|
msgstr ""
|
|
"위 코드를 이용해서, 행렬을 예쁘게 출력하는 `pretty_print`함수와, 행렬을 전치"
|
|
"(행과 열을 서로 바꾸는)시키는 `transpose`함수를 작성해 보시기 바랍니다:"
|
|
|
|
#: src/tuples-and-arrays/exercise.md
|
|
msgid "Hard-code both functions to operate on 3 × 3 matrices."
|
|
msgstr "두 함수 모두 행렬의 크기는 3 x 3 으로 하드코딩 합니다."
|
|
|
|
#: src/tuples-and-arrays/exercise.md
|
|
msgid ""
|
|
"Copy the code below to <https://play.rust-lang.org/> and implement the "
|
|
"functions:"
|
|
msgstr ""
|
|
"아래 코드를 <https://play.rust-lang.org/>에 복사해서 구현하시면 됩니다:"
|
|
|
|
#: src/tuples-and-arrays/exercise.md src/borrowing/exercise.md
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "// TODO: remove this when you're done with your implementation.\n"
|
|
msgstr "// TODO: 구현이 완료되면 이를 삭제합니다.\n"
|
|
|
|
#: src/tuples-and-arrays/exercise.md src/tuples-and-arrays/solution.md
|
|
msgid "//\n"
|
|
msgstr "//\n"
|
|
|
|
#: src/tuples-and-arrays/exercise.md src/tuples-and-arrays/solution.md
|
|
msgid "// <-- the comment makes rustfmt add a newline\n"
|
|
msgstr "// <-- 주석으로 rustfmt가 줄바꿈을 추가합니다.\n"
|
|
|
|
#: src/tuples-and-arrays/exercise.md src/tuples-and-arrays/solution.md
|
|
msgid "\"matrix: {:#?}\""
|
|
msgstr "\"행렬: {:#?}\""
|
|
|
|
#: src/tuples-and-arrays/exercise.md src/tuples-and-arrays/solution.md
|
|
msgid "\"transposed: {:#?}\""
|
|
msgstr "\"전치행렬: {:#?}\""
|
|
|
|
#: src/references.md
|
|
msgid "[Shared References](./references/shared.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/references.md
|
|
msgid "[Exclusive References](./references/exclusive.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/references.md
|
|
msgid "[Exercise: Geometry](./references/exercise.md) (15 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/references/shared.md
|
|
msgid ""
|
|
"A reference provides a way to access another value without taking "
|
|
"responsibility for the value, and is also called \"borrowing\". Shared "
|
|
"references are read-only, and the referenced data cannot change."
|
|
msgstr ""
|
|
"참조는 값에 대한 책임을 지지 않고 다른 값에 액세스하는 방법을 제공하며 '빌"
|
|
"림'이라고도 합니다. 공유 참조는 읽기 전용이며 참조된 데이터는 변경할 수 없습"
|
|
"니다."
|
|
|
|
#: src/references/shared.md
|
|
msgid ""
|
|
"A shared reference to a type `T` has type `&T`. A reference value is made "
|
|
"with the `&` operator. The `*` operator \"dereferences\" a reference, "
|
|
"yielding its value."
|
|
msgstr ""
|
|
"`T` 타입에 대한 공유 참조는 `&T` 타입을 갖습니다. 참조 값은 `&` 연산자로 작성"
|
|
"됩니다. `*` 연산자는 참조를 '역참조'하여 값을 산출합니다."
|
|
|
|
#: src/references/shared.md
|
|
msgid "Rust will statically forbid dangling references:"
|
|
msgstr "러스트는 허상(dangling) 참조를 컴파일러 단계에서 찾아내고 금지합니다:"
|
|
|
|
#: src/references/shared.md
|
|
msgid ""
|
|
"A reference is said to \"borrow\" the value it refers to, and this is a good "
|
|
"model for students not familiar with pointers: code can use the reference to "
|
|
"access the value, but is still \"owned\" by the original variable. The "
|
|
"course will get into more detail on ownership in day 3."
|
|
msgstr ""
|
|
"참조는 참조되는 값을 '빌린다'고 하며, 이는 포인터에 익숙하지 않은 학생들에게 "
|
|
"좋은 모델입니다. 코드에서는 참조를 사용하여 값에 액세스할 수 있지만 여전히 원"
|
|
"래 변수가 값을 '소유'합니다. 소유권에 관한 자세한 내용은 3일 차에 다룹니다."
|
|
|
|
#: src/references/shared.md
|
|
msgid ""
|
|
"References are implemented as pointers, and a key advantage is that they can "
|
|
"be much smaller than the thing they point to. Students familiar with C or C+"
|
|
"+ will recognize references as pointers. Later parts of the course will "
|
|
"cover how Rust prevents the memory-safety bugs that come from using raw "
|
|
"pointers."
|
|
msgstr ""
|
|
"참조는 포인터로 구현되며 주요 이점은 가리키는 대상보다 훨씬 작을 수 있다는 것"
|
|
"입니다. C 또는 C++에 익숙한 학생은 참조를 포인터로 인식합니다. 과정의 후반부"
|
|
"에서는 Rust가 원시 포인터 사용에서 비롯되는 메모리 안전 버그를 방지하는 방법"
|
|
"을 다룹니다."
|
|
|
|
#: src/references/shared.md
|
|
msgid ""
|
|
"Rust does not automatically create references for you - the `&` is always "
|
|
"required."
|
|
msgstr "Rust는 참조를 자동으로 생성하지 않습니다. `&`가 항상 필요합니다."
|
|
|
|
#: src/references/shared.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Rust will auto-dereference in some cases, in particular when invoking "
|
|
"methods (try `r.is_ascii()`). There is no need for an `->` operator like in "
|
|
"C++."
|
|
msgstr ""
|
|
"러스트는 특정한 경우(메서드 호출)에 자동으로 역참조를 합니다.(`ref_x."
|
|
"count_one()`을 하면 `*ref_x`가 `count_one`의 인자로 전달됩니다.)"
|
|
|
|
#: src/references/shared.md
|
|
msgid ""
|
|
"In this example, `r` is mutable so that it can be reassigned (`r = &b`). "
|
|
"Note that this re-binds `r`, so that it refers to something else. This is "
|
|
"different from C++, where assignment to a reference changes the referenced "
|
|
"value."
|
|
msgstr ""
|
|
"이 예에서 `r`은 변경 가능하므로 다시 할당할 수 있습니다(`r = &b`). 이렇게 하"
|
|
"면 `r`이 다시 바인딩되어 다른 것을 참조합니다. 이는 참조에 할당하면 참조된 값"
|
|
"이 변경되는 C++와는 다릅니다."
|
|
|
|
#: src/references/shared.md
|
|
msgid ""
|
|
"A shared reference does not allow modifying the value it refers to, even if "
|
|
"that value was mutable. Try `*r = 'X'`."
|
|
msgstr ""
|
|
"공유 참조에서는 참조 값이 변경 가능하더라도 이를 수정할 수 없습니다. `*r = "
|
|
"'X'`를 입력해 보세요."
|
|
|
|
#: src/references/shared.md
|
|
msgid ""
|
|
"Rust is tracking the lifetimes of all references to ensure they live long "
|
|
"enough. Dangling references cannot occur in safe Rust. `x_axis` would return "
|
|
"a reference to `point`, but `point` will be deallocated when the function "
|
|
"returns, so this will not compile."
|
|
msgstr ""
|
|
"Rust는 모든 참조의 전체 기간을 추적하여 충분히 오래 지속되는지 확인합니다. 안"
|
|
"전한 Rust에서는 댕글링 참조가 발생할 수 없습니다. `x_axis`는 `point`에 대한 "
|
|
"참조를 반환하지만 `point`는 함수가 반환되면 할당이 해제되므로 컴파일되지 않습"
|
|
"니다."
|
|
|
|
#: src/references/shared.md
|
|
msgid "We will talk more about borrowing when we get to ownership."
|
|
msgstr ""
|
|
"소유권에 대한 주제를 다룰 때 이 빌림에 대해 더 자세히 이야기 하겠습니다."
|
|
|
|
#: src/references/exclusive.md
|
|
msgid ""
|
|
"Exclusive references, also known as mutable references, allow changing the "
|
|
"value they refer to. They have type `&mut T`."
|
|
msgstr ""
|
|
"변경 가능한 참조라고도 하는 배타적 참조를 사용하면 참조되는 값을 변경할 수 있"
|
|
"습니다. 타입은 `&mut T`입니다."
|
|
|
|
#: src/references/exclusive.md
|
|
msgid ""
|
|
"\"Exclusive\" means that only this reference can be used to access the "
|
|
"value. No other references (shared or exclusive) can exist at the same time, "
|
|
"and the referenced value cannot be accessed while the exclusive reference "
|
|
"exists. Try making an `&point.0` or changing `point.0` while `x_coord` is "
|
|
"alive."
|
|
msgstr ""
|
|
"'배타적'이란 값에 액세스하는 데 이 참조만 사용할 수 있음을 의미합니다. 동시"
|
|
"에 다른 참조(공유 또는 배타적)가 존재할 수 없으며, 배타적 참조가 존재하는 동"
|
|
"안에는 참조된 값에 액세스할 수 없습니다. `x_coord`가 활성화되어 있는 동안 "
|
|
"`&point.0`을 만들거나 `point.0`을 변경해 보세요."
|
|
|
|
#: src/references/exclusive.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Be sure to note the difference between `let mut x_coord: &i32` and `let "
|
|
"x_coord: &mut i32`. The first one represents a shared reference which can be "
|
|
"bound to different values, while the second represents an exclusive "
|
|
"reference to a mutable value."
|
|
msgstr ""
|
|
"`let mut ref_x: &i32`와 `let ref_x: &mut i32`의 차이점에 주의 하시기 바랍니"
|
|
"다. 첫번째 값은 다른 값에 바인딩 될 수 있는 가변 참조이고, 두번째 값은 가변 "
|
|
"값에 대한 참조입니다."
|
|
|
|
#: src/references/exercise.md
|
|
msgid ""
|
|
"We will create a few utility functions for 3-dimensional geometry, "
|
|
"representing a point as `[f64;3]`. It is up to you to determine the function "
|
|
"signatures."
|
|
msgstr ""
|
|
"3차원 도형을 위한 몇 가지 유틸리티 함수를 만들어 보겠습니다. 3차원 상의 한 점"
|
|
"을 `[f64;3]`으로 나타내도록 합니다. 함수 서명은 개발자가 결정합니다."
|
|
|
|
#: src/references/exercise.md
|
|
msgid ""
|
|
"// Calculate the magnitude of a vector by summing the squares of its "
|
|
"coordinates\n"
|
|
"// and taking the square root. Use the `sqrt()` method to calculate the "
|
|
"square\n"
|
|
"// root, like `v.sqrt()`.\n"
|
|
msgstr ""
|
|
"// 해당 좌표의 제곱을 더하고\n"
|
|
"// 제곱근을 사용하여 벡터의 크기를 계산합니다. `v.sqrt()`와 같은 `sqrt()` 메"
|
|
"서드를 사용하여 제곱근을\n"
|
|
"// 계산합니다.\n"
|
|
|
|
#: src/references/exercise.md
|
|
msgid ""
|
|
"// Normalize a vector by calculating its magnitude and dividing all of its\n"
|
|
"// coordinates by that magnitude.\n"
|
|
msgstr ""
|
|
"// 벡터의 크기를 계산하고 모든 좌표를 해당 크기로 나눠서\n"
|
|
"// 벡터를 정규화합니다.\n"
|
|
|
|
#: src/references/exercise.md
|
|
msgid "// Use the following `main` to test your work.\n"
|
|
msgstr "// 다음 `main`을 사용하여 작업을 테스트합니다.\n"
|
|
|
|
#: src/references/exercise.md src/references/solution.md
|
|
msgid "\"Magnitude of a unit vector: {}\""
|
|
msgstr "\"단위 벡터의 크기: {}\""
|
|
|
|
#: src/references/exercise.md src/references/solution.md
|
|
msgid "\"Magnitude of {v:?}: {}\""
|
|
msgstr "\"{v:?} 크기: {}\""
|
|
|
|
#: src/references/exercise.md src/references/solution.md
|
|
msgid "\"Magnitude of {v:?} after normalization: {}\""
|
|
msgstr "\"정규화 후 {v:?}의 크기: {}\""
|
|
|
|
#: src/references/solution.md
|
|
msgid "/// Calculate the magnitude of the given vector.\n"
|
|
msgstr "/// 지정된 벡터의 크기를 계산합니다.\n"
|
|
|
|
#: src/references/solution.md
|
|
msgid ""
|
|
"/// Change the magnitude of the vector to 1.0 without changing its "
|
|
"direction.\n"
|
|
msgstr "/// 방향 변경 없이 벡터 크기를 1.0으로 변경합니다.\n"
|
|
|
|
#: src/user-defined-types.md
|
|
msgid "[Named Structs](./user-defined-types/named-structs.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/user-defined-types.md
|
|
msgid "[Tuple Structs](./user-defined-types/tuple-structs.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/user-defined-types.md
|
|
msgid "[Enums](./user-defined-types/enums.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/user-defined-types.md
|
|
msgid ""
|
|
"[Static and Const](./user-defined-types/static-and-const.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/user-defined-types.md
|
|
msgid "[Type Aliases](./user-defined-types/aliases.md) (2 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/user-defined-types.md
|
|
msgid ""
|
|
"[Exercise: Elevator Events](./user-defined-types/exercise.md) (15 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/user-defined-types.md src/methods-and-traits.md src/borrowing.md
|
|
msgid "This segment should take about 50 minutes"
|
|
msgstr ""
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
msgid "Like C and C++, Rust has support for custom structs:"
|
|
msgstr "C/C++ 와 마찬가지로 러스트는 커스텀 구조체를 지원합니다:"
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
msgid "\"{} is {} years old\""
|
|
msgstr "\"{}은(는) {}세입니다.\""
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "\"Peter\""
|
|
msgstr "\"피터\""
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
msgid "\"Avery\""
|
|
msgstr "\"에이버리\""
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
msgid "\"Jackie\""
|
|
msgstr "\"재키\""
|
|
|
|
#: src/user-defined-types/named-structs.md src/user-defined-types/enums.md
|
|
#: src/pattern-matching/match.md src/methods-and-traits/methods.md
|
|
msgid "Key Points:"
|
|
msgstr "키 포인트:"
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
msgid "Structs work like in C or C++."
|
|
msgstr "구조체는 C/C++ 와 유사합니다."
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
msgid "Like in C++, and unlike in C, no typedef is needed to define a type."
|
|
msgstr ""
|
|
"C++ 와 같지만 C와는 달리 타입을 정의하기 위해 'typedef'가 필요하지 않습니다."
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
msgid "Unlike in C++, there is no inheritance between structs."
|
|
msgstr "C++ 와 달리 구조체 간 상속은 없습니다."
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"This may be a good time to let people know there are different types of "
|
|
"structs."
|
|
msgstr ""
|
|
"사람들에게 다른 종류의 구조체가 있음을 알게 하기에 좋은 시간일 것입니다. "
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"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."
|
|
msgstr ""
|
|
"0 크기 구조체(예: `struct Foo;`)는 데이터를 가지고 있지 않지만 특정 타입의 트"
|
|
"레잇을 구현할 때 유용합니다. "
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
msgid ""
|
|
"The next slide will introduce Tuple structs, used when the field names are "
|
|
"not important."
|
|
msgstr ""
|
|
"다음 슬라이드에서는 필드 이름이 덜 중요할 때 사용할 수 있는 튜플 구조체를 소"
|
|
"개합니다."
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"If you already have variables with the right names, then you can create the "
|
|
"struct using a shorthand."
|
|
msgstr ""
|
|
"구조체 필드와 동일한 이름의 변수가 있다면 아래와 같이 \"짧은 문법\"으로 구조"
|
|
"체를 생성할 수 있습니다:"
|
|
|
|
#: src/user-defined-types/named-structs.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The syntax `..avery` allows us to copy the majority of the fields from the "
|
|
"old struct without having to explicitly type it all out. It must always be "
|
|
"the last element."
|
|
msgstr ""
|
|
"`..peter` 문법은 한 구조체에서 다른 구조체로 대부분의 값을 복사하려고 하는 경"
|
|
"우에 하나하나 타이핑하는 수고를 덜어줍니다. 반드시 맨 마지막에 와야 합니다."
|
|
|
|
#: src/user-defined-types/tuple-structs.md
|
|
msgid "If the field names are unimportant, you can use a tuple struct:"
|
|
msgstr "각 필드 이름이 중요하지 않다면 튜플 구조체를 사용할 수 있습니다:"
|
|
|
|
#: src/user-defined-types/tuple-structs.md
|
|
msgid "\"({}, {})\""
|
|
msgstr "\"({}, {})\""
|
|
|
|
#: src/user-defined-types/tuple-structs.md
|
|
msgid "This is often used for single-field wrappers (called newtypes):"
|
|
msgstr ""
|
|
"튜플 구조체는 종종 단일 필드의 래퍼(wrapper, 러스트에서 뉴타입(newtype)이라"
|
|
"고 부름)로 사용됩니다:"
|
|
|
|
#: src/user-defined-types/tuple-structs.md
|
|
msgid "\"Ask a rocket scientist at NASA\""
|
|
msgstr "\"NASA 로켓 과학자에게 물어보세요\""
|
|
|
|
#: src/user-defined-types/tuple-structs.md
|
|
#: src/android/interoperability/cpp/cpp-bridge.md
|
|
#: src/bare-metal/microcontrollers/type-state.md
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid "// ...\n"
|
|
msgstr "// ...\n"
|
|
|
|
#: src/user-defined-types/tuple-structs.md
|
|
msgid ""
|
|
"Newtypes are a great way to encode additional information about the value in "
|
|
"a primitive type, for example:"
|
|
msgstr ""
|
|
"뉴타입은 기본 타입에 부가적인 의미를 더하는 좋은 방법입니다. 예를 들어:"
|
|
|
|
#: src/user-defined-types/tuple-structs.md
|
|
msgid "The number is measured in some units: `Newtons` in the example above."
|
|
msgstr "숫자값에 단위를 표시할 수 있음: 위에서 `Newtons`이 그 예입니다."
|
|
|
|
#: src/user-defined-types/tuple-structs.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"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)`."
|
|
msgstr ""
|
|
"값이 생성될 때 이미 유효성 검사를 통과 했으므로 추가적인 검사가 필요없습니"
|
|
"다: `PhoneNumber(String)`또는 `OddNumber(u32)`."
|
|
|
|
#: src/user-defined-types/tuple-structs.md
|
|
msgid ""
|
|
"Demonstrate how to add a `f64` value to a `Newtons` type by accessing the "
|
|
"single field in the newtype."
|
|
msgstr "`Newtons` 타입의 값에 `f64` 값을 더하는 방법을 보여주세요."
|
|
|
|
#: src/user-defined-types/tuple-structs.md
|
|
msgid ""
|
|
"Rust generally doesn’t like inexplicit things, like automatic unwrapping or "
|
|
"for instance using booleans as integers."
|
|
msgstr ""
|
|
"러스트는 분명하지 않은 것을 싫어합니다. 예를 들면 자동으로 unwrap하거나 불리"
|
|
"언 값을 정수 값으로 사용하는 것들이 그렇습니다."
|
|
|
|
#: src/user-defined-types/tuple-structs.md
|
|
msgid "Operator overloading is discussed on Day 3 (generics)."
|
|
msgstr "연산자 재정의는 3일차 제네릭 부분에서 다룹니다."
|
|
|
|
#: src/user-defined-types/tuple-structs.md
|
|
msgid ""
|
|
"The example is a subtle reference to the [Mars Climate Orbiter](https://en."
|
|
"wikipedia.org/wiki/Mars_Climate_Orbiter) failure."
|
|
msgstr ""
|
|
"이는 [화성 기후 궤도선 (Mars Climate Orbiter)](https://en.wikipedia.org/wiki/"
|
|
"Mars_Climate_Orbiter)의 실패 원인으로 지목된 도량형 입력 오류를 보여줍니다."
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid ""
|
|
"The `enum` keyword allows the creation of a type which has a few different "
|
|
"variants:"
|
|
msgstr ""
|
|
"`enum` 키워드는 몇가지 변형(variant)으로 표현되는 열거형 타입을 생성합니다:"
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid "// Simple variant\n"
|
|
msgstr "// 단순 변형\n"
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid "// Tuple variant\n"
|
|
msgstr "// 튜플 변형\n"
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid "// Struct variant\n"
|
|
msgstr "// 구조체 변형\n"
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid "\"On this turn: {:?}\""
|
|
msgstr "\"이번 차례: {:?}\""
|
|
|
|
#: src/user-defined-types/enums.md
|
|
#, fuzzy
|
|
msgid "Enumerations allow you to collect a set of values under one type."
|
|
msgstr "열거형은 값들의 집합을 하나의 타입으로 표현할 수 있게 합니다"
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid ""
|
|
"`Direction` is a type with variants. There are two values of `Direction`: "
|
|
"`Direction::Left` and `Direction::Right`."
|
|
msgstr ""
|
|
"`Direction`은 변형을 가지는 열거형 타입입니다. 여기에는 `Direction::Left`와 "
|
|
"`Direction::Right`의 두 값이 포함됩니다."
|
|
|
|
#: src/user-defined-types/enums.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`PlayerMove` is a type with three variants. In addition to the payloads, "
|
|
"Rust will store a discriminant so that it knows at runtime which variant is "
|
|
"in a `PlayerMove` value."
|
|
msgstr ""
|
|
"`PlayerMove`는 세 가지 변형을 가지는 열거형 타입입니다. Rust는 각 변형에 속"
|
|
"한 데이터 뿐 아니라, 어떤 종류의 변형이 값에 포함되어 있는지 런타임에 판별할 "
|
|
"수 있는 판별식(discriminant)도 저장합니다."
|
|
|
|
#: src/user-defined-types/enums.md
|
|
#, fuzzy
|
|
msgid "This might be a good time to compare structs and enums:"
|
|
msgstr "구조체와 열거형을 비교해 보겠습니다:"
|
|
|
|
#: src/user-defined-types/enums.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"In both, you can have a simple version without fields (unit struct) or one "
|
|
"with different types of fields (variant payloads)."
|
|
msgstr ""
|
|
"구조체나 열거형 모두, 필드가 하나도 없는 단순한 형태도 가능 하고, 여러 타입"
|
|
"의 필드를 가질 수도 있습니다. "
|
|
|
|
#: src/user-defined-types/enums.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"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."
|
|
msgstr ""
|
|
"열거형 타입의 각 variant를 별도의 구조체로 정의할 수도 있지만, 그러면 열거형"
|
|
"을 사용했을 때처럼 하나의 타입으로 취급할 수 없습니다. "
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid "Rust uses minimal space to store the discriminant."
|
|
msgstr "Rust는 판별식을 저장하는 데 최소한의 공간을 사용합니다."
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid "If necessary, it stores an integer of the smallest required size"
|
|
msgstr "필요한 경우 필요한 가장 작은 크기의 정수를 저장합니다."
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid ""
|
|
"If the allowed variant values do not cover all bit patterns, it will use "
|
|
"invalid bit patterns to encode the discriminant (the \"niche "
|
|
"optimization\"). For example, `Option<&u8>` stores either a pointer to an "
|
|
"integer or `NULL` for the `None` variant."
|
|
msgstr ""
|
|
"허용된 변형 값이 모든 비트 패턴을 포함하지 않는 경우 잘못된 비트 패턴을 사용"
|
|
"하여 판별식을 인코딩합니다('틈새 최적화'). 예를 들어 `Option<&u8>`은 정수를 "
|
|
"가리키는 포인터나 `None` 변형의 경우 `NULL`을 저장합니다."
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid ""
|
|
"You can control the discriminant if needed (e.g., for compatibility with C):"
|
|
msgstr "C와의 연동을 위해 식별자 값을 직접 지정할 수도 있습니다:"
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid ""
|
|
"Without `repr`, the discriminant type takes 2 bytes, because 10001 fits 2 "
|
|
"bytes."
|
|
msgstr ""
|
|
"`repr` 속성이 없다면 10001이 2 바이트로 표현가능하기 때문에 식별자의 타입 크"
|
|
"기는 2 바이트가 됩니다."
|
|
|
|
#: src/user-defined-types/enums.md src/user-defined-types/static-and-const.md
|
|
#: src/memory-management/review.md src/memory-management/move.md
|
|
#: src/smart-pointers/box.md src/borrowing/shared.md
|
|
msgid "More to Explore"
|
|
msgstr "더 살펴보기"
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid ""
|
|
"Rust has several optimizations it can employ to make enums take up less "
|
|
"space."
|
|
msgstr ""
|
|
"Rust에는 enum이 더 적은 공간을 차지하도록 하는 데 사용할 수 있는 여러 최적화"
|
|
"가 있습니다."
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid ""
|
|
"Null pointer optimization: For [some types](https://doc.rust-lang.org/std/"
|
|
"option/#representation), Rust guarantees that `size_of::<T>()` equals "
|
|
"`size_of::<Option<T>>()`."
|
|
msgstr ""
|
|
"널포인터 최적화: [어떤 타입들](https://doc.rust-lang.org/std/option/"
|
|
"#representation)에 대해서 러스트는 `size_of::<T>()`가 `size_of::"
|
|
"<Option<T>>()`와 같은 것을 보장합니다."
|
|
|
|
#: src/user-defined-types/enums.md
|
|
msgid ""
|
|
"Example code if you want to show how the bitwise representation _may_ look "
|
|
"like in practice. It's important to note that the compiler provides no "
|
|
"guarantees regarding this representation, therefore this is totally unsafe."
|
|
msgstr ""
|
|
"실제로 널포인터 최적화가 적용된 것을 확인하고 싶다면 아래의 예제코드를 사용하"
|
|
"세요. 주의할 점은, 여기에서 보여주는 비트 패턴이 컴파일러가 보장해 주는 것은 "
|
|
"아니라는 점입니다. 여기에 의존하는 것은 완전히 unsafe합니다."
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Static and constant variables are two different ways to create globally-"
|
|
"scoped values that cannot be moved or reallocated during the execution of "
|
|
"the program."
|
|
msgstr ""
|
|
"정적 변수와 상수는 전역 스코프에서 값을 생성하는 두 가지 방법입니다. 전역 스"
|
|
"코프에 생성된 값은 프로그램 수행 도중에 다른 값으로 이동되지 않으며, 메모리 "
|
|
"상에서 그 위치가 변하지 않습니다. "
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "`const`"
|
|
msgstr "상수(`const`)"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid ""
|
|
"Constant variables are evaluated at compile time and their values are "
|
|
"inlined wherever they are used:"
|
|
msgstr ""
|
|
"상수는 컴파일 할 때 그 값이 정해집니다. 그리고 그 값은 그 상수가 사용되는 모"
|
|
"든 부분에서 인라인 됩니다:"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid ""
|
|
"According to the [Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-"
|
|
"vs-static.html) these are inlined upon use."
|
|
msgstr ""
|
|
"[Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-vs-static.html)"
|
|
"에 따르면 상수는, 그 상수가 사용되는 곳에 인라인 됩니다."
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid ""
|
|
"Only functions marked `const` can be called at compile time to generate "
|
|
"`const` values. `const` functions can however be called at runtime."
|
|
msgstr ""
|
|
"`const` 값을 생성할 때에는 `const`로 마킹된 함수만이 호출 가능하며, 이 함수들"
|
|
"은 컴파일 시에 호출이 됩니다. 물론 `const`함수들을 런타임에 호출하는 것도 가"
|
|
"능합니다."
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "`static`"
|
|
msgstr "정적변수(`static`)"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid ""
|
|
"Static variables will live during the whole execution of the program, and "
|
|
"therefore will not move:"
|
|
msgstr ""
|
|
"정적 변수는 프로그램이 수행되는 동안 유지가 됩니다. 그러므로 다른 변수로 이동"
|
|
"(move)되지 않습니다:"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
#, fuzzy
|
|
msgid "\"Welcome to RustOS 3.14\""
|
|
msgstr "1일차 개요"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "\"{BANNER}\""
|
|
msgstr "\"{BANNER}\""
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"As noted in the [Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-"
|
|
"vs-static.html), 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. When a "
|
|
"globally-scoped value does not have a reason to need object identity, "
|
|
"`const` is generally preferred."
|
|
msgstr ""
|
|
"[Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-vs-static.html)에"
|
|
"서 언급한 바와 같이, 정적 변수는 별도의 메모리 공간을 가지며, 인라인 되지 않"
|
|
"습니다. 정적 변수는 안전하지 않은(unsafe) 러스트와 임베디드 시스템용 코드에"
|
|
"서 유용합니다. 이들의 수명은 프로그램이 수행되는 전체 시간과 동일합니다. 전"
|
|
"역 스코프를 가진 어떤 값이, 메모리 상에 단 하나만 존재해야 한다는 요구조건이 "
|
|
"없다면, 정적 변수 대신 `const`를 쓰는 것이 옳습니다."
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "Mention that `const` behaves semantically similar to C++'s `constexpr`."
|
|
msgstr "러스트의 `const`는 C++의 `constexpr`과 매우 비슷합니다."
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid ""
|
|
"`static`, on the other hand, is much more similar to a `const` or mutable "
|
|
"global variable in C++."
|
|
msgstr ""
|
|
"반면에 러스트의 `static`은 C++의 `const`나 가변 정적 변수(mutable global "
|
|
"variable)와 훨씬 더 유사합니다."
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid ""
|
|
"`static` provides object identity: an address in memory and state as "
|
|
"required by types with interior mutability such as `Mutex<T>`."
|
|
msgstr ""
|
|
"`static`은 객체에 정체성을 부여합니다. 정체정이란 메모리 상에서의 주소, 그리"
|
|
"고 내부 상태를 의미합니다."
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid ""
|
|
"It isn't super common that one would need a runtime evaluated constant, but "
|
|
"it is helpful and safer than using a static."
|
|
msgstr ""
|
|
"프로그램 수행시 그 값이 정해지는 상수가 필요한 경우는 드뭅니다. 그러나 그렇다"
|
|
"고 해도, 정적 변수를 사용하는 것 보다는 더 유용하고 안전합니다."
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "Properties table:"
|
|
msgstr "속성 비교 테이블:"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "Property"
|
|
msgstr "속성"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "Static"
|
|
msgstr "정적(static) 변수"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "Constant"
|
|
msgstr "상수(constant)"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "Has an address in memory"
|
|
msgstr "메모리 상에 주소가 있는가"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid "Yes"
|
|
msgstr "예"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "No (inlined)"
|
|
msgstr "아니오(인라인 됨)"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "Lives for the entire duration of the program"
|
|
msgstr "프로그램이 수행되는 동안 계속 살아 있는가"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid "No"
|
|
msgstr "아니오"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "Can be mutable"
|
|
msgstr "변경 가능한가"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "Yes (unsafe)"
|
|
msgstr "예 (그러나 안전하지 않음)"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "Evaluated at compile time"
|
|
msgstr "컴파일시 그 값이 결정되는가"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "Yes (initialised at compile time)"
|
|
msgstr "예 (컴파일시 초기화 됨)"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
msgid "Inlined wherever it is used"
|
|
msgstr "사용되는 곳에 인라인 되는가"
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Because `static` variables are accessible from any thread, they must be "
|
|
"`Sync`. Interior mutability is possible through a [`Mutex`](https://doc.rust-"
|
|
"lang.org/std/sync/struct.Mutex.html), atomic or similar."
|
|
msgstr ""
|
|
"`static`변수들은 어떤 스레드에서도 접근 가능하기 때문에, `Sync`트레잇을 구현"
|
|
"해야 합니다. 이 변수를 읽고 쓰려면 [`Mutex`](https://doc.rust-lang.org/std/"
|
|
"sync/struct.Mutex.html)로 감싸거나, atomic 연산을 써야 합니다. `static` 변수"
|
|
"를 mutable하게 선언할 수도 있지만, 이 경우 동기화 작업을 수동으로 해 주어야 "
|
|
"합니다. 그래서 그러한 변수를 접근하는 코드는`unsafe`로 명시적으로 표시가 되어"
|
|
"야 합니다. \"안전하지 않은 러스트\"를 배울 때 [mutable statics](../unsafe/"
|
|
"mutable-static-variables.md) 부분에서 좀 더 자세히 다루겠습니다."
|
|
|
|
#: src/user-defined-types/static-and-const.md
|
|
#, fuzzy
|
|
msgid "Thread-local data can be created with the macro `std::thread_local`."
|
|
msgstr ""
|
|
"`thread_local` 데이터는 `std::thread_local` 매크로를 이용하여 생성할 수 있습"
|
|
"니다."
|
|
|
|
#: src/user-defined-types/aliases.md
|
|
msgid ""
|
|
"A type alias creates a name for another type. The two types can be used "
|
|
"interchangeably."
|
|
msgstr ""
|
|
"타입 별칭은 다른 타입의 이름을 생성합니다. 두 타입은 서로 바꿔서 사용할 수 있"
|
|
"습니다."
|
|
|
|
#: src/user-defined-types/aliases.md
|
|
msgid "// Aliases are more useful with long, complex types:\n"
|
|
msgstr "// 별칭은 다음과 같이 길고 복잡한 타입에서 더 유용합니다.\n"
|
|
|
|
#: src/user-defined-types/aliases.md
|
|
msgid "C programmers will recognize this as similar to a `typedef`."
|
|
msgstr "C 프로그래머는 이를 `typedef`와 유사한 것으로 인식합니다."
|
|
|
|
#: src/user-defined-types/exercise.md
|
|
msgid ""
|
|
"We will create a data structure to represent an event in an elevator control "
|
|
"system. It is up to you to define the types and functions to construct "
|
|
"various events. Use `#[derive(Debug)]` to allow the types to be formatted "
|
|
"with `{:?}`."
|
|
msgstr ""
|
|
"엘리베이터 제어 시스템의 이벤트를 나타내는 데이터 구조를 만들어 보겠습니다. "
|
|
"다양한 이벤트를 구성하기 위해 타입과 함수를 정의하는 것은 개발자의 몫입니다. "
|
|
"해당 타입을 `{:?}` 문법을 통해 출력할 수 있도록 `#[derive(Debug)]`를 사용합시"
|
|
"다."
|
|
|
|
#: src/user-defined-types/exercise.md
|
|
msgid ""
|
|
"This exercise only requires creating and populating data structures so that "
|
|
"`main` runs without errors. The next part of the course will cover getting "
|
|
"data out of these structures."
|
|
msgstr ""
|
|
"이 연습에서는 `main` 함수가 에러없이 동작하도록 데이터 구조만 만들면 됩니다. "
|
|
"이 과정의 다음 부분에서는 이러한 구조에서 데이터를 가져오는 방법을 다룹니다."
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid ""
|
|
"/// An event in the elevator system that the controller must react to.\n"
|
|
msgstr "/// 컨트롤러가 반응해야 하는 엘리베이터 시스템의 이벤트입니다.\n"
|
|
|
|
#: src/user-defined-types/exercise.md
|
|
msgid "// TODO: add required variants\n"
|
|
msgstr "// TODO: 필요한 변형들을 추가하세요.\n"
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid "/// A direction of travel.\n"
|
|
msgstr "/// 이동 방향입니다.\n"
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid "/// The car has arrived on the given floor.\n"
|
|
msgstr "/// 엘리베이터가 지정된 층에 도착했습니다.\n"
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid "/// The car doors have opened.\n"
|
|
msgstr "/// 엘리베이터 문이 열렸습니다.\n"
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid "/// The car doors have closed.\n"
|
|
msgstr "/// 엘리베이터 문이 닫혔습니다.\n"
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid ""
|
|
"/// A directional button was pressed in an elevator lobby on the given "
|
|
"floor.\n"
|
|
msgstr "/// 지정된 층의 엘리베이터 로비에서 방향 버튼을 눌렀습니다.\n"
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid "/// A floor button was pressed in the elevator car.\n"
|
|
msgstr "/// 엘리베이터에서 층 버튼을 눌렀습니다.\n"
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid "\"A ground floor passenger has pressed the up button: {:?}\""
|
|
msgstr "\"1층 승객이 위쪽 버튼을 눌렀습니다. {:?}\""
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid "\"The car has arrived on the ground floor: {:?}\""
|
|
msgstr "\"엘리베이터가 1층에 도착했습니다: {:?}\""
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid "\"The car door opened: {:?}\""
|
|
msgstr "\"엘리베이터 문이 열렸습니다. {:?}\""
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid "\"A passenger has pressed the 3rd floor button: {:?}\""
|
|
msgstr "\"승객이 3층 버튼을 눌렀습니다. {:?}\""
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid "\"The car door closed: {:?}\""
|
|
msgstr "\"엘리베이터 문이 닫혔습니다: {:?}\""
|
|
|
|
#: src/user-defined-types/exercise.md src/user-defined-types/solution.md
|
|
msgid "\"The car has arrived on the 3rd floor: {:?}\""
|
|
msgstr "\"엘리베이터가 3층에 도착했습니다. {:?}\""
|
|
|
|
#: src/user-defined-types/solution.md
|
|
msgid "/// A button was pressed.\n"
|
|
msgstr "/// 버튼을 눌렀습니다.\n"
|
|
|
|
#: src/user-defined-types/solution.md
|
|
msgid "/// The car has arrived at the given floor.\n"
|
|
msgstr "/// 엘리베이터가 지정된 층에 도착했습니다.\n"
|
|
|
|
#: src/user-defined-types/solution.md
|
|
msgid "/// The car's doors have opened.\n"
|
|
msgstr "/// 엘리베이터 문이 열렸습니다.\n"
|
|
|
|
#: src/user-defined-types/solution.md
|
|
msgid "/// The car's doors have closed.\n"
|
|
msgstr "/// 엘리베이터 문이 닫혔습니다.\n"
|
|
|
|
#: src/user-defined-types/solution.md
|
|
msgid "/// A floor is represented as an integer.\n"
|
|
msgstr "/// 층은 정수로 표시됩니다.\n"
|
|
|
|
#: src/user-defined-types/solution.md
|
|
msgid "/// A user-accessible button.\n"
|
|
msgstr "/// 사용자가 액세스할 수 있는 버튼입니다.\n"
|
|
|
|
#: src/user-defined-types/solution.md
|
|
msgid "/// A button in the elevator lobby on the given floor.\n"
|
|
msgstr "/// 특정 층의 엘리베이터 로비에 있는 버튼입니다.\n"
|
|
|
|
#: src/user-defined-types/solution.md
|
|
msgid "/// A floor button within the car.\n"
|
|
msgstr "/// 엘리베이터 내부의 층 버튼입니다.\n"
|
|
|
|
#: src/welcome-day-2.md
|
|
msgid "Welcome to Day 2"
|
|
msgstr "2일차 개요"
|
|
|
|
#: src/welcome-day-2.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Now that we have seen a fair amount of Rust, today will focus on Rust's type "
|
|
"system:"
|
|
msgstr "상당한 분량의 러스트에 대해 보았고, 이어서 오늘 강의를 진행하겠습니다:"
|
|
|
|
#: src/welcome-day-2.md
|
|
#, fuzzy
|
|
msgid "Pattern matching: extracting data from structures."
|
|
msgstr "패턴 매칭: 열거형, 구조체 그리고 배열 분해."
|
|
|
|
#: src/welcome-day-2.md
|
|
msgid "Methods: associating functions with types."
|
|
msgstr "메서드: 함수를 타입과 연결"
|
|
|
|
#: src/welcome-day-2.md
|
|
msgid "Traits: behaviors shared by multiple types."
|
|
msgstr "트레잇: 여러 타입에서 공유하는 동작"
|
|
|
|
#: src/welcome-day-2.md
|
|
msgid "Generics: parameterizing types on other types."
|
|
msgstr "제네릭: 다른 타입의 타입 매개변수화"
|
|
|
|
#: src/welcome-day-2.md
|
|
msgid ""
|
|
"Standard library types and traits: a tour of Rust's rich standard library."
|
|
msgstr "표준 라이브러리 타입 및 트레잇: Rust의 풍부한 표준 라이브러리 둘러보기"
|
|
|
|
#: src/welcome-day-2.md
|
|
msgid "[Welcome](./welcome-day-2.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-2.md
|
|
#, fuzzy
|
|
msgid "[Pattern Matching](./pattern-matching.md) (1 hour)"
|
|
msgstr "패턴에 관한 설명은 [패턴 매칭](../pattern-matching.md)을 참조하세요."
|
|
|
|
#: src/welcome-day-2.md
|
|
msgid "[Methods and Traits](./methods-and-traits.md) (50 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-2.md
|
|
msgid "[Generics](./generics.md) (40 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-2.md
|
|
msgid ""
|
|
"Including 10 minute breaks, this session should take about 2 hours and 55 "
|
|
"minutes"
|
|
msgstr ""
|
|
|
|
#: src/pattern-matching.md
|
|
msgid "[Matching Values](./pattern-matching/match.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/pattern-matching.md
|
|
msgid "[Destructuring](./pattern-matching/destructuring.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/pattern-matching.md
|
|
msgid "[Let Control Flow](./pattern-matching/let-control-flow.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/pattern-matching.md
|
|
msgid ""
|
|
"[Exercise: Expression Evaluation](./pattern-matching/exercise.md) (30 "
|
|
"minutes)"
|
|
msgstr ""
|
|
|
|
#: src/pattern-matching.md src/memory-management.md
|
|
msgid "This segment should take about 1 hour"
|
|
msgstr ""
|
|
|
|
#: src/pattern-matching/match.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The `match` keyword lets you match a value against one or more _patterns_. "
|
|
"The comparisons are done from top to bottom and the first match wins."
|
|
msgstr ""
|
|
"`match`키워드는 값을 여러 형태의 패턴과 매치시킬 수 있습니다. 맨 위 패턴부터 "
|
|
"하나씩 매치되는지 검사하며, 처음으로 매치되는 패턴이 선택됩니다."
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "The patterns can be simple values, similarly to `switch` in C and C++:"
|
|
msgstr "C/C++의 `switch`와 비슷하게 값을 패턴으로 사용할 수도 있습니다:"
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "'x'"
|
|
msgstr "'x'"
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "'q'"
|
|
msgstr "'q'"
|
|
|
|
#: src/pattern-matching/match.md
|
|
#, fuzzy
|
|
msgid "\"Quitting\""
|
|
msgstr "\"종료\""
|
|
|
|
#: src/pattern-matching/match.md src/generics/exercise.md
|
|
#: src/generics/solution.md src/std-traits/solution.md
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "'a'"
|
|
msgstr "'a'"
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "'s'"
|
|
msgstr "'s'"
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "'w'"
|
|
msgstr "'w'"
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "'d'"
|
|
msgstr "'d'"
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "\"Moving around\""
|
|
msgstr "\"이리저리 이동\""
|
|
|
|
#: src/pattern-matching/match.md src/error-handling/exercise.md
|
|
#: src/error-handling/solution.md
|
|
msgid "'0'"
|
|
msgstr "'0'"
|
|
|
|
#: src/pattern-matching/match.md src/error-handling/exercise.md
|
|
#: src/error-handling/solution.md
|
|
msgid "'9'"
|
|
msgstr "'9'"
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "\"Number input\""
|
|
msgstr "\"숫자 입력\""
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "\"Lowercase: {key}\""
|
|
msgstr "\"소문자: {key}\""
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "\"Something else\""
|
|
msgstr "\"기타\""
|
|
|
|
#: src/pattern-matching/match.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The `_` pattern is a wildcard pattern which matches any value. The "
|
|
"expressions _must_ be exhaustive, meaning that it covers every possibility, "
|
|
"so `_` is often used as the final catch-all case."
|
|
msgstr ""
|
|
"`_` 패턴은 모든 값과 일치하는 와일드 카드 패턴입니다. 이 표현식은 반박할 수 _"
|
|
"없어야 합니다_. 즉, 모든 가능성을 포함하므로 '_'가 최종 포괄 사례로 사용되는 "
|
|
"경우가 많습니다."
|
|
|
|
#: src/pattern-matching/match.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Match can be used as an expression. Just like `if`, each match arm must have "
|
|
"the same type. The type is the last expression of the block, if any. In the "
|
|
"example above, the type is `()`."
|
|
msgstr ""
|
|
"`if let`과 마찬가지로 매치의 모든 팔(arm)은 같은 타입이어야 합니다. 팔이 블록"
|
|
"이라면 블록의 마지막 표현식이 그 타입이 됩니다. 위의 예제에서 매치 표현식의 "
|
|
"타입은 `()`입니다."
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid ""
|
|
"A variable in the pattern (`key` in this example) will create a binding that "
|
|
"can be used within the match arm."
|
|
msgstr ""
|
|
"패턴의 변수(이 예에서는 `key`)는 일치 부문 내에서 사용할 수 있는 바인딩을 만"
|
|
"듭니다."
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "A match guard causes the arm to match only if the condition is true."
|
|
msgstr "일치 가드는 조건이 참인 경우에만 부분이 일치하도록 합니다."
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid ""
|
|
"You might point out how some specific characters are being used when in a "
|
|
"pattern"
|
|
msgstr "패턴에서 사용되는 특수 문자들을 알려주세요"
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "`|` as an `or`"
|
|
msgstr "`|`: or 기호입니다"
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "`..` can expand as much as it needs to be"
|
|
msgstr "`..`: 필요한 만큼 확장합니다"
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "`1..=5` represents an inclusive range"
|
|
msgstr "`1..=5`: 끝 값(여기서는 5)을 포함하는 범위를 나타냅니다"
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid "`_` is a wild card"
|
|
msgstr "`_`: 와일드카드입니다"
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid ""
|
|
"Match guards as a separate syntax feature are important and necessary when "
|
|
"we wish to concisely express more complex ideas than patterns alone would "
|
|
"allow."
|
|
msgstr ""
|
|
"매치 가드는 별도의 문법 요소로서 패턴 자체만으로 표현하기 어려운 복잡한 경우"
|
|
"를 간결하게 표현하고자 할 때 유용합니다."
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid ""
|
|
"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 of the original `match` expression being considered."
|
|
msgstr ""
|
|
"매치의 각 팔(혹은 가지) 안에 따로 `if`를 사용한 것과 다릅니다. 매치 가지의 "
|
|
"`=>` 뒤에 사용된 `if` 표현식은 해당 가지가 선택된 다음에 실행됩니다. 따라서 "
|
|
"여기서 `if` 조건이 실패하더라도 원래 `match`의 다른 가지는 고려되지 않습니다."
|
|
|
|
#: src/pattern-matching/match.md
|
|
msgid ""
|
|
"The condition defined in the guard applies to every expression in a pattern "
|
|
"with an `|`."
|
|
msgstr "가드에 정의된 조건은 `|` 를 포함하는 패턴의 모든 표현식에 적용됩니다."
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid "Like tuples, structs and enums can also be destructured by matching:"
|
|
msgstr ""
|
|
"튜플과 마찬가지로 구조체 및 enum도 다음을 일치시켜 디스트럭처링할 수 있습니"
|
|
"다."
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid "Structs"
|
|
msgstr "구조체"
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid "\"x.0 = 1, b = {b}, y = {y}\""
|
|
msgstr "\"x.0 = 1, b = {b}, y = {y}\""
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid "\"y = 2, x = {i:?}\""
|
|
msgstr "\"y = 2, x = {i:?}\""
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid "\"y = {y}, other fields were ignored\""
|
|
msgstr "\"y = {y}, 다른 필드는 무시됨\""
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid ""
|
|
"Patterns can also be used to bind variables to parts of your values. This is "
|
|
"how you inspect the structure of your types. Let us start with a simple "
|
|
"`enum` type:"
|
|
msgstr ""
|
|
"구조체나 열거형 값의 일부를 패턴 매치를 통해 변수에 바인딩할 수 있습니다. 간"
|
|
"단한 `enum` 타입을 먼저 살펴보겠습니다:"
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid "\"cannot divide {n} into two equal parts\""
|
|
msgstr "\"{n}을(를) 두 개의 동일한 부분으로 나눌 수 없음\""
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid "\"{n} divided in two is {half}\""
|
|
msgstr "\"{n}을(를) 둘로 나눈 값은 {half}입니다.\""
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid "\"sorry, an error happened: {msg}\""
|
|
msgstr "\"죄송합니다. 오류가 발생했습니다. {msg}\""
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid ""
|
|
"Here we have used the arms to _destructure_ the `Result` value. In the first "
|
|
"arm, `half` is bound to the value inside the `Ok` variant. In the second "
|
|
"arm, `msg` is bound to the error message."
|
|
msgstr ""
|
|
"`match`구문에서 `divide_in_two`함수에서 반환되는 `Result` 값을 두 개의 팔(혹"
|
|
"은 가지)로 _분해(destructure)_ 하였습니다. 첫번째 팔에서 `half`는 `Ok` "
|
|
"variant에 담긴 값으로 바인딩됩니다. 두번째 팔에서 `msg`는 오류 메시지 문자열"
|
|
"에 바인딩됩니다."
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid "Change the literal values in `foo` to match with the other patterns."
|
|
msgstr "`foo`의 리터럴 값을 다른 패턴과 일치하도록 변경합니다."
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid "Add a new field to `Foo` and make changes to the pattern as needed."
|
|
msgstr "`Foo`에 새 필드를 추가하고 필요에 따라 패턴을 변경합니다."
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid ""
|
|
"The distinction between a capture and a constant expression can be hard to "
|
|
"spot. Try changing the `2` in the second arm to a variable, and see that it "
|
|
"subtly doesn't work. Change it to a `const` and see it working again."
|
|
msgstr ""
|
|
"캡처와 상수 표현식은 구분하기 어려울 수 있습니다. 두 번째 부문의 `2`를 변수"
|
|
"로 변경해 보고 작동하지 않는 것을 확인하세요. `const`로 변경하고 다시 작동하"
|
|
"는지 확인합니다."
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid ""
|
|
"The `if`/`else` expression is returning an enum that is later unpacked with "
|
|
"a `match`."
|
|
msgstr ""
|
|
"`if`/`else` 표현식은 열거형을 반환하고, 이 값은 나중에 `match`로 분해됩니다."
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid ""
|
|
"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 tries to give you hints."
|
|
msgstr ""
|
|
"열거형에 세번째 variant를 추가하고 코드를 실행하여 오류를 표시해보세요. 코드 "
|
|
"어느 부분에 누락이 있는지, 그리고 컴파일러가 어떤 식으로 힌트를 주는지 같이 "
|
|
"살펴보세요."
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The values in the enum variants can only be accessed after being pattern "
|
|
"matched."
|
|
msgstr ""
|
|
"열거형 안의 값은 패턴 매칭이 되고 난 이후에만 접근 가능합니다. 그 값에 대한 "
|
|
"레퍼런스는 `=>` 이후에 사용가능합니다."
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Demonstrate what happens when the search is inexhaustive. Note the advantage "
|
|
"the Rust compiler provides by confirming when all cases are handled."
|
|
msgstr ""
|
|
"매칭 패턴들이 불충분 하다면 어떤 일이 일어나는지 설명하세요. 러스트 컴파일러"
|
|
"는 모든 가능한 케이스들이 핸들링 되는지 체크한다는 점을 상기시키세요. "
|
|
|
|
#: src/pattern-matching/destructuring.md
|
|
msgid ""
|
|
"Save the result of `divide_in_two` in the `result` variable and `match` it "
|
|
"in a loop. That won't compile because `msg` is consumed when matched. To fix "
|
|
"it, match `&result` instead of `result`. That will make `msg` a reference so "
|
|
"it won't be consumed. This [\"match ergonomics\"](https://rust-lang.github."
|
|
"io/rfcs/2005-match-ergonomics.html) appeared in Rust 2018. If you want to "
|
|
"support older Rust, replace `msg` with `ref msg` in the pattern."
|
|
msgstr ""
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid ""
|
|
"Rust has a few control flow constructs which differ from other languages. "
|
|
"They are used for pattern matching:"
|
|
msgstr ""
|
|
"Rust에는 다른 언어와는 다른 몇 가지 제어 흐름 구조가 있으며 패턴 일치에 사용"
|
|
"됩니다."
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid "`if let` expressions"
|
|
msgstr "`if let` 표현식"
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
#, fuzzy
|
|
msgid "`while let` expressions"
|
|
msgstr "while let 표현식"
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid "`match` expressions"
|
|
msgstr "`match` 표현식"
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid ""
|
|
"The [`if let` expression](https://doc.rust-lang.org/reference/expressions/if-"
|
|
"expr.html#if-let-expressions) lets you execute different code depending on "
|
|
"whether a value matches a pattern:"
|
|
msgstr ""
|
|
"[`if let` 표현식](https://doc.rust-lang.org/reference/expressions/if-expr."
|
|
"html#if-let-expressions)을 사용하면 값이 패턴과 일치하는지에 따라 다른 코드"
|
|
"를 실행할 수 있습니다:"
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid "\"slept for {:?}\""
|
|
msgstr "\"{:?} 동안 잠들었습니다.\""
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
#, fuzzy
|
|
msgid "`let else` expressions"
|
|
msgstr "`if let` 표현식"
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid ""
|
|
"For the common case of matching a pattern and returning from the function, "
|
|
"use [`let else`](https://doc.rust-lang.org/rust-by-example/flow_control/"
|
|
"let_else.html). The \"else\" case must diverge (`return`, `break`, or panic "
|
|
"- anything but falling off the end of the block)."
|
|
msgstr ""
|
|
"패턴을 일치시키고 함수에서 반환하는 일반적인 경우에는 [`let else`](https://"
|
|
"doc.rust-lang.org/rust-by-example/flow_control/let_else.html)를 사용합니다. "
|
|
"'else' 사례는 해당 코드를 벗어나야 합니다 (`return`, `break` 또는 패닉 - 블록"
|
|
"의 다음 위치로 이동하는 것만 아니면 됩니다)."
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid "\"got None\""
|
|
msgstr "\"None을 가져옴\""
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
#, fuzzy
|
|
msgid "\"got empty string\""
|
|
msgstr "\"빈 문자열을 가져옴\""
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid "\"not a hex digit\""
|
|
msgstr "\"16진수가 아님\""
|
|
|
|
#: src/pattern-matching/let-control-flow.md src/pattern-matching/solution.md
|
|
msgid "\"result: {:?}\""
|
|
msgstr "\"결과: {:?}\""
|
|
|
|
#: src/pattern-matching/let-control-flow.md src/generics/trait-bounds.md
|
|
#: src/smart-pointers/solution.md src/testing/solution.md
|
|
#: src/android/testing.md src/android/testing/googletest.md
|
|
msgid "\"foo\""
|
|
msgstr "\"foo\""
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid ""
|
|
"Like with `if let`, there is a [`while let`](https://doc.rust-lang.org/"
|
|
"reference/expressions/loop-expr.html#predicate-pattern-loops) variant which "
|
|
"repeatedly tests a value against a pattern:"
|
|
msgstr ""
|
|
"마지막으로, 무한 루프를 만드는 [`loop` 키워드](https://doc.rust-lang.org/"
|
|
"reference/expressions/loop-expr.html#infinite-loops)가 있습니다:"
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Here [`String::pop`](https://doc.rust-lang.org/stable/std/string/struct."
|
|
"String.html#method.pop) returns `Some(c)` until the string is empty, after "
|
|
"which it will return `None`. The `while let` lets us keep iterating through "
|
|
"all items."
|
|
msgstr ""
|
|
"`v.into_iter()`가 반환한 반복자는 `next()`가 호출될 때마다 `Option<i32>`를 반"
|
|
"환합니다. 반복자가 완료될 때까지는 `Some(x)`를 반환하고 마지막엔 `None`을 반"
|
|
"환합니다. `while let`을 통해 반복자의 모든 아이템을 확인할 수 있습니다."
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
#, fuzzy
|
|
msgid "if-let"
|
|
msgstr "if-let"
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid ""
|
|
"Unlike `match`, `if let` does not have to cover all branches. This can make "
|
|
"it more concise than `match`."
|
|
msgstr ""
|
|
"`if let`이 `match`보다 더 간결할 수 있습니다(예: 한가지 브랜치만 흥미로운 경"
|
|
"우). 이와 달리 `match`에서는 모든 브랜치가 처리되어야 합니다."
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid "A common usage is handling `Some` values when working with `Option`."
|
|
msgstr "일반적 사용법은 `Option`을 사용할 때 `Some` 값을 처리하는 것입니다."
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid ""
|
|
"Unlike `match`, `if let` does not support guard clauses for pattern matching."
|
|
msgstr ""
|
|
"`match`와 달리 `if let`은 패턴 일치를 위한 보호 절을 지원하지 않습니다."
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid "let-else"
|
|
msgstr "let-else"
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid ""
|
|
"`if-let`s can pile up, as shown. The `let-else` construct supports "
|
|
"flattening this nested code. Rewrite the awkward version for students, so "
|
|
"they can see the transformation."
|
|
msgstr ""
|
|
"위에서 본 것처럼 `if-let`은 중첩할 수 있습니다. `let-else` 구조는 이 중첩된 "
|
|
"코드의 평면화를 지원합니다. 코드가 어떻게 변화하는지 학생들이 볼 수 있도록 어"
|
|
"색한 버전을 다시 작성하세요."
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid "The rewritten version is:"
|
|
msgstr "다시 작성된 버전은 다음과 같습니다."
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid "while-let"
|
|
msgstr "while-let"
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
msgid ""
|
|
"Point out that the `while let` loop will keep going as long as the value "
|
|
"matches the pattern."
|
|
msgstr "`while let`은 값이 패턴에 매치되는 동안 계속됩니다."
|
|
|
|
#: src/pattern-matching/let-control-flow.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"You could rewrite the `while let` loop as an infinite loop with an if "
|
|
"statement that breaks when there is no value to unwrap for `name.pop()`. The "
|
|
"`while let` provides syntactic sugar for the above scenario."
|
|
msgstr ""
|
|
"`while let` 루프 대신 무한 루프를 사용하고 `iter.next()`가 빈 값을 반환할 때 "
|
|
"루프를 빠져나오도록 작성할수도 있습니다. `while let`은 그러한 경우를 위한 문"
|
|
"법적 편의를 제공합니다."
|
|
|
|
#: src/pattern-matching/exercise.md
|
|
#, fuzzy
|
|
msgid "Let's write a simple recursive evaluator for arithmetic expressions."
|
|
msgstr ""
|
|
"산술식을 위한 간단한 재귀 평가자를 작성해 보겠습니다. 이진 연산을 정의하는 "
|
|
"enum으로 시작합니다."
|
|
|
|
#: src/pattern-matching/exercise.md
|
|
msgid ""
|
|
"The `Box` type here is a smart pointer, and will be covered in detail later "
|
|
"in the course. An expression can be \"boxed\" with `Box::new` as seen in the "
|
|
"tests. To evaluate a boxed expression, use the deref operator (`*`) to "
|
|
"\"unbox\" it: `eval(*boxed_expr)`."
|
|
msgstr ""
|
|
"여기서 `Box` 타입은 스마트 포인터이며 이 과정의 후반부에서 자세히 다룹니다. "
|
|
"테스트에서 볼 수 있듯이 표현식은 `Box::new`를 사용하여 \"박스로 표시\"할 수 "
|
|
"있습니다. 박스로 표시된 표현식을 평가하려면 deref 연산자 (`*`)를 사용하여 "
|
|
"\"박스 표시를 해제\"합니다: `eval(*boxed_expr)`."
|
|
|
|
#: src/pattern-matching/exercise.md
|
|
msgid ""
|
|
"Some expressions cannot be evaluated and will return an error. The standard "
|
|
"[`Result<Value, String>`](https://doc.rust-lang.org/std/result/enum.Result."
|
|
"html) type is an enum that represents either a successful value "
|
|
"(`Ok(Value)`) or an error (`Err(String)`). We will cover this type in detail "
|
|
"later."
|
|
msgstr ""
|
|
"일부 표현식은 평가할 수 없으며 오류를 반환합니다. 표준 [`Result<Value, "
|
|
"String>`](https://doc.rust-lang.org/std/result/enum.Result.html) 타입은 성공"
|
|
"한 값을 나타내거나 (`Ok(Value)`) 메시지와 함께 오류를 나타냅니다 "
|
|
"(`Err(String)`). 나중에 이 Result 타입에 대해서 자세히 살펴보겠습니다."
|
|
|
|
#: src/pattern-matching/exercise.md
|
|
msgid ""
|
|
"Copy and paste the code into the Rust playground, and begin implementing "
|
|
"`eval`. The final product should pass the tests. It may be helpful to use "
|
|
"`todo!()` and get the tests to pass one-by-one. You can also skip a test "
|
|
"temporarily with `#[ignore]`:"
|
|
msgstr ""
|
|
"코드를 복사하여 Rust 플레이그라운드에 붙여넣고 `eval` 구현을 시작합니다. 최"
|
|
"종 생성물은 테스트를 통과해야 합니다. `todo!()`를 사용하고 테스트를 하나씩 통"
|
|
"과하도록 하면 도움이 될 수 있습니다. `#[ignore]`를 사용하여 테스트를 일시적으"
|
|
"로 건너뛸 수도 있습니다."
|
|
|
|
#: src/pattern-matching/exercise.md
|
|
msgid ""
|
|
"If you finish early, try writing a test that results in division by zero or "
|
|
"integer overflow. How could you handle this with `Result` instead of a panic?"
|
|
msgstr ""
|
|
"일찍 완료한 경우 0으로 나누기나 정수 오버플로가 발생하는 테스트를 작성해 보세"
|
|
"요. 패닉 대신 `Result`로 이 문제를 어떻게 처리할 수 있을까요?"
|
|
|
|
#: src/pattern-matching/exercise.md src/pattern-matching/solution.md
|
|
msgid "/// An operation to perform on two subexpressions.\n"
|
|
msgstr "/// 두 개의 하위 표현식에서 실행할 연산입니다.\n"
|
|
|
|
#: src/pattern-matching/exercise.md src/pattern-matching/solution.md
|
|
msgid "/// An expression, in tree form.\n"
|
|
msgstr "/// 트리 형식의 표현식입니다.\n"
|
|
|
|
#: src/pattern-matching/exercise.md src/pattern-matching/solution.md
|
|
msgid "/// An operation on two subexpressions.\n"
|
|
msgstr "/// 두 개의 하위 표현식에 관한 연산입니다.\n"
|
|
|
|
#: src/pattern-matching/exercise.md src/pattern-matching/solution.md
|
|
msgid "/// A literal value\n"
|
|
msgstr "/// 리터럴 값\n"
|
|
|
|
#: src/pattern-matching/exercise.md src/pattern-matching/solution.md
|
|
msgid "\"division by zero\""
|
|
msgstr "\"0으로 나누기\""
|
|
|
|
#: src/pattern-matching/solution.md
|
|
msgid "\"expr: {:?}\""
|
|
msgstr "\"expr: {:?}\""
|
|
|
|
#: src/methods-and-traits.md
|
|
msgid "[Methods](./methods-and-traits/methods.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits.md
|
|
msgid "[Traits](./methods-and-traits/traits.md) (15 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits.md
|
|
msgid "[Deriving](./methods-and-traits/deriving.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits.md
|
|
msgid ""
|
|
"[Exercise: Generic Logger](./methods-and-traits/exercise.md) (20 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid ""
|
|
"Rust allows you to associate functions with your new types. You do this with "
|
|
"an `impl` block:"
|
|
msgstr ""
|
|
"러스트에서 선언된 타입에 대해 `impl`블록에 함수를 선언하여 메서드를 연결 할 "
|
|
"수 있습니다:"
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid "// No receiver, a static method\n"
|
|
msgstr "// 수신자 없음, 정적 메서드입니다.\n"
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid "// Exclusive borrowed read-write access to self\n"
|
|
msgstr "// self에 대한 독점적 빌림 읽기/쓰기 액세스입니다.\n"
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid "// Shared and read-only borrowed access to self\n"
|
|
msgstr "// self에 대한 공유 및 읽기 전용 빌림 액세스입니다.\n"
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid "\"Recorded {} laps for {}:\""
|
|
msgstr "\"랩 타임 {}회, {} 경기:\""
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid "\"Lap {idx}: {lap} sec\""
|
|
msgstr "\"{idx}랩: {lap}초\""
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid "// Exclusive ownership of self\n"
|
|
msgstr "// self의 독점적 소유권\n"
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid "\"Race {} is finished, total lap time: {}\""
|
|
msgstr "\"{} 레이스 종료, 총 랩 시간: {}\""
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid "\"Monaco Grand Prix\""
|
|
msgstr "\"모나코 그랑프리\""
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid "// race.add_lap(42);\n"
|
|
msgstr "// race.add_lap(42);\n"
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The `self` arguments specify the \"receiver\" - the object the method acts "
|
|
"on. There are several common receivers for a method:"
|
|
msgstr ""
|
|
"`&self`는 메서드가 객체를 불변하게 빌려옴을 나타냅니다. 메서드의 리시버는 다"
|
|
"음의 형태들이 가능합니다:"
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid ""
|
|
"`&self`: borrows the object from the caller using a shared and immutable "
|
|
"reference. The object can be used again afterwards."
|
|
msgstr ""
|
|
"`&self`: 호출자로부터 공유가능한 불변 참조 방식으로 객체를 빌려옴을 나타냅니"
|
|
"다. 객체는 메소드 호출 뒤에도 사용될 수 있습니다."
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid ""
|
|
"`&mut self`: borrows the object from the caller using a unique and mutable "
|
|
"reference. The object can be used again afterwards."
|
|
msgstr ""
|
|
"`&mut self`: 호출자로부터 유일한 가변 참조 방식으로 객체를 빌려옴을 나타냅니"
|
|
"다. 객체는 메소드 호출 뒤에도 사용될 수 있습니다."
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid ""
|
|
"`self`: takes ownership of the object and moves it away from the caller. The "
|
|
"method becomes the owner of the object. The object will be dropped "
|
|
"(deallocated) when the method returns, unless its ownership is explicitly "
|
|
"transmitted. Complete ownership does not automatically mean mutability."
|
|
msgstr ""
|
|
"`self`: 호출자로부터 객체의 소유권을 가져오고 객체는 호출자로부터 메소드로 이"
|
|
"동됩니다. 메소드가 객체를 소유하게 되며 따라서 명시적으로 소유권을 다른 곳으"
|
|
"로 전달하지 않는다면 메서드 종료와 함께 객체는 drop(해제)됩니다."
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
#, fuzzy
|
|
msgid "`mut self`: same as above, but the method can mutate the object."
|
|
msgstr ""
|
|
"`mut self`: 위와 동일하지만 메서드가 객체의 소유권을 가지면서 동시에 객체를 "
|
|
"수정할 수도 있습니다. 소유권을 가지는 것이 수정할 수 있음을 의미하는 것은 아"
|
|
"닙니다. "
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid ""
|
|
"No receiver: this becomes a static method on the struct. Typically used to "
|
|
"create constructors which are called `new` by convention."
|
|
msgstr ""
|
|
"리시버 없음: 구조체의 정적 메서드가 됩니다. 주로 생성자를 만들때 사용하게 되"
|
|
"며, 생성자는 흔히 `new`라고 이름붙입니다."
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid "It can be helpful to introduce methods by comparing them to functions."
|
|
msgstr "메서드를 함수와 비교하여 소개하는 것도 도움이 될 수 있습니다."
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid ""
|
|
"Methods are called on an instance of a type (such as a struct or enum), the "
|
|
"first parameter represents the instance as `self`."
|
|
msgstr ""
|
|
"메서드는 구조체나 열거형과 같은 타입의 인스턴스에서 호출 되며, 첫번째 매개변"
|
|
"수(파라메터)는 인스턴스를 `self`로 표기합니다."
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid ""
|
|
"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."
|
|
msgstr ""
|
|
"메서드를 이용하면 receiver 문법을 사용할 수 있고 코드를 좀더 체계적으로 정리"
|
|
"할 수 있습니다. 메서드들이 예측 가능한 위치에 모여 있으니 찾기 쉽습니다."
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid "Point out the use of the keyword `self`, a method receiver."
|
|
msgstr "메서드 receiver인 `self` 키워드 사용을 언급해 주시기 바랍니다."
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid ""
|
|
"Show that it is an abbreviated term for `self: Self` and perhaps show how "
|
|
"the struct name could also be used."
|
|
msgstr ""
|
|
"예제의 경우 `self: &Self`의 줄인 버전임을 알려주고, 구조체의 이름을 직접 사용"
|
|
"하면 어떻게 되는지 보여주는 것도 좋습니다."
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid ""
|
|
"Explain that `Self` is a type alias for the type the `impl` block is in and "
|
|
"can be used elsewhere in the block."
|
|
msgstr ""
|
|
"`impl` 블록 내부에서는 `Self`가 해당 타입의 이름 대용으로 사용될 수 있음을 알"
|
|
"려주세요."
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid ""
|
|
"Note how `self` is used like other structs and dot notation can be used to "
|
|
"refer to individual fields."
|
|
msgstr ""
|
|
"구조체의 필드를 접근할 때 점 표기를 사용하듯이 `self`에 점 표기를 사용하여 개"
|
|
"별 필드들을 접근할 수 있습니다."
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"This might be a good time to demonstrate how the `&self` differs from `self` "
|
|
"by trying to run `finish` twice."
|
|
msgstr ""
|
|
"`say_hello` 함수가 두 번 호출되도록 코드를 수정하여 `&self`와 `self`가 어떻"
|
|
"게 다른지 보여주는 것도 좋습니다."
|
|
|
|
#: src/methods-and-traits/methods.md
|
|
msgid ""
|
|
"Beyond variants on `self`, there are also [special wrapper types](https://"
|
|
"doc.rust-lang.org/reference/special-types-and-traits.html) allowed to be "
|
|
"receiver types, such as `Box<Self>`."
|
|
msgstr ""
|
|
"`self`를 사용하는 이같은 변형들 외에도 `Box<Self>`와 같이 리시버 타입으로 허"
|
|
"용되는 [특별한 래퍼 타입](https://doc.rust-lang.org/reference/special-types-"
|
|
"and-traits.html)이 있습니다."
|
|
|
|
#: src/methods-and-traits/traits.md
|
|
msgid ""
|
|
"Rust lets you abstract over types with traits. They're similar to interfaces:"
|
|
msgstr "트레잇은 타입을 추상화 하는데 사용됩니다. 인터페이스와 비슷합니다:"
|
|
|
|
#: src/methods-and-traits/traits.md
|
|
#, fuzzy
|
|
msgid "/// Return a sentence from this pet.\n"
|
|
msgstr "// 이 모듈에서 타입을 다시 내보냅니다.\n"
|
|
|
|
#: src/methods-and-traits/traits.md
|
|
#, fuzzy
|
|
msgid "/// Print a string to the terminal greeting this pet.\n"
|
|
msgstr "/// 인사말을 표준 출력으로 인쇄합니다.\n"
|
|
|
|
#: src/methods-and-traits/traits.md
|
|
msgid ""
|
|
"A trait defines a number of methods that types must have in order to "
|
|
"implement the trait."
|
|
msgstr ""
|
|
"트레잇은 해당 트레잇을 구현하기 위해 타입이 가져야 하는 여러 메서드를 정의합"
|
|
"니다."
|
|
|
|
#: src/methods-and-traits/traits.md
|
|
msgid ""
|
|
"In the \"Generics\" segment, next, we will see how to build functionality "
|
|
"that is generic over all types implementing a trait."
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/traits/implementing.md
|
|
#, fuzzy
|
|
msgid "Implementing Traits"
|
|
msgstr "안전하지 않은 트레잇 구현하기"
|
|
|
|
#: src/methods-and-traits/traits/implementing.md
|
|
msgid "\"Oh you're a cutie! What's your name? {}\""
|
|
msgstr "\"오, 귀여워! 이름이 뭐야? {}\""
|
|
|
|
#: src/methods-and-traits/traits/implementing.md
|
|
#: src/smart-pointers/trait-objects.md
|
|
msgid "\"Woof, my name is {}!\""
|
|
msgstr "\"멍멍, 제 이름은 {}입니다.\""
|
|
|
|
#: src/methods-and-traits/traits/implementing.md
|
|
#: src/smart-pointers/trait-objects.md
|
|
msgid "\"Fido\""
|
|
msgstr "\"Fido\""
|
|
|
|
#: src/methods-and-traits/traits/implementing.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"To implement `Trait` for `Type`, you use an `impl Trait for Type { .. }` "
|
|
"block."
|
|
msgstr "트레잇은 `impl <trait> for <type> { .. }` 블록에서 구현됩니다."
|
|
|
|
#: src/methods-and-traits/traits/implementing.md
|
|
msgid ""
|
|
"Unlike Go interfaces, just having matching methods is not enough: a `Cat` "
|
|
"type with a `talk()` method would not automatically satisfy `Pet` unless it "
|
|
"is in an `impl Pet` block."
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/traits/implementing.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Traits may provide default implementations of some methods. Default "
|
|
"implementations can rely on all the methods of the trait. In this case, "
|
|
"`greet` is provided, and relies on `talk`."
|
|
msgstr ""
|
|
"트레잇은, 그 트레잇이 정의된 위치에서 직접 구현되는 디폴트 메서드와, 거기에서"
|
|
"는 선언만 존재하고 그 트레잇을 구현하는 타입에서 구현해야 하는, 두 종류의 메"
|
|
"서드를 가질 수 있습니다. 디폴트 메서드를 구현할 때에는, 두 종류의 메서드 모"
|
|
"두 사용(호출)할 수 있습니다."
|
|
|
|
#: src/methods-and-traits/traits/supertraits.md
|
|
msgid ""
|
|
"A trait can require that types implementing it also implement other traits, "
|
|
"called _supertraits_. Here, any type implementing `Pet` must implement "
|
|
"`Animal`."
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/traits/supertraits.md
|
|
#: src/async/control-flow/select.md
|
|
msgid "\"Rex\""
|
|
msgstr "\"렉스\""
|
|
|
|
#: src/methods-and-traits/traits/supertraits.md
|
|
#, fuzzy
|
|
msgid "\"{} has {} legs\""
|
|
msgstr "\"{}은(는) {}세입니다.\""
|
|
|
|
#: src/methods-and-traits/traits/supertraits.md
|
|
msgid ""
|
|
"This is sometimes called \"trait inheritance\" but students should not "
|
|
"expect this to behave like OO inheritance. It just specifies an additional "
|
|
"requirement on implementations of a trait."
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/traits/associated-types.md
|
|
msgid ""
|
|
"Associated types are placeholder types which are supplied by the trait "
|
|
"implementation."
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/traits/associated-types.md
|
|
msgid ""
|
|
"Associated types are sometimes also called \"output types\". The key "
|
|
"observation is that the implementer, not the caller, chooses this type."
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/traits/associated-types.md
|
|
msgid ""
|
|
"Many standard library traits have associated types, including arithmetic "
|
|
"operators and `Iterator`."
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/deriving.md
|
|
msgid ""
|
|
"Supported traits can be automatically implemented for your custom types, as "
|
|
"follows:"
|
|
msgstr "지원되는 트레잇은 다음과 같이 맞춤 타입에 자동으로 구현할 수 있습니다."
|
|
|
|
#: src/methods-and-traits/deriving.md
|
|
msgid "// Default trait adds `default` constructor.\n"
|
|
msgstr "// 기본 트레잇은 `default` 생성자를 추가합니다.\n"
|
|
|
|
#: src/methods-and-traits/deriving.md
|
|
msgid "// Clone trait adds `clone` method.\n"
|
|
msgstr "// Clone 트레잇은 `clone` 메서드를 추가합니다.\n"
|
|
|
|
#: src/methods-and-traits/deriving.md
|
|
msgid "\"EldurScrollz\""
|
|
msgstr "\"EldurScrollz\""
|
|
|
|
#: src/methods-and-traits/deriving.md
|
|
msgid "// Debug trait adds support for printing with `{:?}`.\n"
|
|
msgstr "// Debug 트레잇은 `{:?}` 표현을 사용한 출력을 지원합니다.\n"
|
|
|
|
#: src/methods-and-traits/deriving.md
|
|
msgid "\"{:?} vs. {:?}\""
|
|
msgstr "\"{:?} 대 {:?}\""
|
|
|
|
#: src/methods-and-traits/deriving.md
|
|
msgid ""
|
|
"Derivation is implemented with macros, and many crates provide useful derive "
|
|
"macros to add useful functionality. For example, `serde` can derive "
|
|
"serialization support for a struct using `#[derive(Serialize)]`."
|
|
msgstr ""
|
|
"상속은 매크로를 사용하여 구현되며 많은 크레이트가 유용한 상속 매크로를 제공하"
|
|
"여 유용한 기능을 추가합니다. 예를 들어 `serde`는 `#[derive(Serialize)]`를 사"
|
|
"용하여 구조체의 직렬화 지원을 상속할 수 있습니다."
|
|
|
|
#: src/methods-and-traits/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Logger Trait"
|
|
msgstr "연습문제: 카운터"
|
|
|
|
#: src/methods-and-traits/exercise.md
|
|
msgid ""
|
|
"Let's design a simple logging utility, using a trait `Logger` with a `log` "
|
|
"method. Code which might log its progress can then take an `&impl Logger`. "
|
|
"In testing, this might put messages in the test logfile, while in a "
|
|
"production build it would send messages to a log server."
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/exercise.md
|
|
msgid ""
|
|
"However, the `StderrLogger` given below logs all messages, regardless of "
|
|
"verbosity. Your task is to write a `VerbosityFilter` type that will ignore "
|
|
"messages above a maximum verbosity."
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/exercise.md
|
|
msgid ""
|
|
"This is a common pattern: a struct wrapping a trait implementation and "
|
|
"implementing that same trait, adding behavior in the process. What other "
|
|
"kinds of wrappers might be useful in a logging utility?"
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/exercise.md src/methods-and-traits/solution.md
|
|
msgid "/// Log a message at the given verbosity level.\n"
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/exercise.md src/methods-and-traits/solution.md
|
|
msgid "\"verbosity={verbosity}: {message}\""
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/exercise.md src/methods-and-traits/solution.md
|
|
msgid "\"FYI\""
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/exercise.md src/methods-and-traits/solution.md
|
|
#, fuzzy
|
|
msgid "\"Uhoh\""
|
|
msgstr "\"이런\""
|
|
|
|
#: src/methods-and-traits/exercise.md
|
|
msgid "// TODO: Define and implement `VerbosityFilter`.\n"
|
|
msgstr ""
|
|
|
|
#: src/methods-and-traits/solution.md
|
|
msgid "/// Only log messages up to the given verbosity level.\n"
|
|
msgstr ""
|
|
|
|
#: src/generics.md
|
|
msgid "[Generic Functions](./generics/generic-functions.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/generics.md
|
|
msgid "[Generic Data Types](./generics/generic-data.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/generics.md
|
|
msgid "[Trait Bounds](./generics/trait-bounds.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/generics.md
|
|
msgid "[impl Trait](./generics/impl-trait.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/generics.md
|
|
msgid "[Exercise: Generic min](./generics/exercise.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/generics/generic-functions.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Rust supports generics, which lets you abstract algorithms or data "
|
|
"structures (such as sorting or a binary tree) over the types used or stored."
|
|
msgstr ""
|
|
"러스트는 제네릭을 지원합니다. 이를 이용하면 알고리즘(정렬과 같은)이나 데이터 "
|
|
"구조(이진 트리 같은)를 추상화 하여 특정 타입에 의존하지 않도록 할 수 있습니"
|
|
"다."
|
|
|
|
#: src/generics/generic-functions.md
|
|
msgid "/// Pick `even` or `odd` depending on the value of `n`.\n"
|
|
msgstr "/// `n` 값에 따라 `even` 또는 `odd`를 선택합니다.\n"
|
|
|
|
#: src/generics/generic-functions.md
|
|
msgid "\"picked a number: {:?}\""
|
|
msgstr "\"선택한 숫자: {:?}\""
|
|
|
|
#: src/generics/generic-functions.md
|
|
msgid "\"picked a tuple: {:?}\""
|
|
msgstr "\"선택한 튜플: {:?}\""
|
|
|
|
#: src/generics/generic-functions.md
|
|
msgid "\"dog\""
|
|
msgstr "\"개\""
|
|
|
|
#: src/generics/generic-functions.md
|
|
msgid "\"cat\""
|
|
msgstr "\"고양이\""
|
|
|
|
#: src/generics/generic-functions.md
|
|
msgid ""
|
|
"Rust infers a type for T based on the types of the arguments and return "
|
|
"value."
|
|
msgstr "Rust는 인수 및 반환 값의 타입을 기반으로 T의 타입을 추론합니다."
|
|
|
|
#: src/generics/generic-functions.md
|
|
msgid ""
|
|
"This is similar to C++ templates, but Rust partially compiles the generic "
|
|
"function immediately, so that function must be valid for all types matching "
|
|
"the constraints. For example, try modifying `pick` to return `even + odd` if "
|
|
"`n == 0`. Even if only the `pick` instantiation with integers is used, Rust "
|
|
"still considers it invalid. C++ would let you do this."
|
|
msgstr ""
|
|
"이는 C++ 템플릿과 비슷하지만, Rust는 제네릭 함수를 즉시 부분적으로 컴파일하므"
|
|
"로 제약 조건과 일치하는 모든 타입에 함수가 유효해야 합니다. 예를 들어 `n == "
|
|
"0`인 경우 `even + odd`를 반환하도록 `pick`을 수정하세요. 정수가 포함된 "
|
|
"`pick` 인스턴스화만 사용되더라도 Rust는 이를 유효하지 않은 것으로 간주합니"
|
|
"다. C++에서는 이를 허용합니다."
|
|
|
|
#: src/generics/generic-functions.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Generic code is turned into non-generic code based on the call sites. This "
|
|
"is a zero-cost abstraction: you get exactly the same result as if you had "
|
|
"hand-coded the data structures without the abstraction."
|
|
msgstr ""
|
|
"이것이 바로 비용이 들지 않는 (zero-cost) 추상화 입니다: 러스트의 제네릭은 추"
|
|
"상화를 거치지 않고 직접 구체적인 타입을 써서 코딩한 것과 정확히 동일한 결과"
|
|
"를 보여줍니다."
|
|
|
|
#: src/generics/generic-data.md
|
|
msgid "You can use generics to abstract over the concrete field type:"
|
|
msgstr "제네릭을 사용하여 필드의 타입을 추상화 할 수 있습니다:"
|
|
|
|
#: src/generics/generic-data.md
|
|
msgid "// fn set_x(&mut self, x: T)\n"
|
|
msgstr "// fn set_x(&mut self, x: T)\n"
|
|
|
|
#: src/generics/generic-data.md
|
|
msgid "\"{integer:?} and {float:?}\""
|
|
msgstr "\"{integer:?} 및 {float:?}\""
|
|
|
|
#: src/generics/generic-data.md
|
|
msgid "\"coords: {:?}\""
|
|
msgstr "\"좌표: {:?}\""
|
|
|
|
#: src/generics/generic-data.md
|
|
msgid ""
|
|
"_Q:_ Why `T` is specified twice in `impl<T> Point<T> {}`? Isn't that "
|
|
"redundant?"
|
|
msgstr "_질문:_ `impl<T> Point<T> {}`에서 `T`가 왜 두 번 사용됩니까?"
|
|
|
|
#: src/generics/generic-data.md
|
|
msgid ""
|
|
"This is because it is a generic implementation section for generic type. "
|
|
"They are independently generic."
|
|
msgstr ""
|
|
"제네릭 타입에 대한 제네릭 구현 이기 때문입니다. 이 두 제네릭은 서로 독립적입"
|
|
"니다."
|
|
|
|
#: src/generics/generic-data.md
|
|
msgid "It means these methods are defined for any `T`."
|
|
msgstr ""
|
|
"이는 임의의 모든 `T`에 대해서 이 메소드들이 정의된다는 것을 의미합니다."
|
|
|
|
#: src/generics/generic-data.md
|
|
#, fuzzy
|
|
msgid "It is possible to write `impl Point<u32> { .. }`."
|
|
msgstr "`impl Point<u32> { .. }`와 같이 작성하는 것도 가능합니다. "
|
|
|
|
#: src/generics/generic-data.md
|
|
msgid ""
|
|
"`Point` is still generic and you can use `Point<f64>`, but methods in this "
|
|
"block will only be available for `Point<u32>`."
|
|
msgstr ""
|
|
"`Point`는 여전히 제네릭이며 `Point<f64>`를 사용할 수도 있지만 이 블록의 메서"
|
|
"드는 `Point<u32>`만 쓸 수 있습니다."
|
|
|
|
#: src/generics/generic-data.md
|
|
msgid ""
|
|
"Try declaring a new variable `let p = Point { x: 5, y: 10.0 };`. Update the "
|
|
"code to allow points that have elements of different types, by using two "
|
|
"type variables, e.g., `T` and `U`."
|
|
msgstr ""
|
|
"새 변수 `let p = Point { x: 5, y: 10.0 };`를 선언해 보세요. 다음과 같은 두 개"
|
|
"의 타입 변수를 사용하여 다른 타입의 요소를 가진 포인트를 허용하도록 코드를 업"
|
|
"데이트합니다. `T`와 `U`"
|
|
|
|
#: src/generics/generic-traits.md
|
|
msgid ""
|
|
"Traits can also be generic, just like types and functions. A trait's "
|
|
"parameters get concrete types when it is used."
|
|
msgstr ""
|
|
|
|
#: src/generics/generic-traits.md
|
|
msgid "\"Converted from integer: {from}\""
|
|
msgstr ""
|
|
|
|
#: src/generics/generic-traits.md
|
|
msgid "\"Converted from bool: {from}\""
|
|
msgstr ""
|
|
|
|
#: src/generics/generic-traits.md
|
|
msgid "\"{from_int:?}, {from_bool:?}\""
|
|
msgstr ""
|
|
|
|
#: src/generics/generic-traits.md
|
|
msgid ""
|
|
"The `From` trait will be covered later in the course, but its [definition in "
|
|
"the `std` docs](https://doc.rust-lang.org/std/convert/trait.From.html) is "
|
|
"simple."
|
|
msgstr ""
|
|
|
|
#: src/generics/generic-traits.md
|
|
msgid ""
|
|
"Implementations of the trait do not need to cover all possible type "
|
|
"parameters. Here, `Foo::From(\"hello\")` would not compile because there is "
|
|
"no `From<&str>` implementation for `Foo`."
|
|
msgstr ""
|
|
|
|
#: src/generics/generic-traits.md
|
|
msgid ""
|
|
"Generic traits take types as \"input\", while associated types are a kind of "
|
|
"\"output type. A trait can have multiple implementations for different input "
|
|
"types."
|
|
msgstr ""
|
|
|
|
#: src/generics/generic-traits.md
|
|
msgid ""
|
|
"In fact, Rust requires that at most one implementation of a trait match for "
|
|
"any type T. Unlike some other languages, Rust has no heuristic for choosing "
|
|
"the \"most specific\" match. There is work on adding this support, called "
|
|
"[specialization](https://rust-lang.github.io/rfcs/1210-impl-specialization."
|
|
"html)."
|
|
msgstr ""
|
|
|
|
#: src/generics/trait-bounds.md
|
|
msgid ""
|
|
"When working with generics, you often want to require the types to implement "
|
|
"some trait, so that you can call this trait's methods."
|
|
msgstr ""
|
|
"제네릭을 이용하다 보면 타입이 어떤 트레잇을 구현하고 있어야 하는 경우가 있습"
|
|
"니다. 그래야 그 트레잇의 메서드를 호출할 수 있기 때문입니다."
|
|
|
|
#: src/generics/trait-bounds.md
|
|
msgid "You can do this with `T: Trait` or `impl Trait`:"
|
|
msgstr "`T: Trait` 혹은 `impl Trait`를 사용하면 됩니다:"
|
|
|
|
#: src/generics/trait-bounds.md
|
|
msgid "// struct NotClonable;\n"
|
|
msgstr "// struct NotClonable;\n"
|
|
|
|
#: src/generics/trait-bounds.md
|
|
msgid "\"{pair:?}\""
|
|
msgstr "\"{pair:?}\""
|
|
|
|
#: src/generics/trait-bounds.md
|
|
msgid "Try making a `NonClonable` and passing it to `duplicate`."
|
|
msgstr "`NonClonable`을 만들어 `duplicate`에 전달해 보세요."
|
|
|
|
#: src/generics/trait-bounds.md
|
|
msgid "When multiple traits are necessary, use `+` to join them."
|
|
msgstr "여러 트레잇이 필요한 경우 `+`를 사용하여 트레잇을 결합합니다."
|
|
|
|
#: src/generics/trait-bounds.md
|
|
msgid "Show a `where` clause, students will encounter it when reading code."
|
|
msgstr ""
|
|
"`where` 문법을 사용할 수도 있습니다. 수강생들도 코드를 읽다가 그 문법을 마주"
|
|
"할 수 있습니다."
|
|
|
|
#: src/generics/trait-bounds.md
|
|
msgid "It declutters the function signature if you have many parameters."
|
|
msgstr ""
|
|
"이를 이용하면 타입 파라메터가 많은 경우 함수 시그니처를 간결하게 정리하는 데 "
|
|
"도움이 됩니다."
|
|
|
|
#: src/generics/trait-bounds.md
|
|
msgid "It has additional features making it more powerful."
|
|
msgstr "좀 더 강력한 추가 기능도 제공합니다."
|
|
|
|
#: src/generics/trait-bounds.md
|
|
msgid ""
|
|
"If someone asks, the extra feature is that the type on the left of \":\" can "
|
|
"be arbitrary, like `Option<T>`."
|
|
msgstr "`:` 왼쪽에 임의의 타입(예를 들어 `Option<T>`)을 사용할 수 있습니다."
|
|
|
|
#: src/generics/trait-bounds.md
|
|
msgid ""
|
|
"Note that Rust does not (yet) support specialization. For example, given the "
|
|
"original `duplicate`, it is invalid to add a specialized `duplicate(a: u32)`."
|
|
msgstr ""
|
|
"Rust는 아직 특수화를 지원하지 않습니다. 예를 들어 원본 `duplicate`가 있는 경"
|
|
"우 특수 `duplicate(a: u32)`를 추가하는 것은 유효하지 않습니다."
|
|
|
|
#: src/generics/impl-trait.md
|
|
msgid ""
|
|
"Similar to trait bounds, an `impl Trait` syntax can be used in function "
|
|
"arguments and return values:"
|
|
msgstr ""
|
|
"트레잇 바운드와 유사하게 `impl Trait` 문법은 함수의 인자와 반환값에도 적용 가"
|
|
"능합니다:"
|
|
|
|
#: src/generics/impl-trait.md
|
|
msgid ""
|
|
"// Syntactic sugar for:\n"
|
|
"// fn add_42_millions<T: Into<i32>>(x: T) -> i32 {\n"
|
|
msgstr ""
|
|
"// 다음과 동일합니다:\n"
|
|
"// fn add_42_millions<T: Into<i32>>(x: T) -> i32 {\n"
|
|
|
|
#: src/generics/impl-trait.md
|
|
msgid "\"{many}\""
|
|
msgstr "\"{many}\""
|
|
|
|
#: src/generics/impl-trait.md
|
|
msgid "\"{many_more}\""
|
|
msgstr "\"{many_more}\""
|
|
|
|
#: src/generics/impl-trait.md
|
|
msgid "\"debuggable: {debuggable:?}\""
|
|
msgstr "\"디버그 가능: {debuggable:?}\""
|
|
|
|
#: src/generics/impl-trait.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`impl Trait` allows you to work with types which you cannot name. The "
|
|
"meaning of `impl Trait` is a bit different in the different positions."
|
|
msgstr ""
|
|
"`impl Trait`는 이름을 지을 수 없는 타입을 다룰 수 있게 해줍니다. `impl Trait`"
|
|
"의 의미는 다른 위치에서 약간 다릅니다."
|
|
|
|
#: src/generics/impl-trait.md
|
|
msgid ""
|
|
"For a parameter, `impl Trait` is like an anonymous generic parameter with a "
|
|
"trait bound."
|
|
msgstr ""
|
|
"함수 인자의 타입으로 사용되었을 경우에는 `impl Trait`는 트레잇 경계가 있는 익"
|
|
"명의 제네릭 타입을 의미합니다."
|
|
|
|
#: src/generics/impl-trait.md
|
|
msgid ""
|
|
"For a return type, it means that the return type is some concrete type that "
|
|
"implements the trait, without naming the type. This can be useful when you "
|
|
"don't want to expose the concrete type in a public API."
|
|
msgstr ""
|
|
"리턴 타입으로 사용되었을 경우에는, 그 트레잇을 구현하는 구체적인 타입인데, 타"
|
|
"입 이름을 프로그래머가 짓지 않았다는 것을 의미합니다. 이는 그 구체적인 타입 "
|
|
"이름을 API로 공개하고 싶지 않은 경우에 유용합니다."
|
|
|
|
#: src/generics/impl-trait.md
|
|
msgid ""
|
|
"Inference is hard in return position. A function returning `impl Foo` picks "
|
|
"the concrete type it returns, without writing it out in the source. A "
|
|
"function returning a generic type like `collect<B>() -> B` can return any "
|
|
"type satisfying `B`, and the caller may need to choose one, such as with "
|
|
"`let x: Vec<_> = foo.collect()` or with the turbofish, `foo.collect::"
|
|
"<Vec<_>>()`."
|
|
msgstr ""
|
|
"함수가 리턴되는 곳에서의 타입 추론은 어렵습니다. 어떤 함수의 리턴 타입이 "
|
|
"`impl Foo`로 선언되어 있을 경우, 그 함수가 실제로 리턴하는 타입은 소스 코드 "
|
|
"상 어디에도 나타나 있지 않습니다. `collect<B<() -> B`와 같이 제너릭 타입을 리"
|
|
"턴하는 함수는 `B`를 만족하는 어떤 타입도 리턴할 수 있습니다. 이 경우, 호출하"
|
|
"는 측에서는 `let x: Vec<_> = foo.collect()`나 터보피시 문법을 써서 `foo."
|
|
"collect::<Vec<_>>()`와 같이 리턴 타입을 명시적으로 써 주어야 할 수도 있습니"
|
|
"다."
|
|
|
|
#: src/generics/impl-trait.md
|
|
msgid ""
|
|
"What is the type of `debuggable`? Try `let debuggable: () = ..` to see what "
|
|
"the error message shows."
|
|
msgstr ""
|
|
"`debuggable` 타입은 무엇인가요? `let debuggable: () = ..`을 시도하여 오류 메"
|
|
"시지가 어떻게 표시되는지 확인합니다."
|
|
|
|
#: src/generics/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"In this short exercise, you will implement a generic `min` function that "
|
|
"determines the minimum of two values, using the [`Ord`](https://doc.rust-"
|
|
"lang.org/stable/std/cmp/trait.Ord.html) trait."
|
|
msgstr ""
|
|
"이 짧은 연습에서는 `LessThan` 트레잇을 사용하여 두 값의 최솟값을 결정하는 제"
|
|
"네릭 `min` 함수를 구현합니다."
|
|
|
|
#: src/generics/exercise.md
|
|
msgid "// TODO: implement the `min` function used in `main`.\n"
|
|
msgstr "// TODO: `main`에 사용되는 `min` 함수를 구현합니다.\n"
|
|
|
|
#: src/generics/exercise.md src/generics/solution.md
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "'z'"
|
|
msgstr "'z'"
|
|
|
|
#: src/generics/exercise.md src/generics/solution.md
|
|
#, fuzzy
|
|
msgid "'7'"
|
|
msgstr "'x'"
|
|
|
|
#: src/generics/exercise.md src/generics/solution.md
|
|
#, fuzzy
|
|
msgid "'1'"
|
|
msgstr "'x'"
|
|
|
|
#: src/generics/exercise.md src/generics/solution.md
|
|
msgid "\"goodbye\""
|
|
msgstr ""
|
|
|
|
#: src/generics/exercise.md src/generics/solution.md
|
|
msgid "\"bat\""
|
|
msgstr ""
|
|
|
|
#: src/generics/exercise.md src/generics/solution.md
|
|
msgid "\"armadillo\""
|
|
msgstr ""
|
|
|
|
#: src/generics/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Show students the [`Ord`](https://doc.rust-lang.org/stable/std/cmp/trait.Ord."
|
|
"html) trait and [`Ordering`](https://doc.rust-lang.org/stable/std/cmp/enum."
|
|
"Ordering.html) enum."
|
|
msgstr ""
|
|
"[`OsStr`](https://doc.rust-lang.org/std/ffi/struct.OsStr.html)와 [`OsString`]"
|
|
"(https://doc.rust-lang.org/std/ffi/struct.OsString.html)"
|
|
|
|
#: src/welcome-day-2-afternoon.md
|
|
msgid "[Standard Library Types](./std-types.md) (1 hour and 20 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-2-afternoon.md
|
|
msgid "[Standard Library Traits](./std-traits.md) (1 hour and 40 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-2-afternoon.md
|
|
msgid ""
|
|
"Including 10 minute breaks, this session should take about 3 hours and 10 "
|
|
"minutes"
|
|
msgstr ""
|
|
|
|
#: src/std-types.md
|
|
msgid "[Standard Library](./std-types/std.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-types.md
|
|
msgid "[Documentation](./std-types/docs.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-types.md
|
|
msgid "[Option](./std-types/option.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-types.md
|
|
msgid "[Result](./std-types/result.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-types.md
|
|
msgid "[String](./std-types/string.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-types.md
|
|
msgid "[Vec](./std-types/vec.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-types.md
|
|
msgid "[HashMap](./std-types/hashmap.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-types.md
|
|
msgid "[Exercise: Counter](./std-types/exercise.md) (20 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-types.md
|
|
msgid "This segment should take about 1 hour and 20 minutes"
|
|
msgstr ""
|
|
|
|
#: src/std-types.md
|
|
msgid ""
|
|
"For each of the slides in this section, spend some time reviewing the "
|
|
"documentation pages, highlighting some of the more common methods."
|
|
msgstr ""
|
|
"이 섹션의 각 슬라이드에서는 문서 페이지를 검토하고 보다 일반적인 메서드를 중"
|
|
"점적으로 살펴봅니다."
|
|
|
|
#: src/std-types/std.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Rust comes with a standard library which helps establish a set of common "
|
|
"types used by Rust libraries and programs. This way, two libraries can work "
|
|
"together smoothly because they both use the same `String` type."
|
|
msgstr ""
|
|
"러스트에서 제공하는 표준 라이브러리는 러스트로 라이브러리나 프로그램을 작성"
|
|
"할 때 공통적으로 사용할 수 있는 여러 타입들을 포함하고 있습니다. 이를 통해 서"
|
|
"로 다른 두 라이브러리라 하더라도 함께 사용하는데 큰 어려움이 없게 됩니다. 예"
|
|
"를 들면 두 라이브러리 모두 같은 `String` 타입을 사용하기 때문입니다."
|
|
|
|
#: src/std-types/std.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"In fact, Rust contains several layers of the Standard Library: `core`, "
|
|
"`alloc` and `std`."
|
|
msgstr ""
|
|
"사실, 러스트의 표준 라이브러리는 `core`, `alloc`, `std`와 같이 계층(layer)으"
|
|
"로 나눠집니다. "
|
|
|
|
#: src/std-types/std.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`core` includes the most basic types and functions that don't depend on "
|
|
"`libc`, allocator or even the presence of an operating system."
|
|
msgstr ""
|
|
"`core`는 `libc`나 할당자(allocator), 심지어 OS에도 의존하지 않는 가장 기본적"
|
|
"인 함수와 타입을 포함합니다. "
|
|
|
|
#: src/std-types/std.md
|
|
msgid ""
|
|
"`alloc` includes types which require a global heap allocator, such as `Vec`, "
|
|
"`Box` and `Arc`."
|
|
msgstr ""
|
|
"`alloc`은 `Vec`, `Box`, `Arc`와 같이 전역 힙 할당이 필요한 타입을 포함합니다."
|
|
|
|
#: src/std-types/std.md
|
|
msgid ""
|
|
"Embedded Rust applications often only use `core`, and sometimes `alloc`."
|
|
msgstr ""
|
|
"임베디드 러스트 응용프로그램은 주로 `core`만 사용하거나 가끔 `alloc`을 함께 "
|
|
"사용합니다."
|
|
|
|
#: src/std-types/docs.md
|
|
#, fuzzy
|
|
msgid "Rust comes with extensive documentation. For example:"
|
|
msgstr ""
|
|
"Rust에는 언어와 표준 라이브러리에 관한 광범위한 문서가 함께 제공됩니다."
|
|
|
|
#: src/std-types/docs.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"All of the details about [loops](https://doc.rust-lang.org/stable/reference/"
|
|
"expressions/loop-expr.html)."
|
|
msgstr ""
|
|
"루프를 조기에 종료하려면 [`break`](https://doc.rust-lang.org/reference/"
|
|
"expressions/loop-expr.html#break-expressions)를 사용합니다,"
|
|
|
|
#: src/std-types/docs.md
|
|
msgid ""
|
|
"Primitive types like [`u8`](https://doc.rust-lang.org/stable/std/primitive."
|
|
"u8.html)."
|
|
msgstr ""
|
|
"[`u8`](https://doc.rust-lang.org/stable/std/primitive.u8.html)과 같은 기본 타"
|
|
"입"
|
|
|
|
#: src/std-types/docs.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Standard library types like [`Option`](https://doc.rust-lang.org/stable/std/"
|
|
"option/enum.Option.html) or [`BinaryHeap`](https://doc.rust-lang.org/stable/"
|
|
"std/collections/struct.BinaryHeap.html)."
|
|
msgstr ""
|
|
"[`str`](https://doc.rust-lang.org/std/primitive.str.html)과 [`String`]"
|
|
"(https://doc.rust-lang.org/std/string/struct.String.html)"
|
|
|
|
#: src/std-types/docs.md
|
|
msgid "In fact, you can document your own code:"
|
|
msgstr "사실 자체 코드를 문서화할 수 있습니다."
|
|
|
|
#: src/std-types/docs.md
|
|
msgid ""
|
|
"/// Determine whether the first argument is divisible by the second "
|
|
"argument.\n"
|
|
"///\n"
|
|
"/// If the second argument is zero, the result is false.\n"
|
|
msgstr ""
|
|
"/// 첫 번째 인수를 두 번째 인수로 나눌 수 있는지 확인합니다.\n"
|
|
"///\n"
|
|
"/// 두 번째 인수가 0이면 결과는 false입니다.\n"
|
|
|
|
#: src/std-types/docs.md
|
|
msgid ""
|
|
"The contents are treated as Markdown. All published Rust library crates are "
|
|
"automatically documented at [`docs.rs`](https://docs.rs) using the [rustdoc]"
|
|
"(https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html) tool. It is "
|
|
"idiomatic to document all public items in an API using this pattern."
|
|
msgstr ""
|
|
"콘텐츠는 마크다운으로 처리됩니다. 게시된 모든 Rust 라이브러리 크레이트는 "
|
|
"[rustdoc](https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html) 도구를 사용"
|
|
"하여 [`docs.rs`](https://docs.rs)에 자동으로 문서화됩니다. 일반적으로 API의 "
|
|
"모든 공개 항목은 이 패턴을 사용하여 문서화됩니다."
|
|
|
|
#: src/std-types/docs.md
|
|
msgid ""
|
|
"To document an item from inside the item (such as inside a module), use `//!"
|
|
"` or `/*! .. */`, called \"inner doc comments\":"
|
|
msgstr ""
|
|
"항목 내부(예: 모듈 내부)의 항목을 문서화하려면 '내부 문서 주석'이라고 하는 "
|
|
"`//!` 혹은 `/*! .. */`를 사용하세요."
|
|
|
|
#: src/std-types/docs.md
|
|
msgid ""
|
|
"//! This module contains functionality relating to divisibility of "
|
|
"integers.\n"
|
|
msgstr ""
|
|
"//! 이 모듈에는 정수의 분할 가능성과 관련된 기능이 포함되어 있습니다.\n"
|
|
|
|
#: src/std-types/docs.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Show students the generated docs for the `rand` crate at <https://docs.rs/"
|
|
"rand>."
|
|
msgstr ""
|
|
"[`docs.rs/rand`](https://docs.rs/rand)에서 `rand` 크레이트용으로 생성된 문서"
|
|
"를 보여줍니다."
|
|
|
|
#: src/std-types/option.md
|
|
#, fuzzy
|
|
msgid "Option"
|
|
msgstr "예외"
|
|
|
|
#: src/std-types/option.md
|
|
msgid ""
|
|
"We have already seen some use of `Option<T>`. It stores either a value of "
|
|
"type `T` or nothing. For example, [`String::find`](https://doc.rust-lang.org/"
|
|
"stable/std/string/struct.String.html#method.find) returns an `Option<usize>`."
|
|
msgstr ""
|
|
"`Option<T>`의 일부 사용법은 이미 살펴봤습니다. 'T' 타입의 값을 저장하거나 아"
|
|
"무것도 저장하지 않습니다. 예를 들어 [`String::find`](https://doc.rust-lang."
|
|
"org/stable/std/string/struct.String.html#method.find)는 `Option<usize>`를 반"
|
|
"환합니다."
|
|
|
|
#: src/std-types/option.md
|
|
msgid "\"Löwe 老虎 Léopard Gepardi\""
|
|
msgstr "\"Löwe 老虎 Léopard Gepardi\""
|
|
|
|
#: src/std-types/option.md
|
|
msgid "'é'"
|
|
msgstr "'é'"
|
|
|
|
#: src/std-types/option.md
|
|
msgid "\"find returned {position:?}\""
|
|
msgstr "\"find의 반환값 {position:?}\""
|
|
|
|
#: src/std-types/option.md
|
|
msgid "'Z'"
|
|
msgstr "'Z'"
|
|
|
|
#: src/std-types/option.md
|
|
msgid "\"Character not found\""
|
|
msgstr "\"문자를 찾을 수 없음\""
|
|
|
|
#: src/std-types/option.md
|
|
#, fuzzy
|
|
msgid "`Option` is widely used, not just in the standard library."
|
|
msgstr ""
|
|
"`Option`과 `Result`는 표준 라이브러리뿐만아니라 매우 광범위하게 사용되는 타입"
|
|
"입니다."
|
|
|
|
#: src/std-types/option.md
|
|
msgid ""
|
|
"`unwrap` will return the value in an `Option`, or panic. `expect` is similar "
|
|
"but takes an error message."
|
|
msgstr ""
|
|
"`unwrap`은 `Option`의 값을 반환하거나 패닉을 반환합니다. `expect`도 비슷하지"
|
|
"만 오류 메시지가 표시됩니다."
|
|
|
|
#: src/std-types/option.md
|
|
msgid ""
|
|
"You can panic on None, but you can't \"accidentally\" forget to check for "
|
|
"None."
|
|
msgstr ""
|
|
"None 발생 시 패닉 상태가 될 수 있지만 '실수'로 None을 체크하는 것을 잊을 수"
|
|
"는 없습니다."
|
|
|
|
#: src/std-types/option.md
|
|
msgid ""
|
|
"It's common to `unwrap`/`expect` all over the place when hacking something "
|
|
"together, but production code typically handles `None` in a nicer fashion."
|
|
msgstr ""
|
|
"무언가를 함께 해킹할 때 모든 곳에서 `unwrap`/`expect`를 실행하는 것이 일반적"
|
|
"이지만 프로덕션 코드는 일반적으로 더 나은 방식으로 `None`을 처리합니다."
|
|
|
|
#: src/std-types/option.md
|
|
msgid ""
|
|
"The niche optimization means that `Option<T>` often has the same size in "
|
|
"memory as `T`."
|
|
msgstr ""
|
|
"틈새 최적화란 `Option<T>`가 메모리에서 `T`와 크기가 같은 경우가 많다는 것을 "
|
|
"의미합니다."
|
|
|
|
#: src/std-types/result.md
|
|
msgid "Result"
|
|
msgstr "Result"
|
|
|
|
#: src/std-types/result.md
|
|
msgid ""
|
|
"`Result` is similar to `Option`, but indicates the success or failure of an "
|
|
"operation, each with a different type. This is similar to the `Res` defined "
|
|
"in the expression exercise, but generic: `Result<T, E>` where `T` is used in "
|
|
"the `Ok` variant and `E` appears in the `Err` variant."
|
|
msgstr ""
|
|
"`Result`는 `Option`과 유사하지만 작업의 성공 또는 실패를 나타내며, 각각 타입"
|
|
"이 다릅니다. 이는 표현식 연습에서 정의된 `Res`와 유사하지만 제네릭: "
|
|
"`Result<T, E>`입니다. 여기서 `T`는 `Ok` 변형에 사용되고 `E`는 `Err` 변형에 표"
|
|
"시됩니다."
|
|
|
|
#: src/std-types/result.md
|
|
msgid "\"diary.txt\""
|
|
msgstr "\"diary.txt\""
|
|
|
|
#: src/std-types/result.md
|
|
msgid "\"Dear diary: {contents} ({bytes} bytes)\""
|
|
msgstr "\"다이어리: {contents}({bytes}바이트)\""
|
|
|
|
#: src/std-types/result.md
|
|
msgid "\"Could not read file content\""
|
|
msgstr "\"파일 콘텐츠를 읽을 수 없습니다.\""
|
|
|
|
#: src/std-types/result.md
|
|
msgid "\"The diary could not be opened: {err}\""
|
|
msgstr "\"다이어리를 열 수 없습니다. {err}\""
|
|
|
|
#: src/std-types/result.md
|
|
msgid ""
|
|
"As with `Option`, the successful value sits inside of `Result`, forcing the "
|
|
"developer to explicitly extract it. This encourages error checking. In the "
|
|
"case where an error should never happen, `unwrap()` or `expect()` can be "
|
|
"called, and this is a signal of the developer intent too."
|
|
msgstr ""
|
|
"`Option`와 마찬가지로, 성공한 경우의 값은 `Result` 내부에 있습니다. 그래서, "
|
|
"개발자는 명시적으로 이를 추출하여야 합니다. 이렇게 함으로써 값을 읽기 전에 오"
|
|
"류 발생 여부를 반드시 체크하도록 유도하고 있습니다. 만일 오류가 절대 발생하"
|
|
"지 않는 경우라면 `unwrap()`이나 `expect()`를 사용할 수 있으며, 이는 개발자의 "
|
|
"의도(_역주_: 오류가 발생할 수 없음)을 명시적으로 나타내는 방법이기도 합니다."
|
|
|
|
#: src/std-types/result.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`Result` documentation is a recommended read. Not during the course, but it "
|
|
"is worth mentioning. It contains a lot of convenience methods and functions "
|
|
"that help functional-style programming."
|
|
msgstr ""
|
|
"수업중엔 아니지만 `Result`의 API 레퍼런스를 읽는 것을 권장합니다. 함수형 프로"
|
|
"그래밍 스타일에 도움이 되는 편리한 메서드와 함수를 많이 배울 수 있습니다. "
|
|
|
|
#: src/std-types/result.md
|
|
msgid ""
|
|
"`Result` is the standard type to implement error handling as we will see on "
|
|
"Day 3."
|
|
msgstr ""
|
|
"`Result`는 오류 처리를 위한 표준 타입입니다. 3일차 과정에서 살펴봅니다."
|
|
|
|
#: src/std-types/string.md
|
|
msgid "String"
|
|
msgstr "String"
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"[`String`](https://doc.rust-lang.org/std/string/struct.String.html) is the "
|
|
"standard heap-allocated growable UTF-8 string buffer:"
|
|
msgstr ""
|
|
"[`String`](https://doc.rust-lang.org/std/string/struct.String.html)은 힙에 할"
|
|
"당되고 가변 길이의 표준 UTF-8 문자열 버퍼입니다:"
|
|
|
|
#: src/std-types/string.md src/std-traits/read-and-write.md
|
|
#: src/memory-management/review.md src/testing/unit-tests.md
|
|
#: src/concurrency/scoped-threads.md
|
|
msgid "\"Hello\""
|
|
msgstr "\"안녕하세요\""
|
|
|
|
#: src/std-types/string.md
|
|
msgid "\"s1: len = {}, capacity = {}\""
|
|
msgstr "\"s1: len = {}, 용량 = {}\""
|
|
|
|
#: src/std-types/string.md
|
|
msgid "'!'"
|
|
msgstr "'!'"
|
|
|
|
#: src/std-types/string.md
|
|
msgid "\"s2: len = {}, capacity = {}\""
|
|
msgstr "\"s2: len = {}, 용량 = {}\""
|
|
|
|
#: src/std-types/string.md
|
|
msgid "\"🇨🇭\""
|
|
msgstr "\"🇨🇭\""
|
|
|
|
#: src/std-types/string.md
|
|
msgid "\"s3: len = {}, number of chars = {}\""
|
|
msgstr "\"s3: len = {}, 문자 수 = {}\""
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"`String` implements [`Deref<Target = str>`](https://doc.rust-lang.org/std/"
|
|
"string/struct.String.html#deref-methods-str), which means that you can call "
|
|
"all `str` methods on a `String`."
|
|
msgstr ""
|
|
"`String`은 [`Deref<Target = str>`](https://doc.rust-lang.org/std/string/"
|
|
"struct.String.html#deref-methods-str)을 구현합니다. 이는 , `String` 값에 대해"
|
|
"서도 `str`의 모든 메서드를 호출 할 수 있다는 의미 입니다."
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"`String::new` returns a new empty string, use `String::with_capacity` when "
|
|
"you know how much data you want to push to the string."
|
|
msgstr ""
|
|
"`String::new`는 새로운 빈 문자열을 반환합니다. `String::with_capacity`는 새"
|
|
"로 만들 문자열 버퍼에 넣을 데이터 크기를 알고 있는 경우에 사용할 수 있습니다."
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"`String::len` returns the size of the `String` in bytes (which can be "
|
|
"different from its length in characters)."
|
|
msgstr ""
|
|
"`String::len`은 `String`의 바이트 크기를 반환합니다. (실제 문자 개수와는 다"
|
|
"를 수 있습니다.)"
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"`String::chars` returns an iterator over the actual characters. Note that a "
|
|
"`char` can be different from what a human will consider a \"character\" due "
|
|
"to [grapheme clusters](https://docs.rs/unicode-segmentation/latest/"
|
|
"unicode_segmentation/struct.Graphemes.html)."
|
|
msgstr ""
|
|
"`String::chars`는 실제 문자(character)들에 대한 이터레이터를 반환합니다. "
|
|
"`char`로 표현되는 문자는 우리가 실제로 인식하고 사용하는 문자와는 다를 수 있"
|
|
"습니다. 자소 결합으로 문자를 표현하는 경우가 있기 때문입니다. 이에 대해서는 "
|
|
"[Grapheme Cluster](https://docs.rs/unicode-segmentation/latest/"
|
|
"unicode_segmentation/struct.Graphemes.html)를 참고하세요."
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"When people refer to strings they could either be talking about `&str` or "
|
|
"`String`."
|
|
msgstr "사람들이 문자열이라고 말할 때에는 `&str`이거나 `String`일 수 있습니다."
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"When a type implements `Deref<Target = T>`, the compiler will let you "
|
|
"transparently call methods from `T`."
|
|
msgstr ""
|
|
"어떤 타입이 `Deref<Target = T>`를 구현하고 있으면, 컴파일러는 여러분이 `T`의 "
|
|
"메소드들을 호출할 수 있게 도와줍니다."
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"We haven't discussed the `Deref` trait yet, so at this point this mostly "
|
|
"explains the structure of the sidebar in the documentation."
|
|
msgstr ""
|
|
"`Deref` 트레잇에 관해서 아직 다루지 않았으므로 이 시점에서는 이것으로 문서의 "
|
|
"사이드바 구조가 대부분 설명됩니다."
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"`String` implements `Deref<Target = str>` which transparently gives it "
|
|
"access to `str`'s methods."
|
|
msgstr ""
|
|
"`String`은 `Deref<Target = str>`을 구현하고 있기 때문에 `String`에 대해서도 "
|
|
"`str` 메소드들을 호출할 수 있습니다."
|
|
|
|
#: src/std-types/string.md
|
|
#, fuzzy
|
|
msgid "Write and compare `let s3 = s1.deref();` and `let s3 = &*s1;`."
|
|
msgstr "`let s3 = s1.deref();`와 `let s3 = &*s1;`을 비교해보세요."
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"`String` is implemented as a wrapper around a vector of bytes, many of the "
|
|
"operations you see supported on vectors are also supported on `String`, but "
|
|
"with some extra guarantees."
|
|
msgstr ""
|
|
"`String`은 바이트 벡터의 래퍼로 구현되어 있습니다. 벡터가 지원하는 여러가지 "
|
|
"연산들을 `String`도 지원합니다. 다만 `String`은 몇가지 보장 내용이 더 있습니"
|
|
"다."
|
|
|
|
#: src/std-types/string.md
|
|
msgid "Compare the different ways to index a `String`:"
|
|
msgstr "`String`을 인덱스로 접근하는 방법들을 비교해보세요:"
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"To a character by using `s3.chars().nth(i).unwrap()` where `i` is in-bound, "
|
|
"out-of-bounds."
|
|
msgstr ""
|
|
"`s3.chars().nth(i).unwrap()`를 이용하여 한 문자를 선택하는 경우, `i`값이 범위"
|
|
"를 벗어날 때, 벗어나지 않을 때 동작을 설명하세요."
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"To a substring by using `s3[0..4]`, where that slice is on character "
|
|
"boundaries or not."
|
|
msgstr ""
|
|
"`s3[0..4]`를 이용해서 문자열의 일부를 선택하는데, 슬라이스가 유니코드 문자열 "
|
|
"경계에 딱 맞지 않을 경우 어떻게 되는지 설명하세요."
|
|
|
|
#: src/std-types/string.md
|
|
msgid ""
|
|
"Many types can be converted to a string with the [`to_string`](https://doc."
|
|
"rust-lang.org/std/string/trait.ToString.html#tymethod.to_string) method. "
|
|
"This trait is automatically implemented for all types that implement "
|
|
"`Display`, so anything that can be formatted can also be converted to a "
|
|
"string."
|
|
msgstr ""
|
|
|
|
#: src/std-types/vec.md
|
|
msgid ""
|
|
"[`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html) is the standard "
|
|
"resizable heap-allocated buffer:"
|
|
msgstr ""
|
|
"[`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html) 는 힙에 할당된 표"
|
|
"준 가변 크기 버퍼입니다:"
|
|
|
|
#: src/std-types/vec.md
|
|
msgid "\"v1: len = {}, capacity = {}\""
|
|
msgstr "\"v1: len = {}, 용량 = {}\""
|
|
|
|
#: src/std-types/vec.md
|
|
msgid "\"v2: len = {}, capacity = {}\""
|
|
msgstr "\"v2: len = {}, 용량 = {}\""
|
|
|
|
#: src/std-types/vec.md
|
|
msgid "// Canonical macro to initialize a vector with elements.\n"
|
|
msgstr "// 요소가 있는 벡터를 초기화하는 표준 매크로입니다.\n"
|
|
|
|
#: src/std-types/vec.md
|
|
msgid "// Retain only the even elements.\n"
|
|
msgstr "// 짝수 요소만 유지합니다.\n"
|
|
|
|
#: src/std-types/vec.md
|
|
msgid "\"{v3:?}\""
|
|
msgstr "\"{v3:?}\""
|
|
|
|
#: src/std-types/vec.md
|
|
msgid "// Remove consecutive duplicates.\n"
|
|
msgstr "// 연속 중복 삭제\n"
|
|
|
|
#: src/std-types/vec.md
|
|
msgid ""
|
|
"`Vec` implements [`Deref<Target = [T]>`](https://doc.rust-lang.org/std/vec/"
|
|
"struct.Vec.html#deref-methods-%5BT%5D), which means that you can call slice "
|
|
"methods on a `Vec`."
|
|
msgstr ""
|
|
"`Vec`은 [`Deref<Target = [T]>`](https://doc.rust-lang.org/std/vec/struct.Vec."
|
|
"html#deref-methods-%5BT%5D)를 구현합니다. 이는 `Vec`에서 슬라이스 메서드를 호"
|
|
"출 할 수 있다는 의미입니다."
|
|
|
|
#: src/std-types/vec.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`Vec` is a type of collection, along with `String` and `HashMap`. The data "
|
|
"it contains is stored on the heap. This means the amount of data doesn't "
|
|
"need to be known at compile time. It can grow or shrink at runtime."
|
|
msgstr ""
|
|
"`Vec`은 `String`이나 `HashMap`과 같은 컬렉션 타입입니다. 벡터는 데이터를 힙"
|
|
"에 저장합니다. 이는 컴파일 시점에 데이터 크기를 알 필요가 없다는 의미고, 런타"
|
|
"임에 더 커질 수도 작아질 수도 있습니다."
|
|
|
|
#: src/std-types/vec.md
|
|
msgid ""
|
|
"Notice how `Vec<T>` is a generic type too, but you don't have to specify `T` "
|
|
"explicitly. As always with Rust type inference, the `T` was established "
|
|
"during the first `push` call."
|
|
msgstr ""
|
|
"`Vec<T>`는 제네릭 타입이기도 합니다. 하지만 `T`를 꼭 지정해줄 필요는 없습니"
|
|
"다. 이 경우, 러스트 타입 추론이 벡터에 처음 `push`하는 데이터로 `T`를 알 수 "
|
|
"있었습니다."
|
|
|
|
#: src/std-types/vec.md
|
|
msgid ""
|
|
"`vec![...]` is a canonical macro to use instead of `Vec::new()` and it "
|
|
"supports adding initial elements to the vector."
|
|
msgstr ""
|
|
"`vec![...]`는 `Vec::new()` 대신 쓸 수 있는 표준 매크로로서, 초기 데이터를 추"
|
|
"가한 벡터를 생성할 수 있습니다."
|
|
|
|
#: src/std-types/vec.md
|
|
msgid ""
|
|
"To index the vector you use `[` `]`, but they will panic if out of bounds. "
|
|
"Alternatively, using `get` will return an `Option`. The `pop` function will "
|
|
"remove the last element."
|
|
msgstr ""
|
|
"벡터는 `[` `]`를 사용하여 인덱스로 접근할 수 있습니다. 하지만 범위를 벗어나"
|
|
"면 패닉이 발생합니다. 대신 `get`을 사용하면 `Option`을 반환합니다. `pop` 함수"
|
|
"는 마지막 요소를 제거합니다."
|
|
|
|
#: src/std-types/vec.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Slices are covered on day 3. For now, students only need to know that a "
|
|
"value of type `Vec` gives access to all of the documented slice methods, too."
|
|
msgstr ""
|
|
"슬라이스는 3일 차에 다룹니다. 지금은 'Vec' 타입의 값을 통해 문서화된 모든 읽"
|
|
"기 전용 슬라이스 메서드에도 액세스할 수 있다는 사실만 알면 됩니다."
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "Standard hash map with protection against HashDoS attacks:"
|
|
msgstr "HashDoS 공격으로부터 보호되는 표준 해시 맵입니다:"
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "\"Adventures of Huckleberry Finn\""
|
|
msgstr "\"허클베리 핀의 모험\""
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "\"Grimms' Fairy Tales\""
|
|
msgstr "\"그림 동화\""
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "\"Pride and Prejudice\""
|
|
msgstr "\"오만과 편견\""
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "\"Les Misérables\""
|
|
msgstr "\"레 미제라블\""
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "\"We know about {} books, but not Les Misérables.\""
|
|
msgstr "\"{}의 책은 알고 있지만 레 미제라블은 알지 못합니다.\""
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "\"Alice's Adventure in Wonderland\""
|
|
msgstr "\"이상한 나라의 앨리스\""
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "\"{book}: {count} pages\""
|
|
msgstr "\"{book}: {count}페이지\""
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "\"{book} is unknown.\""
|
|
msgstr "\"{book}을(를) 알 수 없습니다.\""
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "// Use the .entry() method to insert a value if nothing is found.\n"
|
|
msgstr ""
|
|
"// 값을 찾을 수 없는 경우 .entry() 메서드를 사용하여 값을 삽입합니다.\n"
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "\"{page_counts:#?}\""
|
|
msgstr "\"{page_counts:#?}\""
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid ""
|
|
"`HashMap` is not defined in the prelude and needs to be brought into scope."
|
|
msgstr ""
|
|
"`HashMap`은 prelude에 정의되어 있지 않기 때문에 명시적으로 추가해줘야 합니다."
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid ""
|
|
"Try the following lines of code. The first line will see if a book is in the "
|
|
"hashmap and if not return an alternative value. The second line will insert "
|
|
"the alternative value in the hashmap if the book is not found."
|
|
msgstr ""
|
|
"아래 코드를 테스트해보세요. 첫 문장에서는 해시맵에 책이 있는지 검사하여, 없으"
|
|
"면 디폴트 값을 반환합니다. 두번 째 문장에서는 해시맵에 해당 책이 없는 경우, "
|
|
"지정한 값을 해시맵에 추가한 뒤 그 값을 반환합니다."
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "\"Harry Potter and the Sorcerer's Stone\""
|
|
msgstr "\"해리 포터와 마법사의 돌\""
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "\"The Hunger Games\""
|
|
msgstr "\"헝거게임\""
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid "Unlike `vec!`, there is unfortunately no standard `hashmap!` macro."
|
|
msgstr "안타깝지만 `hashmap!`같은 매크로가 없습니다."
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid ""
|
|
"Although, since Rust 1.56, HashMap implements [`From<[(K, V); N]>`](https://"
|
|
"doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#impl-"
|
|
"From%3C%5B(K,+V);+N%5D%3E-for-HashMap%3CK,+V,+RandomState%3E), which allows "
|
|
"us to easily initialize a hash map from a literal array:"
|
|
msgstr ""
|
|
"러스트 1.56부터는 `HashMap`이 [`From<[(K, V); N]>`](https://doc.rust-lang."
|
|
"org/std/collections/hash_map/struct.HashMap.html#impl-From%3C%5B(K,+V);"
|
|
"+N%5D%3E-for-HashMap%3CK,+V,+RandomState%3E)을 구현하기 때문에 배열 리터럴을 "
|
|
"이용하여 쉽게 해시맵을 초기화할 수 있습니다:"
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid ""
|
|
"Alternatively HashMap can be built from any `Iterator` which yields key-"
|
|
"value tuples."
|
|
msgstr "키-값 쌍에 대한 `Iterator`로 해시맵을 만들 수도 있습니다."
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid ""
|
|
"We are showing `HashMap<String, i32>`, and avoid using `&str` as key to make "
|
|
"examples easier. Using references in collections can, of course, be done, "
|
|
"but it can lead into complications with the borrow checker."
|
|
msgstr ""
|
|
"예제 코드에서는 편의상 해시맵의 키로 `&str`를 사용하지 않았습니다. 물론 컬렉"
|
|
"션에 참조를 사용할 수도 있습니다. 다만 참조를 사용하게 되면 빌림 검사기 때문"
|
|
"에 복잡해 질 수 있습니다."
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid ""
|
|
"Try removing `to_string()` from the example above and see if it still "
|
|
"compiles. Where do you think we might run into issues?"
|
|
msgstr ""
|
|
"예제 코드에서 `to_string()`을 없애도 컴파일에 문제가 없는지 확인해보세요. 어"
|
|
"떤 문제에 부딪힐까요?"
|
|
|
|
#: src/std-types/hashmap.md
|
|
msgid ""
|
|
"This type has several \"method-specific\" return types, such as `std::"
|
|
"collections::hash_map::Keys`. These types often appear in searches of the "
|
|
"Rust docs. Show students the docs for this type, and the helpful link back "
|
|
"to the `keys` method."
|
|
msgstr ""
|
|
"해시맵의 몇 몇 메서드는 해시맵 내부의 특별한 타입(예를 들어 `std::"
|
|
"collections::hash_map::Keys`)들을 리턴합니다. 이러한 타입들은 Rust 문서에서"
|
|
"도 검색할 수 있습니다. 수강생들에게 이 타입들에 대한 문서를 보여주고, 이 문서"
|
|
"에 `keys` 메서드로의 역 링크가 있음을 알려주세요."
|
|
|
|
#: src/std-types/exercise.md
|
|
msgid ""
|
|
"In this exercise you will take a very simple data structure and make it "
|
|
"generic. It uses a [`std::collections::HashMap`](https://doc.rust-lang.org/"
|
|
"stable/std/collections/struct.HashMap.html) to keep track of which values "
|
|
"have been seen and how many times each one has appeared."
|
|
msgstr ""
|
|
"이 연습에서는 매우 간단한 데이터 구조를 사용하여 제네릭으로 만듭니다. [`std::"
|
|
"collections::HashMap`](https://doc.rust-lang.org/stable/std/collections/"
|
|
"struct.HashMap.html)을 사용하여 어떤 값이 표시되었는지, 각각 얼마나 표시되었"
|
|
"는지 추적합니다."
|
|
|
|
#: src/std-types/exercise.md
|
|
msgid ""
|
|
"The initial version of `Counter` is hard coded to only work for `u32` "
|
|
"values. Make the struct and its methods generic over the type of value being "
|
|
"tracked, that way `Counter` can track any type of value."
|
|
msgstr ""
|
|
"`Counter`의 초기 버전은 `u32` 값에만 작동하도록 하드 코딩되어 있습니다. 추적 "
|
|
"중인 값 타입에 대해 구조체 및 메서드를 제네릭으로 만듭니다. 그러면 `Counter`"
|
|
"가 모든 타입의 값을 추적할 수 있습니다."
|
|
|
|
#: src/std-types/exercise.md
|
|
msgid ""
|
|
"If you finish early, try using the [`entry`](https://doc.rust-lang.org/"
|
|
"stable/std/collections/struct.HashMap.html#method.entry) method to halve the "
|
|
"number of hash lookups required to implement the `count` method."
|
|
msgstr ""
|
|
"일찍 완료한 경우 [`entry`](https://doc.rust-lang.org/stable/std/collections/"
|
|
"struct.HashMap.html#method.entry) 메서드를 사용하여, `count` 메서드를 구현하"
|
|
"는 데 필요한 해시 조회 횟수를 절반으로 줄여보세요."
|
|
|
|
#: src/std-types/exercise.md src/std-types/solution.md
|
|
msgid ""
|
|
"/// Counter counts the number of times each value of type T has been seen.\n"
|
|
msgstr "/// Counter는 각 T 타입 값이 표시된 횟수를 계산합니다.\n"
|
|
|
|
#: src/std-types/exercise.md src/std-types/solution.md
|
|
msgid "/// Create a new Counter.\n"
|
|
msgstr "/// 새 Counter를 만듭니다.\n"
|
|
|
|
#: src/std-types/exercise.md src/std-types/solution.md
|
|
msgid "/// Count an occurrence of the given value.\n"
|
|
msgstr "/// 지정된 값의 발생 횟수를 셉니다.\n"
|
|
|
|
#: src/std-types/exercise.md src/std-types/solution.md
|
|
msgid "/// Return the number of times the given value has been seen.\n"
|
|
msgstr "/// 지정된 값이 표시된 횟수를 반환합니다.\n"
|
|
|
|
#: src/std-types/exercise.md src/std-types/solution.md
|
|
msgid "\"saw {} values equal to {}\""
|
|
msgstr "\"{} 개의 {} 값을 발견했습니다.\""
|
|
|
|
#: src/std-types/exercise.md src/std-types/solution.md
|
|
msgid "\"apple\""
|
|
msgstr "\"사과\""
|
|
|
|
#: src/std-types/exercise.md src/std-types/solution.md
|
|
msgid "\"orange\""
|
|
msgstr "\"오렌지\""
|
|
|
|
#: src/std-types/exercise.md src/std-types/solution.md
|
|
msgid "\"got {} apples\""
|
|
msgstr "\"사과 {}개 받음\""
|
|
|
|
#: src/std-traits.md
|
|
msgid "[Comparisons](./std-traits/comparisons.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-traits.md
|
|
msgid "[Operators](./std-traits/operators.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-traits.md
|
|
msgid "[From and Into](./std-traits/from-and-into.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-traits.md
|
|
msgid "[Casting](./std-traits/casting.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-traits.md
|
|
msgid "[Read and Write](./std-traits/read-and-write.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-traits.md
|
|
msgid "[Default, struct update syntax](./std-traits/default.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-traits.md
|
|
msgid "[Closures](./std-traits/closures.md) (20 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-traits.md
|
|
msgid "[Exercise: ROT13](./std-traits/exercise.md) (30 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/std-traits.md
|
|
msgid "This segment should take about 1 hour and 40 minutes"
|
|
msgstr ""
|
|
|
|
#: src/std-traits.md
|
|
msgid ""
|
|
"As with the standard-library types, spend time reviewing the documentation "
|
|
"for each trait."
|
|
msgstr ""
|
|
"표준 라이브러리 타입과 마찬가지로 각 트레잇에 관한 문서를 검토하는 데 시간을 "
|
|
"할애하세요."
|
|
|
|
#: src/std-traits.md
|
|
msgid "This section is long. Take a break midway through."
|
|
msgstr "이 섹션은 깁니다. 중간에 휴식을 취하세요."
|
|
|
|
#: src/std-traits/comparisons.md
|
|
msgid ""
|
|
"These traits support comparisons between values. All traits can be derived "
|
|
"for types containing fields that implement these traits."
|
|
msgstr ""
|
|
"이러한 트레잇은 값 간의 비교를 지원합니다. 모든 트레잇은 이러한 트레잇을 구현"
|
|
"하는 필드를 포함하는 타입에 대해 상속될 수 있습니다."
|
|
|
|
#: src/std-traits/comparisons.md
|
|
#, fuzzy
|
|
msgid "`PartialEq` and `Eq`"
|
|
msgstr "`PartialEq` 및 `Eq`"
|
|
|
|
#: src/std-traits/comparisons.md
|
|
msgid ""
|
|
"`PartialEq` is a partial equivalence relation, with required method `eq` and "
|
|
"provided method `ne`. The `==` and `!=` operators will call these methods."
|
|
msgstr ""
|
|
"`PartialEq`는 필수 메서드인 `eq` 및 제공된 `ne` 메서드를 사용하는 부분 등가 "
|
|
"관계입니다. `==` 및 `!=` 연산자는 이러한 메서드를 호출합니다."
|
|
|
|
#: src/std-traits/comparisons.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`Eq` is a full equivalence relation (reflexive, symmetric, and transitive) "
|
|
"and implies `PartialEq`. Functions that require full equivalence will use "
|
|
"`Eq` as a trait bound."
|
|
msgstr ""
|
|
"`Eq`는 완전한 등가 관계(반사, 대칭, 추이)이며 `PartialEq`를 암시합니다. 완전"
|
|
"한 등가가 필요한 함수는 트레잇 경계로 `Eq`를 사용합니다."
|
|
|
|
#: src/std-traits/comparisons.md
|
|
msgid "`PartialOrd` and `Ord`"
|
|
msgstr "`PartialOrd` 및 `Ord`"
|
|
|
|
#: src/std-traits/comparisons.md
|
|
msgid ""
|
|
"`PartialOrd` defines a partial ordering, with a `partial_cmp` method. It is "
|
|
"used to implement the `<`, `<=`, `>=`, and `>` operators."
|
|
msgstr ""
|
|
"`PartialOrd`는 `partial_cmp` 메서드를 사용하여 부분 순서를 정의합니다. `<`, "
|
|
"`<=`, `>=`, `>` 연산자를 구현하는 데 사용됩니다."
|
|
|
|
#: src/std-traits/comparisons.md
|
|
msgid "`Ord` is a total ordering, with `cmp` returning `Ordering`."
|
|
msgstr "`Ord`는 전체 순서 지정이며 `cmp`는 `Ordering`을 반환합니다."
|
|
|
|
#: src/std-traits/comparisons.md
|
|
msgid ""
|
|
"`PartialEq` can be implemented between different types, but `Eq` cannot, "
|
|
"because it is reflexive:"
|
|
msgstr ""
|
|
"`PartialEq`는 서로 다른 타입 간에 구현될 수 있지만 `Eq`는 구현될 수 없습니"
|
|
"다. 반사적이기 때문입니다."
|
|
|
|
#: src/std-traits/comparisons.md
|
|
msgid ""
|
|
"In practice, it's common to derive these traits, but uncommon to implement "
|
|
"them."
|
|
msgstr ""
|
|
"실제로 이러한 트레잇을 상속하는 것은 일반적이지만 구현하는 것은 드문 일입니"
|
|
"다."
|
|
|
|
#: src/std-traits/operators.md
|
|
msgid ""
|
|
"Operator overloading is implemented via traits in [`std::ops`](https://doc."
|
|
"rust-lang.org/std/ops/index.html):"
|
|
msgstr "연산자 오버로드는 `std::ops`에 있는 다양한 트레잇들을 통해 구현됩니다:"
|
|
|
|
#: src/std-traits/operators.md
|
|
msgid "\"{:?} + {:?} = {:?}\""
|
|
msgstr "\"{:?} + {:?} = {:?}\""
|
|
|
|
#: src/std-traits/operators.md src/memory-management/drop.md
|
|
msgid "Discussion points:"
|
|
msgstr "논의점:"
|
|
|
|
#: src/std-traits/operators.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"You could implement `Add` for `&Point`. In which situations is that useful?"
|
|
msgstr ""
|
|
"`&Point`가 `Add`를 구현하도록 할 수도 있습니다. 이게 어떤 경우에 유용할까요? "
|
|
|
|
#: src/std-traits/operators.md
|
|
msgid ""
|
|
"Answer: `Add:add` consumes `self`. If type `T` for which you are overloading "
|
|
"the operator is not `Copy`, you should consider overloading the operator for "
|
|
"`&T` as well. This avoids unnecessary cloning on the call site."
|
|
msgstr ""
|
|
"답: `Add:add`는 `self`를 소모합니다. 만약 타입 `T`가 `Copy`트레잇을 구현하고 "
|
|
"있지 않다면 `&T`에 대해서도 연산자 오버로딩을 고려해야 합니다. 이렇게 하면 호"
|
|
"출부에서 불필요한 복사를 피할 수 있습니다."
|
|
|
|
#: src/std-traits/operators.md
|
|
msgid ""
|
|
"Why is `Output` an associated type? Could it be made a type parameter of the "
|
|
"method?"
|
|
msgstr "왜 `Output`이 연관된 타입인가요? 타입 파라메터로 만들 수 있을까요?"
|
|
|
|
#: src/std-traits/operators.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Short answer: Function type parameters are controlled by the caller, but "
|
|
"associated types (like `Output`) are controlled by the implementer of a "
|
|
"trait."
|
|
msgstr ""
|
|
"답: 타입 파라메터를 호출하는 쪽에서 결정합니다. 반면 연관된 타입(`Output`같"
|
|
"은) 은 트레잇을 구현하는 쪽에서 제어 가능합니다."
|
|
|
|
#: src/std-traits/operators.md
|
|
msgid ""
|
|
"You could implement `Add` for two different types, e.g. `impl Add<(i32, "
|
|
"i32)> for Point` would add a tuple to a `Point`."
|
|
msgstr ""
|
|
"`Add`를 이용해서 서로 다른 두 개의 타입을 더할 수도 있습니다. 예를 들어 "
|
|
"`impl Add<(i32, i32)> for Point`는 튜플을 `Point`에 더할 수 있게 해 줍니다."
|
|
|
|
#: src/std-traits/from-and-into.md
|
|
msgid ""
|
|
"Types implement [`From`](https://doc.rust-lang.org/std/convert/trait.From."
|
|
"html) and [`Into`](https://doc.rust-lang.org/std/convert/trait.Into.html) to "
|
|
"facilitate type conversions:"
|
|
msgstr ""
|
|
"타입은 용이한 형변환을 위해 [`From`](https://doc.rust-lang.org/std/convert/"
|
|
"trait.From.html)과 [`Into`](https://doc.rust-lang.org/std/convert/trait.Into."
|
|
"html)를 구현합니다:"
|
|
|
|
#: src/std-traits/from-and-into.md
|
|
msgid "\"{s}, {addr}, {one}, {bigger}\""
|
|
msgstr "\"{s}, {addr}, {one}, {bigger}\""
|
|
|
|
#: src/std-traits/from-and-into.md
|
|
msgid ""
|
|
"[`Into`](https://doc.rust-lang.org/std/convert/trait.Into.html) is "
|
|
"automatically implemented when [`From`](https://doc.rust-lang.org/std/"
|
|
"convert/trait.From.html) is implemented:"
|
|
msgstr ""
|
|
"[`From`](https://doc.rust-lang.org/std/convert/trait.From.html)이 구현되면 "
|
|
"[`Into`](https://doc.rust-lang.org/std/convert/trait.Into.html) 역시 자동으"
|
|
"로 구현됩니다:"
|
|
|
|
#: src/std-traits/from-and-into.md
|
|
msgid ""
|
|
"That's why it is common to only implement `From`, as your type will get "
|
|
"`Into` implementation too."
|
|
msgstr ""
|
|
"그렇기 때문에 사용자 정의 타입의 경우에도 `From` 만 구현하는 것이 일반적입니"
|
|
"다."
|
|
|
|
#: src/std-traits/from-and-into.md
|
|
msgid ""
|
|
"When declaring a function argument input type like \"anything that can be "
|
|
"converted into a `String`\", the rule is opposite, you should use `Into`. "
|
|
"Your function will accept types that implement `From` and those that _only_ "
|
|
"implement `Into`."
|
|
msgstr ""
|
|
"\"`String`으로 변환할 수 있는 모든 것\"과 같은 함수의 인수 타입을 선언할 때에"
|
|
"는 `Into`를 사용해야 함을 조심하세요. 그래야만, 함수는 `From`을 구현한 타입"
|
|
"과 `Into` _만_ 구현한 타입 모두를 인자로 받을 수 있습니다."
|
|
|
|
#: src/std-traits/casting.md
|
|
msgid ""
|
|
"Rust has no _implicit_ type conversions, but does support explicit casts "
|
|
"with `as`. These generally follow C semantics where those are defined."
|
|
msgstr ""
|
|
"Rust에는 _암시적_ 타입 변환이 없지만 `as`를 사용한 명시적 변환은 지원됩니다. "
|
|
"이는 일반적으로 C 의미론을 따라 정의됩니다."
|
|
|
|
#: src/std-traits/casting.md
|
|
msgid "\"as u16: {}\""
|
|
msgstr "\"as u16: {}\""
|
|
|
|
#: src/std-traits/casting.md
|
|
msgid "\"as i16: {}\""
|
|
msgstr "\"as i16: {}\""
|
|
|
|
#: src/std-traits/casting.md
|
|
msgid "\"as u8: {}\""
|
|
msgstr "\"as u8: {}\""
|
|
|
|
#: src/std-traits/casting.md
|
|
msgid ""
|
|
"The results of `as` are _always_ defined in Rust and consistent across "
|
|
"platforms. This might not match your intuition for changing sign or casting "
|
|
"to a smaller type -- check the docs, and comment for clarity."
|
|
msgstr ""
|
|
"`as`의 결과는 Rust에서 _항상_ 정의되며 여러 플랫폼에서 일관됩니다. 이는 기호"
|
|
"를 변경하거나 더 작은 타입으로 변환할 때의 직관과 일치하지 않을 수 있습니다. "
|
|
"문서를 확인하고 명확하게 설명해 주세요."
|
|
|
|
#: src/std-traits/casting.md
|
|
msgid ""
|
|
"Casting with `as` is a relatively sharp tool that is easy to use "
|
|
"incorrectly, and can be a source of subtle bugs as future maintenance work "
|
|
"changes the types that are used or the ranges of values in types. Casts are "
|
|
"best used only when the intent is to indicate unconditional truncation (e.g. "
|
|
"selecting the bottom 32 bits of a `u64` with `as u32`, regardless of what "
|
|
"was in the high bits)."
|
|
msgstr ""
|
|
|
|
#: src/std-traits/casting.md
|
|
msgid ""
|
|
"For infallible casts (e.g. `u32` to `u64`), prefer using `From` or `Into` "
|
|
"over `as` to confirm that the cast is in fact infallible. For fallible "
|
|
"casts, `TryFrom` and `TryInto` are available when you want to handle casts "
|
|
"that fit differently from those that don't."
|
|
msgstr ""
|
|
|
|
#: src/std-traits/casting.md
|
|
msgid "Consider taking a break after this slide."
|
|
msgstr "이 슬라이드가 끝난 후 잠시 쉬어가는 것이 좋습니다."
|
|
|
|
#: src/std-traits/casting.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`as` is similar to a C++ static cast. Use of `as` in cases where data might "
|
|
"be lost is generally discouraged, or at least deserves an explanatory "
|
|
"comment."
|
|
msgstr ""
|
|
"`as`는 C++ 정적 변환과 유사합니다. 데이터가 손실될 수 있는 경우 'as'를 사용"
|
|
"하는 것은 일반적으로 권장되지 않으며, 적어도 설명하는 주석을 다는 것이 좋습니"
|
|
"다."
|
|
|
|
#: src/std-traits/casting.md
|
|
msgid "This is common in casting integers to `usize` for use as an index."
|
|
msgstr "이는 정수를 `usize`로 변환하여 색인으로 사용할 때 일반적입니다."
|
|
|
|
#: src/std-traits/read-and-write.md
|
|
msgid ""
|
|
"Using [`Read`](https://doc.rust-lang.org/std/io/trait.Read.html) and "
|
|
"[`BufRead`](https://doc.rust-lang.org/std/io/trait.BufRead.html), you can "
|
|
"abstract over `u8` sources:"
|
|
msgstr ""
|
|
"[`Read`](https://doc.rust-lang.org/std/io/trait.Read.html)와 [`BufRead`]"
|
|
"(https://doc.rust-lang.org/std/io/trait.BufRead.html)를 사용하면 `u8` 타입의 "
|
|
"데이터 스트림을 읽을 수 있습니다:"
|
|
|
|
#: src/std-traits/read-and-write.md
|
|
msgid "b\"foo\\nbar\\nbaz\\n\""
|
|
msgstr "b\"foo\\nbar\\nbaz\\n\""
|
|
|
|
#: src/std-traits/read-and-write.md
|
|
msgid "\"lines in slice: {}\""
|
|
msgstr "\"슬라이스 내 줄: {}\""
|
|
|
|
#: src/std-traits/read-and-write.md
|
|
msgid "\"lines in file: {}\""
|
|
msgstr "\"파일 내 줄: {}\""
|
|
|
|
#: src/std-traits/read-and-write.md
|
|
msgid ""
|
|
"Similarly, [`Write`](https://doc.rust-lang.org/std/io/trait.Write.html) lets "
|
|
"you abstract over `u8` sinks:"
|
|
msgstr "이와 비슷하게, `Write`를 사옹하면 `u8` 타입의 데이터를 쓸 수 있습니다:"
|
|
|
|
#: src/std-traits/read-and-write.md
|
|
msgid "\"\\n\""
|
|
msgstr "\"\\n\""
|
|
|
|
#: src/std-traits/read-and-write.md src/slices-and-lifetimes/str.md
|
|
msgid "\"World\""
|
|
msgstr "\"World\""
|
|
|
|
#: src/std-traits/read-and-write.md
|
|
msgid "\"Logged: {:?}\""
|
|
msgstr "\"로그 내역: {:?}\""
|
|
|
|
#: src/std-traits/default.md
|
|
msgid "The `Default` Trait"
|
|
msgstr "`Default` 트레잇"
|
|
|
|
#: src/std-traits/default.md
|
|
msgid ""
|
|
"[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) trait "
|
|
"produces a default value for a type."
|
|
msgstr ""
|
|
"[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) 트레잇"
|
|
"은 어떤 타입에 대한 기본값을 제공합니다."
|
|
|
|
#: src/std-traits/default.md
|
|
msgid "\"John Smith\""
|
|
msgstr "\"존 스미스\""
|
|
|
|
#: src/std-traits/default.md
|
|
msgid "\"{default_struct:#?}\""
|
|
msgstr "\"{default_struct:#?}\""
|
|
|
|
#: src/std-traits/default.md
|
|
msgid "\"Y is set!\""
|
|
msgstr "\"Y 설정됨\""
|
|
|
|
#: src/std-traits/default.md
|
|
msgid "\"{almost_default_struct:#?}\""
|
|
msgstr "\"{almost_default_struct:#?}\""
|
|
|
|
#: src/std-traits/default.md src/slices-and-lifetimes/exercise.md
|
|
#: src/slices-and-lifetimes/solution.md
|
|
msgid "\"{:#?}\""
|
|
msgstr "\"{:#?}\""
|
|
|
|
#: src/std-traits/default.md
|
|
msgid ""
|
|
"It can be implemented directly or it can be derived via `#[derive(Default)]`."
|
|
msgstr ""
|
|
"트레잇을 직접 구현하거나 `#[derive(Default)]`를 붙여서 컴파일러에게 구현을 맡"
|
|
"길 수 있습니다."
|
|
|
|
#: src/std-traits/default.md
|
|
msgid ""
|
|
"A derived implementation will produce a value where all fields are set to "
|
|
"their default values."
|
|
msgstr ""
|
|
"컴파일러가 제공하는 자동 구현의 경우 모든 필드에 대해 기본 값을 설정한 새 인"
|
|
"스턴스를 반환합니다."
|
|
|
|
#: src/std-traits/default.md
|
|
msgid "This means all types in the struct must implement `Default` too."
|
|
msgstr ""
|
|
"이는 구조체의 각 필드 타입들이 모두 `Default` 트레잇을 구현해야 함을 의미합니"
|
|
"다."
|
|
|
|
#: src/std-traits/default.md
|
|
msgid ""
|
|
"Standard Rust types often implement `Default` with reasonable values (e.g. "
|
|
"`0`, `\"\"`, etc)."
|
|
msgstr ""
|
|
"러스트 표준 타입들은 대부분 `Default`를 구현하고 있으며, 기본 값은 `0`이나 "
|
|
"`\"\"`처럼 예상 가능한 값들입니다."
|
|
|
|
#: src/std-traits/default.md
|
|
#, fuzzy
|
|
msgid "The partial struct initialization works nicely with default."
|
|
msgstr ""
|
|
"구조체의 일부분만 복사하고 싶을 때 `default`를 편리하게 사용할 수 있습니다."
|
|
|
|
#: src/std-traits/default.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The Rust standard library is aware that types can implement `Default` and "
|
|
"provides convenience methods that use it."
|
|
msgstr ""
|
|
"러스트 표준 라이브러리는 `Default` 트레잇을 구현한 타입을 위한 편의 메서드를 "
|
|
"제공하기도 합니다."
|
|
|
|
#: src/std-traits/default.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The `..` syntax is called [struct update syntax](https://doc.rust-lang.org/"
|
|
"book/ch05-01-defining-structs.html#creating-instances-from-other-instances-"
|
|
"with-struct-update-syntax)."
|
|
msgstr ""
|
|
"이 `..` 문법은 [구조체 업데이트 문법(struct update syntax)](https://doc.rust-"
|
|
"lang.org/book/ch05-01-defining-structs.html#creating-instances-from-other-"
|
|
"instances-with-struct-update-syntax)라고 합니다"
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid ""
|
|
"Closures or lambda expressions have types which cannot be named. However, "
|
|
"they implement special [`Fn`](https://doc.rust-lang.org/std/ops/trait.Fn."
|
|
"html), [`FnMut`](https://doc.rust-lang.org/std/ops/trait.FnMut.html), and "
|
|
"[`FnOnce`](https://doc.rust-lang.org/std/ops/trait.FnOnce.html) traits:"
|
|
msgstr ""
|
|
"클로저 혹은 람다표현식은 익명타입입니다. 이들은 [`Fn`](https://doc.rust-lang."
|
|
"org/std/ops/trait.Fn.html),[`FnMut`](https://doc.rust-lang.org/std/ops/trait."
|
|
"FnMut.html), [`FnOnce`](https://doc.rust-lang.org/std/ops/trait.FnOnce.html) "
|
|
"라는 특별한 트레잇을 구현합니다:"
|
|
|
|
#: src/std-traits/closures.md
|
|
#, fuzzy
|
|
msgid "\"Calling function on {input}\""
|
|
msgstr "안전하지 않은 함수 호출"
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid "\"add_3: {}\""
|
|
msgstr "\"add_3: {}\""
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid "\"accumulate: {}\""
|
|
msgstr "\"accumulate: {}\""
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid "\"multiply_sum: {}\""
|
|
msgstr "\"multiply_sum: {}\""
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid ""
|
|
"An `Fn` (e.g. `add_3`) neither consumes nor mutates captured values, or "
|
|
"perhaps captures nothing at all. It can be called multiple times "
|
|
"concurrently."
|
|
msgstr ""
|
|
"`Fn`(예를 들어 `add_3`)은 캡처된 값을 소모도 변경도 하지 않고, 혹은 어떤 것"
|
|
"도 캡쳐하지 않았을 수도 있기 때문에 동시에 여러번 호출할 수 있습니다."
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid ""
|
|
"An `FnMut` (e.g. `accumulate`) might mutate captured values. You can call it "
|
|
"multiple times, but not concurrently."
|
|
msgstr ""
|
|
"`FnMut`(예를 들어 `accumulate`)는 캡처된 값을 변경할 수 있으므로 여러 번 호출"
|
|
"은 가능하지만 동시에 호출 할 수는 없습니다."
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid ""
|
|
"If you have an `FnOnce` (e.g. `multiply_sum`), you may only call it once. It "
|
|
"might consume captured values."
|
|
msgstr ""
|
|
"`FnOnce` (예를 들어 `multiply_sum`)는 한번만 호출되며 캡처된 값을 소모합니다."
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid ""
|
|
"`FnMut` is a subtype of `FnOnce`. `Fn` is a subtype of `FnMut` and `FnOnce`. "
|
|
"I.e. you can use an `FnMut` wherever an `FnOnce` is called for, and you can "
|
|
"use an `Fn` wherever an `FnMut` or `FnOnce` is called for."
|
|
msgstr ""
|
|
"`FnMut` 는 `FnOnce`의 하위타입입니다. `Fn`은 `FnMut`과 `FnOnce`의 하위 타입입"
|
|
"니다. 즉, `FnMut`는 `FnOnce`가 호출되는 곳이면 어디서나 사용 할 수 있고 `Fn`"
|
|
"은 `FnMut`와 `FnOnce`가 호출되는 곳이면 어디든 사용할 수 있습니다."
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid ""
|
|
"When you define a function that takes a closure, you should take `FnOnce` if "
|
|
"you can (i.e. you call it once), or `FnMut` else, and last `Fn`. This allows "
|
|
"the most flexibility for the caller."
|
|
msgstr ""
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid ""
|
|
"In contrast, when you have a closure, the most flexible you can have is `Fn` "
|
|
"(it can be passed everywhere), then `FnMut`, and lastly `FnOnce`."
|
|
msgstr ""
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid ""
|
|
"The compiler also infers `Copy` (e.g. for `add_3`) and `Clone` (e.g. "
|
|
"`multiply_sum`), depending on what the closure captures."
|
|
msgstr ""
|
|
"컴파일러는 클로저가 무엇을 캡쳐하는지에 따라 `Copy`(예를 들어 `add_3`)과 "
|
|
"`Clone`(예를 들어 `multiply_sum`)을 알아서 추론합니다."
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid ""
|
|
"By default, closures will capture by reference if they can. The `move` "
|
|
"keyword makes them capture by value."
|
|
msgstr ""
|
|
"기본적으로 클로져는, 가능하다면, 참조를 사용하여 캡쳐를 합니다. `move` 키워드"
|
|
"를 쓰면 값으로 캡쳐가 됩니다."
|
|
|
|
#: src/std-traits/closures.md src/smart-pointers/trait-objects.md
|
|
msgid "\"{} {}\""
|
|
msgstr "\"{} {}\""
|
|
|
|
#: src/std-traits/closures.md
|
|
msgid "\"Hi\""
|
|
msgstr "\"Hi\""
|
|
|
|
#: src/std-traits/closures.md
|
|
#, fuzzy
|
|
msgid "\"Greg\""
|
|
msgstr "\"인사말\""
|
|
|
|
#: src/std-traits/exercise.md
|
|
msgid ""
|
|
"In this example, you will implement the classic [\"ROT13\" cipher](https://"
|
|
"en.wikipedia.org/wiki/ROT13). Copy this code to the playground, and "
|
|
"implement the missing bits. Only rotate ASCII alphabetic characters, to "
|
|
"ensure the result is still valid UTF-8."
|
|
msgstr ""
|
|
"이 예에서는 기존의 [\"ROT13\" 암호화](https://en.wikipedia.org/wiki/ROT13)를 "
|
|
"구현합니다. 이 코드를 플레이그라운드에 복사하고 누락된 비트를 구현합니다. 결"
|
|
"과가 여전히 유효한 UTF-8인지 확인하려면 ASCII 영문자만 회전하세요."
|
|
|
|
#: src/std-traits/exercise.md
|
|
msgid "// Implement the `Read` trait for `RotDecoder`.\n"
|
|
msgstr "// `RotDecoder`의 `Read` 트레잇을 구현합니다.\n"
|
|
|
|
#: src/std-traits/exercise.md src/std-traits/solution.md
|
|
msgid "\"Gb trg gb gur bgure fvqr!\""
|
|
msgstr "\"Gb trg gb gur bgure fvqr!\""
|
|
|
|
#: src/std-traits/exercise.md src/std-traits/solution.md
|
|
msgid "\"To get to the other side!\""
|
|
msgstr "\"To get to the other side!\""
|
|
|
|
#: src/std-traits/exercise.md
|
|
msgid ""
|
|
"What happens if you chain two `RotDecoder` instances together, each rotating "
|
|
"by 13 characters?"
|
|
msgstr ""
|
|
"각각 13자씩 회전하는 두 개의 `RotDecoder` 인스턴스를 함께 체이닝하면 어떻게 "
|
|
"될까요?"
|
|
|
|
#: src/std-traits/solution.md
|
|
msgid "'A'"
|
|
msgstr "'A'"
|
|
|
|
#: src/welcome-day-3.md
|
|
msgid "Welcome to Day 3"
|
|
msgstr "3일차 개요"
|
|
|
|
#: src/welcome-day-3.md
|
|
msgid "Today, we will cover:"
|
|
msgstr "오늘 다룰 내용은 다음과 같습니다."
|
|
|
|
#: src/welcome-day-3.md
|
|
msgid ""
|
|
"Memory management, lifetimes, and the borrow checker: how Rust ensures "
|
|
"memory safety."
|
|
msgstr "메모리 관리, 수명, 빌림 검사기: Rust가 메모리 안전을 보장하는 방법"
|
|
|
|
#: src/welcome-day-3.md
|
|
msgid "Smart pointers: standard library pointer types."
|
|
msgstr "스마트 포인터: 표준 라이브러리 포인터 타입"
|
|
|
|
#: src/welcome-day-3.md
|
|
msgid "[Welcome](./welcome-day-3.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-3.md
|
|
msgid "[Memory Management](./memory-management.md) (1 hour)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-3.md
|
|
msgid "[Smart Pointers](./smart-pointers.md) (55 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-3.md
|
|
msgid ""
|
|
"Including 10 minute breaks, this session should take about 2 hours and 20 "
|
|
"minutes"
|
|
msgstr ""
|
|
|
|
#: src/memory-management.md
|
|
msgid "[Review of Program Memory](./memory-management/review.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/memory-management.md
|
|
msgid ""
|
|
"[Approaches to Memory Management](./memory-management/approaches.md) (10 "
|
|
"minutes)"
|
|
msgstr ""
|
|
|
|
#: src/memory-management.md
|
|
msgid "[Ownership](./memory-management/ownership.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/memory-management.md
|
|
msgid "[Move Semantics](./memory-management/move.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/memory-management.md
|
|
msgid "[Clone](./memory-management/clone.md) (2 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/memory-management.md
|
|
msgid "[Copy Types](./memory-management/copy-types.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/memory-management.md
|
|
msgid "[Drop](./memory-management/drop.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/memory-management.md
|
|
msgid "[Exercise: Builder Type](./memory-management/exercise.md) (20 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/memory-management/review.md
|
|
msgid "Programs allocate memory in two ways:"
|
|
msgstr "프로그램은 두 가지 방법으로 메모리를 할당합니다."
|
|
|
|
#: src/memory-management/review.md
|
|
msgid "Stack: Continuous area of memory for local variables."
|
|
msgstr "스택: 로컬 변수를 위한 연속적인 메모리 영역."
|
|
|
|
#: src/memory-management/review.md
|
|
msgid "Values have fixed sizes known at compile time."
|
|
msgstr "여기 저장되는 값은 컴파일 시 결정되는 고정 크기를 갖습니다."
|
|
|
|
#: src/memory-management/review.md
|
|
msgid "Extremely fast: just move a stack pointer."
|
|
msgstr ""
|
|
"매우 빠름: 메모리 할당/반환이 단지 스택 포인터의 이동만으로 구현됩니다."
|
|
|
|
#: src/memory-management/review.md
|
|
msgid "Easy to manage: follows function calls."
|
|
msgstr "관리가 쉬움: 함수가 호출되면 할당되고, 리턴하면 반환됩니다."
|
|
|
|
#: src/memory-management/review.md
|
|
msgid "Great memory locality."
|
|
msgstr "스택에 있는 값들은 매우 높은 메모리 인접성을 가집니다."
|
|
|
|
#: src/memory-management/review.md
|
|
msgid "Heap: Storage of values outside of function calls."
|
|
msgstr "힙: 함수 호출/리턴과 상관 없이 유지되는 값이 저장되는 곳."
|
|
|
|
#: src/memory-management/review.md
|
|
msgid "Values have dynamic sizes determined at runtime."
|
|
msgstr "여기 저장되는 값은 프로그램 수행시 그 크기가 결정됩니다."
|
|
|
|
#: src/memory-management/review.md
|
|
msgid "Slightly slower than the stack: some book-keeping needed."
|
|
msgstr "스택 보다는 느림: 메모리 할당/반환시 해야 할 일이 좀 더 있습니다."
|
|
|
|
#: src/memory-management/review.md
|
|
msgid "No guarantee of memory locality."
|
|
msgstr "메모리 인접성을 보장하지 않습니다."
|
|
|
|
#: src/memory-management/review.md
|
|
msgid ""
|
|
"Creating a `String` puts fixed-sized metadata on the stack and dynamically "
|
|
"sized data, the actual string, on the heap:"
|
|
msgstr ""
|
|
"`String`을 하나 만들게 되면, 스택에는 고정된 크기의 메타 데이터가 생성되고, "
|
|
"힙에는 가변 크기의 데이터, 즉, 실제 문자열, 이 생성됩니다:"
|
|
|
|
#: src/memory-management/review.md
|
|
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/review.md
|
|
msgid ""
|
|
"If students ask about it, you can mention that the underlying memory is heap "
|
|
"allocated using the [System Allocator](https://doc.rust-lang.org/std/alloc/"
|
|
"struct.System.html) and custom allocators can be implemented using the "
|
|
"[Allocator API](https://doc.rust-lang.org/std/alloc/index.html)"
|
|
msgstr ""
|
|
"힙은 기본적으로 [System Allocator](https://doc.rust-lang.org/std/alloc/"
|
|
"struct.System.html)를 통해 할당됩니다. 그리고 [Allocator API](https://doc."
|
|
"rust-lang.org/std/alloc/index.html)를 이용해서 커스텀 메모리 할당자를 만들 수"
|
|
"도 있습니다."
|
|
|
|
#: src/memory-management/review.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"We can inspect the memory layout with `unsafe` Rust. However, you should "
|
|
"point out that this is rightfully unsafe!"
|
|
msgstr ""
|
|
"아래와 같은 `unsafe` 코드로 메모리 레이아웃을 살펴볼 수 있습니다. 물론 이 코"
|
|
"드가 안전하지 않다는 점을 알려주세요!"
|
|
|
|
#: src/memory-management/review.md src/testing/unit-tests.md
|
|
msgid "' '"
|
|
msgstr "' '"
|
|
|
|
#: src/memory-management/review.md
|
|
msgid "\"world\""
|
|
msgstr "\"world\""
|
|
|
|
#: src/memory-management/review.md
|
|
msgid ""
|
|
"// DON'T DO THIS AT HOME! For educational purposes only.\n"
|
|
" // String provides no guarantees about its layout, so this could lead "
|
|
"to\n"
|
|
" // undefined behavior.\n"
|
|
msgstr ""
|
|
"// 집에서는 하지 마세요. 교육 목적으로만 사용할 수 있습니다.\n"
|
|
" // 문자열은 레이아웃을 보장하지 않으므로\n"
|
|
" // 정의되지 않은 동작이 발생할 수 있습니다.\n"
|
|
|
|
#: src/memory-management/review.md
|
|
msgid "\"capacity = {capacity}, ptr = {ptr:#x}, len = {len}\""
|
|
msgstr ""
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid "Traditionally, languages have fallen into two broad categories:"
|
|
msgstr "전통적으로, 두 종류의 프로그래밍 언어가 있습니다:"
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid "Full control via manual memory management: C, C++, Pascal, ..."
|
|
msgstr ""
|
|
"메모리 관리가 프로그래머의 완전한 통제하에 있지만 수동(그래서 안전하지 않을 "
|
|
"수 있는)인 언어: C, C++, Pascal, ..."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid "Programmer decides when to allocate or free heap memory."
|
|
msgstr "프로그래머가 힙 메모리를 할당하거나 확보할 시기를 결정합니다."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid ""
|
|
"Programmer must determine whether a pointer still points to valid memory."
|
|
msgstr ""
|
|
"프로그래머는 포인터가 여전히 유효한 메모리를 가리키는지 확인해야 합니다."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid "Studies show, programmers make mistakes."
|
|
msgstr "연구 결과에 따르면 프로그래머도 실수합니다."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid ""
|
|
"Full safety via automatic memory management at runtime: Java, Python, Go, "
|
|
"Haskell, ..."
|
|
msgstr ""
|
|
"메모리 관리가 런타임에 의해 되므로 안전하지만 자동(그래서 프로그래머가 개입"
|
|
"할 여지가 적거나 없는)인 언어: Java, Python, Go, Haskell, ..."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid ""
|
|
"A runtime system ensures that memory is not freed until it can no longer be "
|
|
"referenced."
|
|
msgstr ""
|
|
"런타임 시스템은 메모리를 더 이상 참조할 수 없을 때까지 해제되지 않도록 합니"
|
|
"다."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid ""
|
|
"Typically implemented with reference counting, garbage collection, or RAII."
|
|
msgstr "일반적으로 참조 계산, 가비지 컬렉션 또는 RAII로 구현됩니다."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid "Rust offers a new mix:"
|
|
msgstr "러스트는 이 둘을 혼합한 새로운 형태의 메모리 관리 기법을 제공합니다:"
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid ""
|
|
"Full control _and_ safety via compile time enforcement of correct memory "
|
|
"management."
|
|
msgstr ""
|
|
"컴파일 시 올바른 메모리 관리를 강제함으로써 완전한 통제와 안전성 _모두_ 제공."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid "It does this with an explicit ownership concept."
|
|
msgstr "이를 가능하게 하는 러스트의 컨셉은 명시적인 소유권입니다."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid ""
|
|
"This slide is intended to help students coming from other languages to put "
|
|
"Rust in context."
|
|
msgstr ""
|
|
"이 슬라이드는 다른 언어를 사용하는 학생들이 맥락에 따라 Rust를 사용하는 데 도"
|
|
"움을 주기 위해 작성되었습니다."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid ""
|
|
"C must manage heap manually with `malloc` and `free`. Common errors include "
|
|
"forgetting to call `free`, calling it multiple times for the same pointer, "
|
|
"or dereferencing a pointer after the memory it points to has been freed."
|
|
msgstr ""
|
|
"C는 `malloc` 및 `free`를 사용하여 힙을 수동으로 관리해야 합니다. 일반적인 오"
|
|
"류로는 `free` 호출을 잊어버리거나, 동일한 포인터에 대해 여러 번 호출하거나, "
|
|
"포인터가 가리키는 메모리가 해제된 후 포인터를 역참조하는 것 등이 있습니다."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid ""
|
|
"C++ has tools like smart pointers (`unique_ptr`, `shared_ptr`) that take "
|
|
"advantage of language guarantees about calling destructors to ensure memory "
|
|
"is freed when a function returns. It is still quite easy to mis-use these "
|
|
"tools and create similar bugs to C."
|
|
msgstr ""
|
|
"C++에는 함수가 반환될 때 메모리가 해제되도록 소멸자를 호출하는 것에 관한 언"
|
|
"어 보장을 활용하는 스마트 포인터(`unique_ptr`, `shared_ptr`)와 같은 도구가 있"
|
|
"습니다. 이러한 도구를 오용하여 C와 유사한 버그를 생성하는 것은 여전히 매우 쉽"
|
|
"습니다."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid ""
|
|
"Java, Go, and Python rely on the garbage collector to identify memory that "
|
|
"is no longer reachable and discard it. This guarantees that any pointer can "
|
|
"be dereferenced, eliminating use-after-free and other classes of bugs. But, "
|
|
"GC has a runtime cost and is difficult to tune properly."
|
|
msgstr ""
|
|
"Java, Go, Python은 가비지 컬렉터를 사용해 더 이상 연결할 수 없는 메모리를 식"
|
|
"별하고 삭제합니다. 이렇게 하면 모든 포인터가 역참조될 수 있으므로 use-after-"
|
|
"free 및 기타 클래스의 버그를 제거할 수 있습니다. 하지만 GC는 런타임 비용이 발"
|
|
"생하며 제대로 조정하기가 어렵습니다."
|
|
|
|
#: src/memory-management/approaches.md
|
|
msgid ""
|
|
"Rust's ownership and borrowing model can, in many cases, get the performance "
|
|
"of C, with alloc and free operations precisely where they are required -- "
|
|
"zero cost. It also provides tools similar to C++'s smart pointers. When "
|
|
"required, other options such as reference counting are available, and there "
|
|
"are even third-party crates available to support runtime garbage collection "
|
|
"(not covered in this class)."
|
|
msgstr ""
|
|
"Rust의 소유권 및 빌림 모델은 대부분의 경우 정확히 필요한 곳에 alloc 및 free "
|
|
"작업을 실행하여 C의 성능을 얻을 수 있습니다. 즉, 비용이 들지 않습니다. C++의 "
|
|
"스마트 포인터와 유사한 도구도 제공합니다. 필요한 경우 참조 계산과 같은 다른 "
|
|
"옵션을 사용할 수 있으며, 서드 파티 크레이트를 사용하여 런타임 가비지 컬렉션"
|
|
"을 지원할 수도 있습니다(이 클래스에서는 다루지 않음)."
|
|
|
|
#: src/memory-management/ownership.md
|
|
msgid ""
|
|
"All variable bindings have a _scope_ where they are valid and it is an error "
|
|
"to use a variable outside its scope:"
|
|
msgstr ""
|
|
"모든 변수 바인딩은 유효한 \"범위(스코프)\"를 가지며, 범위 밖에서 변수 사용하"
|
|
"면 에러가 발생합니다:"
|
|
|
|
#: src/memory-management/ownership.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"We say that the variable _owns_ the value. Every Rust value has precisely "
|
|
"one owner at all times."
|
|
msgstr "이것을 두고 변수가 값을 \"소유\"한다고 표현합니다."
|
|
|
|
#: src/memory-management/ownership.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"At the end of the scope, the variable is _dropped_ and the data is freed. A "
|
|
"destructor can run here to free up resources."
|
|
msgstr ""
|
|
"스코프가 종료되면 변수는 \"삭제(drop)\"되었다고 하며 그 변수의 데이터는 메모"
|
|
"리에서 해제됩니다."
|
|
|
|
#: src/memory-management/ownership.md
|
|
msgid ""
|
|
"Students familiar with garbage-collection implementations will know that a "
|
|
"garbage collector starts with a set of \"roots\" to find all reachable "
|
|
"memory. Rust's \"single owner\" principle is a similar idea."
|
|
msgstr ""
|
|
"가비지 컬렉션 구현에 익숙한 학생은 가비지 컬렉터가 연결 가능한 모든 메모리를 "
|
|
"찾기 위해 '루트' 세트로 시작한다는 사실을 알 수 있을 것입니다. Rust의 '단일 "
|
|
"소유자' 원칙도 이와 유사합니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "An assignment will transfer _ownership_ between variables:"
|
|
msgstr "(변수의) 할당은 \\_소유권_을 변수 간에 이동시킵니다:"
|
|
|
|
#: src/memory-management/move.md
|
|
#, fuzzy
|
|
msgid "\"Hello!\""
|
|
msgstr "\"Hello!\""
|
|
|
|
#: src/memory-management/move.md src/slices-and-lifetimes/str.md
|
|
msgid "\"s2: {s2}\""
|
|
msgstr "\"s2: {s2}\""
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "// println!(\"s1: {s1}\");\n"
|
|
msgstr "// println!(\"s1: {s1}\");\n"
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "The assignment of `s1` to `s2` transfers ownership."
|
|
msgstr "`s1`을 `s2`에 할당하여 소유권을 이전시킵니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "When `s1` goes out of scope, nothing happens: it does not own anything."
|
|
msgstr ""
|
|
"`s1`의 스코프가 종료되면 아무 일도 없습니다: 왜냐하면 `s1`은 아무런 소유권이 "
|
|
"없기 때문입니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "When `s2` goes out of scope, the string data is freed."
|
|
msgstr "`s2`의 스코프가 종료되면 문자열 데이터는 해제됩니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "Before move to `s2`:"
|
|
msgstr "`s2`로 이동 전 메모리:"
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "After move to `s2`:"
|
|
msgstr "`s2`로 이동 후 메모리:"
|
|
|
|
#: src/memory-management/move.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"```bob\n"
|
|
" Stack Heap\n"
|
|
".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - -.\n"
|
|
": : : :\n"
|
|
": s1 \"(inaccessible)\" : : :\n"
|
|
": +-----------+-------+ : : +----+----+----+----+----+----+ :\n"
|
|
": | ptr | o---+---+--+--+-->| H | e | l | l | o | ! | :\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 ""
|
|
"```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"
|
|
"```"
|
|
|
|
#: src/memory-management/move.md
|
|
msgid ""
|
|
"When you pass a value to a function, the value is assigned to the function "
|
|
"parameter. This transfers ownership:"
|
|
msgstr ""
|
|
"값을 함수에 전달할때, 그 값은 매개변수에 할당됩니다. 이때 소유권의 이동이 일"
|
|
"어납니다:"
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "\"Hello {name}\""
|
|
msgstr "\"안녕하세요 {name}\""
|
|
|
|
#: src/memory-management/move.md src/android/interoperability/java.md
|
|
msgid "\"Alice\""
|
|
msgstr "\"Alice\""
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "// say_hello(name);\n"
|
|
msgstr "// say_hello(name);\n"
|
|
|
|
#: src/memory-management/move.md
|
|
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/memory-management/move.md
|
|
msgid ""
|
|
"It is only the ownership that moves. Whether any machine code is generated "
|
|
"to manipulate the data itself is a matter of optimization, and such copies "
|
|
"are aggressively optimized away."
|
|
msgstr ""
|
|
"실제로 이동되는 것은 소유권일 뿐입니다. 머신 코드 레벨에서 데이터 복사가 일어"
|
|
"날 지 말 지에 대한 것은 컴파일러 내부에서 일어나는 최적화 문제입니다. 이런 복"
|
|
"사는 최적화 과정에서 제거가 됩니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid ""
|
|
"Simple values (such as integers) can be marked `Copy` (see later slides)."
|
|
msgstr ""
|
|
"정수와 같은 간단한 값들은 `Copy` (뒤에 설명합니다)로 마킹될 수 있습니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "In Rust, clones are explicit (by using `clone`)."
|
|
msgstr "러스트에서는 복사할때에는 명시적으로 `clone`을 사용합니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "In the `say_hello` example:"
|
|
msgstr "`say_hello` 예:"
|
|
|
|
#: src/memory-management/move.md
|
|
msgid ""
|
|
"With the first call to `say_hello`, `main` gives up ownership of `name`. "
|
|
"Afterwards, `name` cannot be used anymore within `main`."
|
|
msgstr ""
|
|
"`say_hello`함수의 첫번째 호출시 `main`함수는 자신이 가진 `name`에 대한 소유권"
|
|
"을 포기하므로, 이후 `main`함수에서는 `name`을 사용할 수 없습니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid ""
|
|
"The heap memory allocated for `name` will be freed at the end of the "
|
|
"`say_hello` function."
|
|
msgstr "`name`에 할당되있는 힙 메모리는 `say_hello`함수의 끝에서 해제됩니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid ""
|
|
"`main` can retain ownership if it passes `name` as a reference (`&name`) and "
|
|
"if `say_hello` accepts a reference as a parameter."
|
|
msgstr ""
|
|
"`main`함수에서 `name`을 참조로 전달(빌림)하고(`&name`), `say_hello`에서 매개"
|
|
"변수를 참조형으로 수정한다면 `main`함수는 `name`의 소유권을 유지할 수 있습니"
|
|
"다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid ""
|
|
"Alternatively, `main` can pass a clone of `name` in the first call (`name."
|
|
"clone()`)."
|
|
msgstr ""
|
|
"또는 첫번째 호출 시 `main`함수에서 `name`을 복제하여 전달할 수도 있습니다."
|
|
"(`name.clone()`)"
|
|
|
|
#: src/memory-management/move.md
|
|
msgid ""
|
|
"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 ""
|
|
"러스트는 이동을 기본으로 하고 복제를 명시적으로 선언하도록 만듬으로, 의도치 "
|
|
"않게 복사본을 만드는 것이 C++에서보다 어렵습니다."
|
|
|
|
#: src/memory-management/move.md
|
|
#, fuzzy
|
|
msgid "Defensive Copies in Modern C++"
|
|
msgstr "Modern C++에서 이중해제 문제"
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "Modern C++ solves this differently:"
|
|
msgstr "Modern C++은 이 문제를 다르게 해결합니다:"
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "\"Cpp\""
|
|
msgstr "\"Cpp\""
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "// Duplicate the data in s1.\n"
|
|
msgstr "// s1의 데이터를 복제합니다.\n"
|
|
|
|
#: src/memory-management/move.md
|
|
msgid ""
|
|
"The heap data from `s1` is duplicated and `s2` gets its own independent copy."
|
|
msgstr "`s1`의 힙 데이터는 복제되고, `s2`는 독립적인 복사본을 얻습니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "When `s1` and `s2` go out of scope, they each free their own memory."
|
|
msgstr "`s1` 와 `s2`의 스코프가 종료되면 각각의 메모리가 해제됩니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "Before copy-assignment:"
|
|
msgstr "복사 전:"
|
|
|
|
#: src/memory-management/move.md
|
|
msgid "After copy-assignment:"
|
|
msgstr "복사 후:"
|
|
|
|
#: src/memory-management/move.md
|
|
msgid ""
|
|
"C++ has made a slightly different choice than Rust. Because `=` copies data, "
|
|
"the string data has to be cloned. Otherwise we would get a double-free when "
|
|
"either string goes out of scope."
|
|
msgstr ""
|
|
"C++는 Rust와 약간 다른 선택을 했습니다. `=`는 데이터를 복사하므로 문자열 데이"
|
|
"터가 클론되어야 합니다. 그렇지 않으면 문자열 중 하나가 범위를 벗어날 때 "
|
|
"double-free가 발생합니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid ""
|
|
"C++ also has [`std::move`](https://en.cppreference.com/w/cpp/utility/move), "
|
|
"which is used to indicate when a value may be moved from. If the example had "
|
|
"been `s2 = std::move(s1)`, no heap allocation would take place. After the "
|
|
"move, `s1` would be in a valid but unspecified state. Unlike Rust, the "
|
|
"programmer is allowed to keep using `s1`."
|
|
msgstr ""
|
|
"C++에는 값을 이동할 수 있는 시점을 나타내는 데 사용되는 [`std::move`]"
|
|
"(https://en.cppreference.com/w/cpp/utility/move)도 있습니다. 예가 `s2 = std::"
|
|
"move(s1)`이었다면 힙 할당이 발생하지 않습니다. 이동 후에는 `s1`이 유효하지만 "
|
|
"지정되지 않은 상태가 됩니다. Rust와 달리 프로그래머는 `s1`을 계속 사용할 수 "
|
|
"있습니다."
|
|
|
|
#: src/memory-management/move.md
|
|
msgid ""
|
|
"Unlike Rust, `=` in C++ can run arbitrary code as determined by the type "
|
|
"which is being copied or moved."
|
|
msgstr ""
|
|
"Rust와 달리, C++의 `=`는 복사되거나 이동되는 타입에 따라 결정된 임의의 코드"
|
|
"를 실행할 수 있습니다."
|
|
|
|
#: src/memory-management/clone.md
|
|
msgid "Clone"
|
|
msgstr "Clone"
|
|
|
|
#: src/memory-management/clone.md
|
|
msgid ""
|
|
"Sometimes you _want_ to make a copy of a value. The `Clone` trait "
|
|
"accomplishes this."
|
|
msgstr ""
|
|
"값을 _복사해야_ 하는 경우도 있습니다. `Clone` 트레잇을 사용하면 됩니다."
|
|
|
|
#: src/memory-management/clone.md
|
|
msgid ""
|
|
"The idea of `Clone` is to make it easy to spot where heap allocations are "
|
|
"occurring. Look for `.clone()` and a few others like `Vec::new` or `Box::"
|
|
"new`."
|
|
msgstr ""
|
|
"`Clone`의 개념은 힙 할당이 발생하는 위치를 쉽게 알아내는 것입니다. `."
|
|
"clone()` 및 `Vec::new` 또는 `Box::new`와 같은 다른 코드도 찾아봅니다."
|
|
|
|
#: src/memory-management/clone.md
|
|
msgid ""
|
|
"It's common to \"clone your way out\" of problems with the borrow checker, "
|
|
"and return later to try to optimize those clones away."
|
|
msgstr ""
|
|
"빌림 검사기로 문제 해결 방법을 '클론'하고 나중에 다시 방문하여 해당 클론을 최"
|
|
"적화하려고 시도하는 경우가 많습니다."
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid ""
|
|
"While move semantics are the default, certain types are copied by default:"
|
|
msgstr "이동이 기본 설정이지만, 특정 타입은 복사됩니다:"
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid "These types implement the `Copy` trait."
|
|
msgstr "이러한 타입들은 `Copy` 트레잇을 구현합니다."
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid "You can opt-in your own types to use copy semantics:"
|
|
msgstr "직접 만든 타입들도 `Copy`트레잇을 구현하여 복사를 할 수 있습니다:"
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid "After the assignment, both `p1` and `p2` own their own data."
|
|
msgstr "할당 후, `p1`와 `p2`는 자신의 데이터를 소유합니다."
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid "We can also use `p1.clone()` to explicitly copy the data."
|
|
msgstr "명시적으로 `p1.clone()`를 사용하여 데이터를 복사할 수 있습니다."
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid "Copying and cloning are not the same thing:"
|
|
msgstr "복사(copy)와 복제(clone)는 같지 않습니다:"
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid ""
|
|
"Copying refers to bitwise copies of memory regions and does not work on "
|
|
"arbitrary objects."
|
|
msgstr ""
|
|
"복사는 메모리의 내용을 그대로 한 벌 더 만드는 것을 의미하며, 아무 객체에서나 "
|
|
"다 지원하지는 않습니다."
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid ""
|
|
"Copying does not allow for custom logic (unlike copy constructors in C++)."
|
|
msgstr ""
|
|
"복사는 커스터마이즈 할 수 없습니다. (C++에서 복사 생성자를 통해 복사 동작을 "
|
|
"임의로 구현할 수 있는 것과 비교가 됩니다.)"
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid ""
|
|
"Cloning is a more general operation and also allows for custom behavior by "
|
|
"implementing the `Clone` trait."
|
|
msgstr ""
|
|
"복제는 보다 일반적인 작업이며, `Clone`트레잇을 구현하여 복제시 동작을 커스터"
|
|
"마이즈 할 수 있습니다."
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid "Copying does not work on types that implement the `Drop` trait."
|
|
msgstr "`Drop` 트레잇을 구현한 타입은 복사되지 않습니다."
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid "In the above example, try the following:"
|
|
msgstr "위의 예시에서 다음을 시도해 보시기 바랍니다:"
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid ""
|
|
"Add a `String` field to `struct Point`. It will not compile because `String` "
|
|
"is not a `Copy` type."
|
|
msgstr ""
|
|
"`Point`구조체에 `String`필드를 추가하세요. 컴파일 되지 않을 것입니다. 왜냐하"
|
|
"면 `String`은 `Copy`트레잇을 구현하고 있지 않기 때문입니다."
|
|
|
|
#: src/memory-management/copy-types.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Remove `Copy` from the `derive` attribute. The compiler error is now in the "
|
|
"`println!` for `p1`."
|
|
msgstr ""
|
|
"`derive` 속성에서 `Copy`를 제거해 보세요. `p1`을 `println!` 할 때 컴파일 에러"
|
|
"가 발생할 것입니다."
|
|
|
|
#: src/memory-management/copy-types.md
|
|
msgid "Show that it works if you clone `p1` instead."
|
|
msgstr "`p1`을 복제하면 잘 동작함을 확인해 보세요."
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid "The `Drop` Trait"
|
|
msgstr "`Drop` 트레잇"
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid ""
|
|
"Values which implement [`Drop`](https://doc.rust-lang.org/std/ops/trait.Drop."
|
|
"html) can specify code to run when they go out of scope:"
|
|
msgstr ""
|
|
"[`Drop`](https://doc.rust-lang.org/std/ops/trait.Drop.html)트레잇을 구현하"
|
|
"면, 그 값이 스코프 밖으로 나갈 때 실행될 코드를 작성할 수 있습니다:"
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid "\"Dropping {}\""
|
|
msgstr "\"{} 삭제 중\""
|
|
|
|
#: src/memory-management/drop.md src/exercises/concurrency/link-checker.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "\"a\""
|
|
msgstr "\"a\""
|
|
|
|
#: src/memory-management/drop.md src/android/testing/googletest.md
|
|
msgid "\"b\""
|
|
msgstr "\"b\""
|
|
|
|
#: src/memory-management/drop.md
|
|
#, fuzzy
|
|
msgid "\"c\""
|
|
msgstr "\"c\""
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid "\"d\""
|
|
msgstr "\"d\""
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid "\"Exiting block B\""
|
|
msgstr "\"B 블록에서 나가기\""
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid "\"Exiting block A\""
|
|
msgstr "\"A 블록에서 나가기\""
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid "\"Exiting main\""
|
|
msgstr "\"main에서 나가기\""
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid "Note that `std::mem::drop` is not the same as `std::ops::Drop::drop`."
|
|
msgstr "`std::mem::drop`은 `std::ops::Drop::drop`과 같지 않습니다."
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid "Values are automatically dropped when they go out of scope."
|
|
msgstr "값이 범위를 벗어나면 자동으로 삭제됩니다."
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid ""
|
|
"When a value is dropped, if it implements `std::ops::Drop` then its `Drop::"
|
|
"drop` implementation will be called."
|
|
msgstr ""
|
|
"값이 삭제될 때 `std::ops::Drop`을 구현하면 `Drop::drop` 구현이 호출됩니다."
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid ""
|
|
"All its fields will then be dropped too, whether or not it implements `Drop`."
|
|
msgstr "그러면 `Drop` 구현 여부와 관계없이 해당 필드도 모두 삭제됩니다."
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid ""
|
|
"`std::mem::drop` is just an empty function that takes any value. The "
|
|
"significance is that it takes ownership of the value, so at the end of its "
|
|
"scope it gets dropped. This makes it a convenient way to explicitly drop "
|
|
"values earlier than they would otherwise go out of scope."
|
|
msgstr ""
|
|
"`std::mem::drop`은 값을 사용하는 빈 함수입니다. 중요한 점은 값의 소유권을 가"
|
|
"지므로 범위 끝에서 삭제된다는 점입니다. 따라서 범위를 벗어날 때보다 빨리 값"
|
|
"을 명시적으로 삭제할 수 있는 편리한 방법입니다."
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid ""
|
|
"This can be useful for objects that do some work on `drop`: releasing locks, "
|
|
"closing files, etc."
|
|
msgstr ""
|
|
"이는 `drop`에서 잠금 해제, 파일 닫기 등의 작업을 실행하는 객체에 유용할 수 있"
|
|
"습니다."
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid "Why doesn't `Drop::drop` take `self`?"
|
|
msgstr "`Drop::drop`은 왜 `self`를 인자로 받지 않습니까?"
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid ""
|
|
"Short-answer: If it did, `std::mem::drop` would be called at the end of the "
|
|
"block, resulting in another call to `Drop::drop`, and a stack overflow!"
|
|
msgstr ""
|
|
"짧은 대답: 만약 그렇게 된다면 `std::mem::drop`이 블록의 끝에서 호출되고, 다"
|
|
"시 `Drop::drop`을 호출하게 되어, 스택 오버플로가 발생합니다!"
|
|
|
|
#: src/memory-management/drop.md
|
|
msgid "Try replacing `drop(a)` with `a.drop()`."
|
|
msgstr "`drop(a)`를 `a.drop()`로 변경해 보시기 바랍니다."
|
|
|
|
#: src/memory-management/exercise.md
|
|
msgid ""
|
|
"In this example, we will implement a complex data type that owns all of its "
|
|
"data. We will use the \"builder pattern\" to support building a new value "
|
|
"piece-by-piece, using convenience functions."
|
|
msgstr ""
|
|
"이 예에서는 모든 데이터를 소유하는 복잡한 데이터 타입을 구현합니다. 편의 함수"
|
|
"를 사용하여 새로운 값을 하나씩 빌드하도록 지원하기 위해 '빌더 패턴'을 사용합"
|
|
"니다."
|
|
|
|
#: src/memory-management/exercise.md
|
|
msgid "Fill in the missing pieces."
|
|
msgstr "누락된 부분을 채우세요."
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "/// A representation of a software package.\n"
|
|
msgstr "/// 소프트웨어 패키지를 나타냅니다.\n"
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid ""
|
|
"/// Return a representation of this package as a dependency, for use in\n"
|
|
" /// building other packages.\n"
|
|
msgstr ""
|
|
|
|
#: src/memory-management/exercise.md
|
|
msgid "\"1\""
|
|
msgstr "\"1\""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid ""
|
|
"/// A builder for a Package. Use `build()` to create the `Package` itself.\n"
|
|
msgstr ""
|
|
"/// 패키지용 빌더입니다. `build()`를 사용하여 `Package` 자체를 만듭니다.\n"
|
|
|
|
#: src/memory-management/exercise.md
|
|
msgid "\"2\""
|
|
msgstr "\"2\""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "/// Set the package version.\n"
|
|
msgstr "/// 패키지 버전을 설정합니다.\n"
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "/// Set the package authors.\n"
|
|
msgstr "/// 패키지 작성자를 설정합니다.\n"
|
|
|
|
#: src/memory-management/exercise.md
|
|
msgid "\"3\""
|
|
msgstr "\"3\""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "/// Add an additional dependency.\n"
|
|
msgstr "/// 종속 항목을 추가합니다.\n"
|
|
|
|
#: src/memory-management/exercise.md
|
|
msgid "\"4\""
|
|
msgstr "\"4\""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "/// Set the language. If not set, language defaults to None.\n"
|
|
msgstr ""
|
|
"/// 언어를 설정합니다. 설정하지 않으면 언어가 기본적으로 None으로 설정됩니"
|
|
"다.\n"
|
|
|
|
#: src/memory-management/exercise.md
|
|
msgid "\"5\""
|
|
msgstr "\"5\""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "\"base64\""
|
|
msgstr "\"base64\""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "\"0.13\""
|
|
msgstr "\"0.13\""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "\"base64: {base64:?}\""
|
|
msgstr "\"base64: {base64:?}\""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "\"log\""
|
|
msgstr ""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "\"0.4\""
|
|
msgstr "\"0.4\""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "\"log: {log:?}\""
|
|
msgstr "\"log: {log:?}\""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "\"serde\""
|
|
msgstr ""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "\"djmitche\""
|
|
msgstr "\"djmitche\""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "\"4.0\""
|
|
msgstr "\"4.0\""
|
|
|
|
#: src/memory-management/exercise.md src/memory-management/solution.md
|
|
msgid "\"serde: {serde:?}\""
|
|
msgstr "\"serde: {serde:?}\""
|
|
|
|
#: src/memory-management/solution.md
|
|
msgid "\"0.1\""
|
|
msgstr "\"0.1\""
|
|
|
|
#: src/smart-pointers.md
|
|
msgid "[Box"
|
|
msgstr ""
|
|
|
|
#: src/smart-pointers.md
|
|
msgid "](./smart-pointers/box.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/smart-pointers.md
|
|
msgid "[Rc](./smart-pointers/rc.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/smart-pointers.md
|
|
msgid "[Trait Objects](./smart-pointers/trait-objects.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/smart-pointers.md
|
|
msgid "[Exercise: Binary Tree](./smart-pointers/exercise.md) (30 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/smart-pointers.md src/error-handling.md
|
|
msgid "This segment should take about 55 minutes"
|
|
msgstr ""
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid ""
|
|
"[`Box`](https://doc.rust-lang.org/std/boxed/struct.Box.html) is an owned "
|
|
"pointer to data on the heap:"
|
|
msgstr ""
|
|
"[`Box`](https://doc.rust-lang.org/std/boxed/struct.Box.html)는 힙 데이터에 대"
|
|
"한 소유 포인터입니다:"
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid "\"five: {}\""
|
|
msgstr "\"five: {}\""
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid ""
|
|
"`Box<T>` implements `Deref<Target = T>`, which means that you can [call "
|
|
"methods from `T` directly on a `Box<T>`](https://doc.rust-lang.org/std/ops/"
|
|
"trait.Deref.html#more-on-deref-coercion)."
|
|
msgstr ""
|
|
"`Box<T>`은 [`Deref<Target = T>`](https://doc.rust-lang.org/std/ops/trait."
|
|
"Deref.html#more-on-deref-coercion)를 구현합니다. 이는 [`Box<T>`에서 `T` 메서"
|
|
"드를 직접 호출](https://doc.rust-lang.org/std/ops/trait.Deref.html#more-on-"
|
|
"deref-coercion) 할 수 있다는 의미입니다."
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid ""
|
|
"Recursive data types or data types with dynamic sizes need to use a `Box`:"
|
|
msgstr "재귀 데이터나 동적크기의 데이터 타입은 `Box`타입을 사용해야 합니다:"
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid "/// A non-empty list: first element and the rest of the list.\n"
|
|
msgstr ""
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid "/// An empty list.\n"
|
|
msgstr ""
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid "\"{list:?}\""
|
|
msgstr "\"{list:?}\""
|
|
|
|
#: src/smart-pointers/box.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"```bob\n"
|
|
" Stack Heap\n"
|
|
".- - - - - - - - - - - - - - . .- - - - - - - - - - - - - - - - - - - - "
|
|
"- - - - -.\n"
|
|
": : : :\n"
|
|
": "
|
|
"list : : :\n"
|
|
": +---------+----+----+ : : +---------+----+----+ +------+----"
|
|
"+----+ :\n"
|
|
": | Element | 1 | o--+----+-----+--->| Element | 2 | o--+--->| Nil | // "
|
|
"| // | :\n"
|
|
": +---------+----+----+ : : +---------+----+----+ +------+----"
|
|
"+----+ :\n"
|
|
": : : :\n"
|
|
": : : :\n"
|
|
"'- - - - - - - - - - - - - - ' '- - - - - - - - - - - - - - - - - - - - "
|
|
"- - - - -'\n"
|
|
"```"
|
|
msgstr ""
|
|
"```bob\n"
|
|
" 스택 힙\n"
|
|
".- - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - - - - "
|
|
"- -.\n"
|
|
": : : :\n"
|
|
": "
|
|
"list : : :\n"
|
|
": +------+----+----+ : : +------+----+----+ +------+----+----"
|
|
"+ :\n"
|
|
": | Cons | 1 | o--+----+-----+--->| Cons | 2 | o--+--->| Nil | // | // "
|
|
"| :\n"
|
|
": +------+----+----+ : : +------+----+----+ +------+----+----"
|
|
"+ :\n"
|
|
": : : :\n"
|
|
": : : :\n"
|
|
"'- - - - - - - - - - - - -' '- - - - - - - - - - - - - - - - - - - - - - "
|
|
"- -'\n"
|
|
"```"
|
|
|
|
#: src/smart-pointers/box.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`Box` is like `std::unique_ptr` in C++, except that it's guaranteed to be "
|
|
"not null."
|
|
msgstr ""
|
|
"`Box`는 C++의 `std::unique_ptr`과 비슷합니다. 차이라면 `Box`는 널이 아님을 보"
|
|
"장한다는 점입니다. "
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid "A `Box` can be useful when you:"
|
|
msgstr "`Box`는 아래의 경우에 유용합니다:"
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid ""
|
|
"have a type whose size that can't be known at compile time, but the Rust "
|
|
"compiler wants to know an exact size."
|
|
msgstr "타입 크기를 컴파일 시점에 알 수 없는 경우."
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid ""
|
|
"want to transfer ownership of a large amount of data. To avoid copying large "
|
|
"amounts of data on the stack, instead store the data on the heap in a `Box` "
|
|
"so only the pointer is moved."
|
|
msgstr ""
|
|
"아주 큰 데이터의 소유권을 전달하고 싶은 경우. 스택에 있는 큰 데이터를 복사하"
|
|
"는 대신 `Box`를 이용하여 데이터는 힙에 저장하고 포인터만 이동하면 됩니다."
|
|
|
|
#: src/smart-pointers/box.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"If `Box` was not used and we attempted to embed a `List` directly into the "
|
|
"`List`, the compiler would not be able to compute a fixed size for the "
|
|
"struct in memory (the `List` would be of infinite size)."
|
|
msgstr ""
|
|
"만일 `Box`를 사용하지 않고 `List`에 직접 `List`를 포함하려고 시도한다면, 컴파"
|
|
"일러는 구조체의 고정 크기를 계산할 수 없습니다. 컴파일러가 보기에 무한대의 크"
|
|
"기로 보일 것입니다."
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid ""
|
|
"`Box` solves this problem as it has the same size as a regular pointer and "
|
|
"just points at the next element of the `List` in the heap."
|
|
msgstr ""
|
|
"`Box`는 일반 포인터와 크기가 같기 때문에 크기를 계산하는 데 문제가 없습니다. "
|
|
"다만 힙에 위치한 `List`의 다음 요소를 가리킬 뿐입니다."
|
|
|
|
#: src/smart-pointers/box.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Remove the `Box` in the List definition and show the compiler error. We get "
|
|
"the message \"recursive without indirection\", because for data recursion, "
|
|
"we have to use indirection, a `Box` or reference of some kind, instead of "
|
|
"storing the value directly."
|
|
msgstr ""
|
|
"`List` 정의에서 `Box`를 제거하면 어떤 컴파일러 에러가 나오는지 같이 살펴보세"
|
|
"요. “Recursive with indirection”라는 메시지를 보면, 값을 직접 저장하는 대신 "
|
|
"`Box`나 비슷한 다른 종류의 참조 타입이 필요하다는 힌트를 얻을 수 있습니다."
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid "Niche Optimization"
|
|
msgstr "니치(틈새) 최적화(Niche Optimization)"
|
|
|
|
#: src/smart-pointers/box.md
|
|
msgid ""
|
|
"A `Box` cannot be empty, so the pointer is always valid and non-`null`. This "
|
|
"allows the compiler to optimize the memory layout:"
|
|
msgstr ""
|
|
"`Box`는 비어있을 수 없습니다. 따라서 포인터는 항상 유효하며 `null`이 아닙니"
|
|
"다. 이는 컴파일러가 메모리 레이아웃을 최적화 할 수 있게 해줍니다:"
|
|
|
|
#: src/smart-pointers/box.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"```bob\n"
|
|
" Stack Heap\n"
|
|
".- - - - - - - - - - - - - - . .- - - - - - - - - - - - - -.\n"
|
|
": : : :\n"
|
|
": list : : :\n"
|
|
": +---------+----+----+ : : +---------+----+----+ :\n"
|
|
": | Element | 1 | o--+----+-----+--->| Element | 2 | // | :\n"
|
|
": +---------+----+----+ : : +---------+----+----+ :\n"
|
|
": : : :\n"
|
|
": : : :\n"
|
|
"'- - - - - - - - - - - - - - ' '- - - - - - - - - - - - - -'\n"
|
|
"```"
|
|
msgstr ""
|
|
"```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"
|
|
"```"
|
|
|
|
#: src/smart-pointers/rc.md
|
|
msgid ""
|
|
"[`Rc`](https://doc.rust-lang.org/std/rc/struct.Rc.html) is a reference-"
|
|
"counted shared pointer. Use this when you need to refer to the same data "
|
|
"from multiple places:"
|
|
msgstr ""
|
|
"[`Rc`](https://doc.rust-lang.org/std/rc/struct.Rc.html)는 참조 카운팅 공유 포"
|
|
"인터입니다. 여러 위치에서 동일한 데이터를 참조해야할 경우 사용합니다:"
|
|
|
|
#: src/smart-pointers/rc.md
|
|
msgid "\"a: {a}\""
|
|
msgstr "\"a: {a}\""
|
|
|
|
#: src/smart-pointers/rc.md
|
|
msgid "\"b: {b}\""
|
|
msgstr "\"b: {b}\""
|
|
|
|
#: src/smart-pointers/rc.md
|
|
msgid ""
|
|
"See [`Arc`](../concurrency/shared_state/arc.md) and [`Mutex`](https://doc."
|
|
"rust-lang.org/std/sync/struct.Mutex.html) if you are in a multi-threaded "
|
|
"context."
|
|
msgstr ""
|
|
"멀티스레드 환경에서 작업하는 경우 [`Arc`](../concurrency/shared_state/arc.md)"
|
|
"와 [`Mutex`](https://doc.rust-lang.org/std/sync/struct.Mutex.html)를 참조하세"
|
|
"요."
|
|
|
|
#: src/smart-pointers/rc.md
|
|
msgid ""
|
|
"You can _downgrade_ a shared pointer into a [`Weak`](https://doc.rust-lang."
|
|
"org/std/rc/struct.Weak.html) pointer to create cycles that will get dropped."
|
|
msgstr ""
|
|
"drop 가능한 순환 구조를 만들기 위해 공유 포인터를 [`Weak`](https://doc.rust-"
|
|
"lang.org/std/rc/struct.Weak.html) 포인터로 _다운그레이드_할 수도 있습니다."
|
|
|
|
#: src/smart-pointers/rc.md
|
|
msgid ""
|
|
"`Rc`'s count ensures that its contained value is valid for as long as there "
|
|
"are references."
|
|
msgstr ""
|
|
"`Rc`는 참조 카운트를 통해 참조가 있는 동안은 `Rc`가 가리키고 있는 값이 메모리"
|
|
"에서 해제되지 않음을 보장합니다."
|
|
|
|
#: src/smart-pointers/rc.md
|
|
msgid "`Rc` in Rust is like `std::shared_ptr` in C++."
|
|
msgstr "C++의 `std::shared_ptr`와 유사합니다."
|
|
|
|
#: src/smart-pointers/rc.md
|
|
msgid ""
|
|
"`Rc::clone` is cheap: it creates a pointer to the same allocation and "
|
|
"increases the reference count. Does not make a deep clone and can generally "
|
|
"be ignored when looking for performance issues in code."
|
|
msgstr ""
|
|
"`clone`은 비용이 거의 들지 않습니다. 같은 곳을 가리키는 포인터를 하나 더 만들"
|
|
"고, 참조 카운트를 늘립니다. 포인터가 가리키는 값 자체가 복제(깊은 복제)되지"
|
|
"는 않으며, 그래서 코드에서 성능 문제가 있는지 검토할 때 일반적으로 `Rc`를 "
|
|
"`clone`하는 것은 무시할 수 있습니다."
|
|
|
|
#: src/smart-pointers/rc.md
|
|
msgid ""
|
|
"`make_mut` actually clones the inner value if necessary (\"clone-on-write\") "
|
|
"and returns a mutable reference."
|
|
msgstr ""
|
|
"`make_mut`는 실제로 필요한 경우에 내부 값을 복제하고(\"clone-on-write\") 가"
|
|
"변 참조를 반환합니다."
|
|
|
|
#: src/smart-pointers/rc.md
|
|
msgid "Use `Rc::strong_count` to check the reference count."
|
|
msgstr "참조 카운트를 확인하려면 `Rc::strong_count`를 사용하세요."
|
|
|
|
#: src/smart-pointers/rc.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`Rc::downgrade` gives you a _weakly reference-counted_ object to create "
|
|
"cycles that will be dropped properly (likely in combination with `RefCell`)."
|
|
msgstr ""
|
|
"`Rc`는 `downgrade()`로 다운그레이드하여 _약하게 참조 카운트되는(weekly "
|
|
"reference-counted)_ 객체가 될 있습니다. 그러면 순환구조라 하더라도 drop이 가"
|
|
"능합니다. (아마도 `RefCell` 을 함께 사용해야 할 것입니다.)"
|
|
|
|
#: src/smart-pointers/trait-objects.md
|
|
msgid ""
|
|
"Trait objects allow for values of different types, for instance in a "
|
|
"collection:"
|
|
msgstr ""
|
|
"트레잇 객체는 타입이 다른 값(예를 들어 컬렉션에 속한 각 값)들을 가질 수 있습"
|
|
"니다:"
|
|
|
|
#: src/smart-pointers/trait-objects.md
|
|
msgid "\"Miau!\""
|
|
msgstr "\"냐옹!\""
|
|
|
|
#: src/smart-pointers/trait-objects.md
|
|
#, fuzzy
|
|
msgid "\"Hello, who are you? {}\""
|
|
msgstr "'안녕, 넌 누구니? {}'"
|
|
|
|
#: src/smart-pointers/trait-objects.md
|
|
msgid "Memory layout after allocating `pets`:"
|
|
msgstr "`pets`를 할당한 이후의 메모리 레이아웃:"
|
|
|
|
#: src/smart-pointers/trait-objects.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"```bob\n"
|
|
" Stack Heap\n"
|
|
".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - - - "
|
|
"- -.\n"
|
|
": : : :\n"
|
|
": \"pets: Vec<dyn Pet>\" : : \"data: Cat\" +----+----+----"
|
|
"+----+ :\n"
|
|
": +-----------+-------+ : : +-------+-------+ | F | i | d | "
|
|
"o | :\n"
|
|
": | ptr | o---+---+--. : | lives | 9 | +----+----+----"
|
|
"+----+ :\n"
|
|
": | len | 2 | : | : +-------+-------+ "
|
|
"^ :\n"
|
|
": | capacity | 2 | : | : ^ "
|
|
"| :\n"
|
|
": +-----------+-------+ : | : | "
|
|
"'-------. :\n"
|
|
": : | : | data:"
|
|
"\"Dog\"| :\n"
|
|
": : | : | +-------+--|-------"
|
|
"+ :\n"
|
|
"`- - - - - - - - - - - - - -' | : +---|-+-----+ | name | o, 4, 4 "
|
|
"| :\n"
|
|
" `--+-->| o o | o o-|----->| age | 5 "
|
|
"| :\n"
|
|
" : +-|---+-|---+ +-------+----------"
|
|
"+ :\n"
|
|
" : | "
|
|
"| :\n"
|
|
" `- - -| - - |- - - - - - - - - - - - - - - "
|
|
"- -'\n"
|
|
" | |\n"
|
|
" | | "
|
|
"\"Program text\"\n"
|
|
" .- - -| - - |- - - - - - - - - - - - - - - "
|
|
"- -.\n"
|
|
" : | | "
|
|
"vtable :\n"
|
|
" : | | +----------------------"
|
|
"+ :\n"
|
|
" : | `----->| \"<Dog as Pet>::"
|
|
"talk\" | :\n"
|
|
" : | +----------------------"
|
|
"+ :\n"
|
|
" : | "
|
|
"vtable :\n"
|
|
" : | +----------------------"
|
|
"+ :\n"
|
|
" : '----------->| \"<Cat as Pet>::"
|
|
"talk\" | :\n"
|
|
" : +----------------------"
|
|
"+ :\n"
|
|
" : :\n"
|
|
" '- - - - - - - - - - - - - - - - - - - - - "
|
|
"- -'\n"
|
|
"```"
|
|
msgstr ""
|
|
"```bob\n"
|
|
" 스택 힙\n"
|
|
".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - - - "
|
|
"- -.\n"
|
|
": : : :\n"
|
|
": "
|
|
"pets : : :\n"
|
|
": +-----------+-------+ : : +-----+-----"
|
|
"+ :\n"
|
|
": | ptr | o---+---+-----+-->| o o | o o "
|
|
"| :\n"
|
|
": | len | 2 | : : +-|-|-+-|-|-"
|
|
"+ :\n"
|
|
": | capacity | 2 | : : | | | | +---------------"
|
|
"+ :\n"
|
|
": +-----------+-------+ : : | | | '-->| name: \"Fido\" "
|
|
"| :\n"
|
|
": : : | | | +---------------"
|
|
"+ :\n"
|
|
"`- - - - - - - - - - - - - -' : | | "
|
|
"| :\n"
|
|
" : | | | +----------------------"
|
|
"+ : \n"
|
|
" : | | '---->| \"<Dog as Pet>::name\" "
|
|
"| :\n"
|
|
" : | | +----------------------"
|
|
"+ : \n"
|
|
" : | "
|
|
"| : \n"
|
|
" : | | +-"
|
|
"+ : \n"
|
|
" : | '-->|"
|
|
"\\| : \n"
|
|
" : | +-"
|
|
"+ : \n"
|
|
" : "
|
|
"| : \n"
|
|
" : | +----------------------"
|
|
"+ : \n"
|
|
" : '---->| \"<Cat as Pet>::name\" "
|
|
"| : \n"
|
|
" : +----------------------"
|
|
"+ :\n"
|
|
" : :\n"
|
|
" '- - - - - - - - - - - - - - - - - - - - - "
|
|
"- -'\n"
|
|
"\n"
|
|
"```"
|
|
|
|
#: src/smart-pointers/trait-objects.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Types that implement a given trait may be of different sizes. This makes it "
|
|
"impossible to have things like `Vec<dyn Pet>` in the example above."
|
|
msgstr ""
|
|
"여러 타입이 같은 트레잇을 구현하더라도 그 크기는 서로 다를 수 있습니다. 그래"
|
|
"서 `Vec<Greeet>`같은 것은 불가능합니다."
|
|
|
|
#: src/smart-pointers/trait-objects.md
|
|
msgid ""
|
|
"`dyn Pet` is a way to tell the compiler about a dynamically sized type that "
|
|
"implements `Pet`."
|
|
msgstr ""
|
|
"`dyn Pet`이라고 하면이 타입의 크기는 동적이며 `Pet`을 구현하고 있다고 컴파일"
|
|
"러에게 알려주는 것입니다."
|
|
|
|
#: src/smart-pointers/trait-objects.md
|
|
msgid ""
|
|
"In the example, `pets` is allocated on the stack and the vector data is on "
|
|
"the heap. The two vector elements are _fat pointers_:"
|
|
msgstr ""
|
|
"이 예에서는 `pets`가 스택에 할당되고 벡터 데이터는 힙에 있습니다. 두 벡터 요"
|
|
"소는 _fat 포인터_입니다."
|
|
|
|
#: src/smart-pointers/trait-objects.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"A fat pointer is a double-width pointer. It has two components: a pointer to "
|
|
"the actual object and a pointer to the [virtual method table](https://en."
|
|
"wikipedia.org/wiki/Virtual_method_table) (vtable) for the `Pet` "
|
|
"implementation of that particular object."
|
|
msgstr ""
|
|
"예제에서 `pets`는 `Pet`을 구현하는 객체들의 _Fat 포인터_를 담고 있습니다. "
|
|
"Fat 포인터는 실제 객체에 대한 포인터와 그 객체가 `Pet`을 구현하고 있는 가상 "
|
|
"함수 테이블에 대한 포인터를 가집니다."
|
|
|
|
#: src/smart-pointers/trait-objects.md
|
|
msgid ""
|
|
"The data for the `Dog` named Fido is the `name` and `age` fields. The `Cat` "
|
|
"has a `lives` field."
|
|
msgstr ""
|
|
"이름이 Fido인 `Dog`의 데이터는 `name` 및 `age` 필드입니다. `Cat`에는 `lives` "
|
|
"필드가 있습니다."
|
|
|
|
#: src/smart-pointers/trait-objects.md
|
|
msgid "Compare these outputs in the above example:"
|
|
msgstr "아래 코드의 결과와 비교해보세요:"
|
|
|
|
#: src/smart-pointers/exercise.md
|
|
msgid ""
|
|
"A binary tree is a tree-type data structure where every node has two "
|
|
"children (left and right). We will create a tree where each node stores a "
|
|
"value. For a given node N, all nodes in a N's left subtree contain smaller "
|
|
"values, and all nodes in N's right subtree will contain larger values."
|
|
msgstr ""
|
|
"바이너리 트리는 모든 노드에 두 개의 하위 요소(왼쪽과 오른쪽)가 있는 트리 유"
|
|
"형 데이터 구조입니다. 각 노드가 값을 저장하는 트리를 만들겠습니다. 주어진 노"
|
|
"드 N의 경우 N의 왼쪽 하위 트리에 있는 모든 노드는 더 작은 값을 포함하고, N의 "
|
|
"오른쪽 하위 트리에 있는 모든 노드는 더 큰 값을 포함합니다."
|
|
|
|
#: src/smart-pointers/exercise.md
|
|
msgid "Implement the following types, so that the given tests pass."
|
|
msgstr "지정된 테스트가 통과하도록 다음 타입을 구현합니다."
|
|
|
|
#: src/smart-pointers/exercise.md
|
|
msgid ""
|
|
"Extra Credit: implement an iterator over a binary tree that returns the "
|
|
"values in order."
|
|
msgstr ""
|
|
"추가 크레딧: 값을 순서대로 반환하는 바이너리 트리에 대한 반복자를 구현합니다."
|
|
|
|
#: src/smart-pointers/exercise.md src/smart-pointers/solution.md
|
|
msgid "/// A node in the binary tree.\n"
|
|
msgstr ""
|
|
|
|
#: src/smart-pointers/exercise.md src/smart-pointers/solution.md
|
|
msgid "/// A possibly-empty subtree.\n"
|
|
msgstr ""
|
|
|
|
#: src/smart-pointers/exercise.md src/smart-pointers/solution.md
|
|
msgid ""
|
|
"/// A container storing a set of values, using a binary tree.\n"
|
|
"///\n"
|
|
"/// If the same value is added multiple times, it is only stored once.\n"
|
|
msgstr ""
|
|
"/// 바이너리 트리를 사용하여 값 집합을 저장하는 컨테이너입니다.\n"
|
|
"///\n"
|
|
"/// 동일한 값이 여러 번 추가되면 한 번만 저장됩니다.\n"
|
|
|
|
#: src/smart-pointers/exercise.md
|
|
#, fuzzy
|
|
msgid "// Implement `new`, `insert`, `len`, and `has`.\n"
|
|
msgstr "// `new`, `insert`, `has`를 구현합니다.\n"
|
|
|
|
#: src/smart-pointers/exercise.md src/smart-pointers/solution.md
|
|
msgid "// not a unique item\n"
|
|
msgstr "// 고유 항목이 아닙니다.\n"
|
|
|
|
#: src/smart-pointers/solution.md src/android/testing/googletest.md
|
|
msgid "\"bar\""
|
|
msgstr "\"bar\""
|
|
|
|
#: src/welcome-day-3-afternoon.md
|
|
msgid "[Borrowing](./borrowing.md) (50 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-3-afternoon.md
|
|
msgid ""
|
|
"[Slices and Lifetimes](./slices-and-lifetimes.md) (1 hour and 10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/borrowing.md
|
|
msgid "[Borrowing a Value](./borrowing/shared.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/borrowing.md
|
|
msgid "[Borrow Checking](./borrowing/borrowck.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/borrowing.md
|
|
msgid "[Interior Mutability](./borrowing/interior-mutability.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/borrowing.md
|
|
msgid "[Exercise: Health Statistics](./borrowing/exercise.md) (20 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/borrowing/shared.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"As we saw before, instead of transferring ownership when calling a function, "
|
|
"you can let a function _borrow_ the value:"
|
|
msgstr ""
|
|
"함수 호출시 값의 소유권을 이동하는 대신의 함수가 값을 _빌려올 수_ 있습니다:"
|
|
|
|
#: src/borrowing/shared.md
|
|
msgid "The `add` function _borrows_ two points and returns a new point."
|
|
msgstr ""
|
|
"`add` 함수는 두 `Point` 객체 값을 \\_빌려_와서 새로운 `Point` 객체를 반환합니"
|
|
"다."
|
|
|
|
#: src/borrowing/shared.md
|
|
msgid "The caller retains ownership of the inputs."
|
|
msgstr "`p1`과 `p2`의 소유권은 여전히 호출자(`main`함수)에 있습니다."
|
|
|
|
#: src/borrowing/shared.md
|
|
msgid ""
|
|
"This slide is a review of the material on references from day 1, expanding "
|
|
"slightly to include function arguments and return values."
|
|
msgstr ""
|
|
"이 슬라이드는 1일 차의 참조를 다룬 자료를 검토하는 것으로, 약간 확장되어 함"
|
|
"수 인수와 반환 값을 포함합니다."
|
|
|
|
#: src/borrowing/shared.md
|
|
msgid "Notes on stack returns:"
|
|
msgstr "스택에 할당된 값을 리턴하는 것에 대한 참고:"
|
|
|
|
#: src/borrowing/shared.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"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](https://play.rust-lang.org/?"
|
|
"version=stable&mode=release&edition=2021&gist=0cb13be1c05d7e3446686ad9947c4671) "
|
|
"or look at the assembly in [Godbolt](https://rust.godbolt.org/). In the "
|
|
"\"DEBUG\" optimization level, the addresses should change, while they stay "
|
|
"the same when changing to the \"RELEASE\" setting:"
|
|
msgstr ""
|
|
"`add`에서 값을 반환하는 것은 매우 값이 싸다는 것을 설명하세요. 왜냐하면, 컴파"
|
|
"일러가 복사 과정을 생략할 수 있기 때문입니다. 위 코드를 스택 주소를 출력하도"
|
|
"록 수정하고 [Playground](https://play.rust-lang.org/)에서 수행해 보세요. 또"
|
|
"는 [Godbolt](https://rust.godbolt.org/)에서 어셈블리를 확인해 보세요. 최적화 "
|
|
"레벨이 \"DEBUG\" 일 때에는 주소가 바뀌지만, \"RELEASE\" 레벨에서는 바뀌지 않"
|
|
"습니다:"
|
|
|
|
#: src/borrowing/shared.md
|
|
msgid "The Rust compiler can do return value optimization (RVO)."
|
|
msgstr "러스트 컴파일러는 반환값 최적화(RVO)를 수행할 수 있습니다."
|
|
|
|
#: src/borrowing/shared.md
|
|
msgid ""
|
|
"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 perform a simple and efficient `memcpy` "
|
|
"copy."
|
|
msgstr ""
|
|
"C++에서 copy elision은 생성자의 부수효과 가능성이 있어 언어레벨의 정의가 필요"
|
|
"하지만 러스트에서는 문제가 되지 않습니다. 만약 RVO가 발생하지 않으면 러스트"
|
|
"는 항상 간단하고 효율적인 `memcpy`복사를 수행할 것입니다."
|
|
|
|
#: src/borrowing/borrowck.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Rust's _borrow checker_ puts constraints on the ways you can borrow values. "
|
|
"For a given value, at any time:"
|
|
msgstr "러스트에서는 값을 빌릴 때 다음과 같은 제약조건이 있습니다:"
|
|
|
|
#: src/borrowing/borrowck.md
|
|
#, fuzzy
|
|
msgid "You can have one or more shared references to the value, _or_"
|
|
msgstr "한번에 하나 이상의 `&T` 값을 가지거나, _또는_"
|
|
|
|
#: src/borrowing/borrowck.md
|
|
#, fuzzy
|
|
msgid "You can have exactly one exclusive reference to the value."
|
|
msgstr "정확히 하나의 `&mut T` 값만을 가질 수 있습니다."
|
|
|
|
#: src/borrowing/borrowck.md
|
|
msgid ""
|
|
"Note that the requirement is that conflicting references not _exist_ at the "
|
|
"same point. It does not matter where the reference is dereferenced."
|
|
msgstr ""
|
|
"충돌하는 참조가 같은 지점에 _존재_해서는 안 됩니다. 참조가 역참조되는 위치는 "
|
|
"중요하지 않습니다."
|
|
|
|
#: src/borrowing/borrowck.md
|
|
msgid ""
|
|
"The above code does not compile because `a` is borrowed as mutable (through "
|
|
"`c`) and as immutable (through `b`) at the same time."
|
|
msgstr ""
|
|
"위 코드 컴파일 되지 않습니다. 왜냐하면 `c`는 `a`를 가변 변수로 빌렸고, 이와 "
|
|
"동시에 `b`는 `a`를 불변 변수로 빌렸기 때문입니다."
|
|
|
|
#: src/borrowing/borrowck.md
|
|
msgid ""
|
|
"Move the `println!` statement for `b` before the scope that introduces `c` "
|
|
"to make the code compile."
|
|
msgstr ""
|
|
"`b`에 대한 `println!` 구분을 `c`가 있는 스코프 앞으로 이동하면 컴파일이 됩니"
|
|
"다."
|
|
|
|
#: src/borrowing/borrowck.md
|
|
msgid ""
|
|
"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`가 사용된"
|
|
"다는 것을 확인할 수 있습니다. 빌림 검사기의 이러한 기능을 \"non-lexical "
|
|
"lifetime\" 이라고 합니다."
|
|
|
|
#: src/borrowing/borrowck.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The exclusive reference constraint is quite strong. Rust uses it to ensure "
|
|
"that data races do not occur. Rust also _relies_ on this constraint to "
|
|
"optimize code. For example, a value behind a shared reference can be safely "
|
|
"cached in a register for the lifetime of that reference."
|
|
msgstr ""
|
|
"배타적인 참조 제약 조건은 매우 강력합니다. Rust는 이를 사용하여 데이터 경합"
|
|
"이 발생하지 않도록 합니다. Rust는 또한 이 제약 조건을 _사용_하여 코드를 최적"
|
|
"화합니다. 예를 들어 공유 참조 뒤에 있는 값은 해당 참조의 수명 동안 레지스터"
|
|
"에 안전하게 캐시될 수 있습니다."
|
|
|
|
#: src/borrowing/borrowck.md
|
|
msgid ""
|
|
"The borrow checker is designed to accommodate many common patterns, such as "
|
|
"taking exclusive references to different fields in a struct at the same "
|
|
"time. But, there are some situations where it doesn't quite \"get it\" and "
|
|
"this often results in \"fighting with the borrow checker.\""
|
|
msgstr ""
|
|
"빌림 검사기는 구조체의 여러 필드에 대한 배타적 참조를 동시에 가져오는 등 여"
|
|
"러 일반적인 패턴을 수용하도록 설계되었습니다. 하지만 제대로 \"인식\"하지 못"
|
|
"해 \"빌림 검사기와의 충돌\"이 발생하는 경우도 있습니다."
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
msgid ""
|
|
"In some situations, it's necessary to modify data behind a shared (read-"
|
|
"only) reference. For example, a shared data structure might have an internal "
|
|
"cache, and wish to update that cache from read-only methods."
|
|
msgstr ""
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
msgid ""
|
|
"The \"interior mutability\" pattern allows exclusive (mutable) access behind "
|
|
"a shared reference. The standard library provides several ways to do this, "
|
|
"all while still ensuring safety, typically by performing a runtime check."
|
|
msgstr ""
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
#, fuzzy
|
|
msgid "`RefCell`"
|
|
msgstr "`RefCell<T>`"
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
msgid "\"graph: {root:#?}\""
|
|
msgstr "\"그래프: {root:#?}\""
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
msgid "\"graph sum: {}\""
|
|
msgstr "\"그래프 합계: {}\""
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
#, fuzzy
|
|
msgid "`Cell`"
|
|
msgstr "`Cell<T>`"
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
msgid ""
|
|
"`Cell` wraps a value and allows getting or setting the value, even with a "
|
|
"shared reference to the `Cell`. However, it does not allow any references to "
|
|
"the value. Since there are no references, borrowing rules cannot be broken."
|
|
msgstr ""
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
msgid ""
|
|
"The main thing to take away from this slide is that Rust provides _safe_ "
|
|
"ways to modify data behind a shared reference. There are a variety of ways "
|
|
"to ensure that safety, and `RefCell` and `Cell` are two of them."
|
|
msgstr ""
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
msgid ""
|
|
"`RefCell` enforces Rust's usual borrowing rules (either multiple shared "
|
|
"references or a single exclusive reference) with a runtime check. In this "
|
|
"case, all borrows are very short and never overlap, so the checks always "
|
|
"succeed."
|
|
msgstr ""
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
msgid ""
|
|
"`Rc` only allows shared (read-only) access to its contents, since its "
|
|
"purpose is to allow (and count) many references. But we want to modify the "
|
|
"value, so we need interior mutability."
|
|
msgstr ""
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
msgid ""
|
|
"`Cell` is a simpler means to ensure safety: it has a `set` method that takes "
|
|
"`&self`. This needs no runtime check, but requires moving values, which can "
|
|
"have its own cost."
|
|
msgstr ""
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Demonstrate that reference loops can be created by adding `root` to `subtree."
|
|
"children`."
|
|
msgstr ""
|
|
"`root`를 `subtree.children`에 추가해서 순환 참조가 생길 수 있음을 보여주세요 "
|
|
"(그래프를 출력하지는 마세요!)."
|
|
|
|
#: src/borrowing/interior-mutability.md
|
|
msgid ""
|
|
"To demonstrate a runtime panic, add a `fn inc(&mut self)` that increments "
|
|
"`self.value` and calls the same method on its children. This will panic in "
|
|
"the presence of the reference loop, with `thread 'main' panicked at 'already "
|
|
"borrowed: BorrowMutError'`."
|
|
msgstr ""
|
|
"`self.value`를 증가시키는 메서드인`fn inc(&mut self)`를 추가하고 그 메서드를 "
|
|
"자식노드에서 호출하세요. 그러면 `thread 'main' panicked at 'already "
|
|
"borrowed: BorrowMutError'` 런타임 패닉이 발생함을 보이세요."
|
|
|
|
#: src/borrowing/exercise.md
|
|
msgid ""
|
|
"You're working on implementing a health-monitoring system. As part of that, "
|
|
"you need to keep track of users' health statistics."
|
|
msgstr ""
|
|
"당신은 건강 상태를 모니터링하는 시스템을 구현하는 일을 하고 있습니다. 그 일환"
|
|
"으로 당신은 사용자의 건강 상태 통계를 추적해야합니다."
|
|
|
|
#: src/borrowing/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"You'll start with a stubbed function in an `impl` block as well as a `User` "
|
|
"struct definition. Your goal is to implement the stubbed out method on the "
|
|
"`User` `struct` defined in the `impl` block."
|
|
msgstr ""
|
|
"당신의 목표는 `User` 구조체의 `impl` 블록의 빈 함수를 구현하는 것입니다."
|
|
|
|
#: src/borrowing/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Copy the code below to <https://play.rust-lang.org/> and fill in the missing "
|
|
"method:"
|
|
msgstr ""
|
|
"아래 코드를 <https://play.rust-lang.org/>에 복사해서 빠진 메서드를 구현하면 "
|
|
"됩니다:"
|
|
|
|
#: src/borrowing/exercise.md
|
|
msgid ""
|
|
"\"Update a user's statistics based on measurements from a visit to the "
|
|
"doctor\""
|
|
msgstr "\"병원 방문에 따른 측정값을 기반으로 사용자 통계를 업데이트합니다.\""
|
|
|
|
#: src/borrowing/exercise.md src/borrowing/solution.md
|
|
#: src/android/build-rules/library.md
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid "\"Bob\""
|
|
msgstr "\"Bob\""
|
|
|
|
#: src/borrowing/exercise.md src/borrowing/solution.md
|
|
msgid "\"I'm {} and my age is {}\""
|
|
msgstr "\"저는 {}이고, 나이는 {}세입니다.\""
|
|
|
|
#: src/slices-and-lifetimes.md
|
|
msgid "[Slices: &\\[T\\]](./slices-and-lifetimes/slices.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/slices-and-lifetimes.md
|
|
msgid "[String References](./slices-and-lifetimes/str.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/slices-and-lifetimes.md
|
|
msgid ""
|
|
"[Lifetime Annotations](./slices-and-lifetimes/lifetime-annotations.md) (10 "
|
|
"minutes)"
|
|
msgstr ""
|
|
|
|
#: src/slices-and-lifetimes.md
|
|
msgid ""
|
|
"[Lifetime Elision](./slices-and-lifetimes/lifetime-elision.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/slices-and-lifetimes.md
|
|
msgid ""
|
|
"[Struct Lifetimes](./slices-and-lifetimes/struct-lifetimes.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/slices-and-lifetimes.md
|
|
msgid ""
|
|
"[Exercise: Protobuf Parsing](./slices-and-lifetimes/exercise.md) (30 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/slices-and-lifetimes.md
|
|
msgid "This segment should take about 1 hour and 10 minutes"
|
|
msgstr ""
|
|
|
|
#: src/slices-and-lifetimes/slices.md
|
|
msgid "Slices"
|
|
msgstr "슬라이스"
|
|
|
|
#: src/slices-and-lifetimes/slices.md
|
|
msgid "A slice gives you a view into a larger collection:"
|
|
msgstr "슬라이스는 큰 컬랙션의 일부(혹은 전체)를 보여주는 뷰(view)입니다:"
|
|
|
|
#: src/slices-and-lifetimes/slices.md
|
|
msgid "Slices borrow data from the sliced type."
|
|
msgstr "슬라이스는 다른(슬라이스 된) 타입으로부터 데이터를 '빌려'옵니다."
|
|
|
|
#: src/slices-and-lifetimes/slices.md
|
|
msgid "Question: What happens if you modify `a[3]` right before printing `s`?"
|
|
msgstr "질문: `s`를 출력하기 전에 `a[3]`을 수정하면 무슨 일이 있어날까요?"
|
|
|
|
#: src/slices-and-lifetimes/slices.md
|
|
msgid ""
|
|
"We create a slice by borrowing `a` and specifying the starting and ending "
|
|
"indexes in brackets."
|
|
msgstr ""
|
|
"슬라이스는 우선 `a`를 빌린다음, 시작과 끝 인덱스를 브래킷(`[]`)안에 지정해서 "
|
|
"만듭니다."
|
|
|
|
#: src/slices-and-lifetimes/slices.md
|
|
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."
|
|
msgstr ""
|
|
"슬라이스가 인덱스 0부터 시작한다면 시작 인덱스는 생략 가능합니다. 즉 `&a[0.."
|
|
"a.len()]`와 `&a[..a.len()]` 는 동일합니다."
|
|
|
|
#: src/slices-and-lifetimes/slices.md
|
|
msgid ""
|
|
"The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are "
|
|
"identical."
|
|
msgstr ""
|
|
"마지막 인덱스도 생략 가능합니다. 그래서 `&a[2..a.len()]` 와 `&a[2..]`는 동일"
|
|
"합니다."
|
|
|
|
#: src/slices-and-lifetimes/slices.md
|
|
msgid ""
|
|
"To easily create a slice of the full array, we can therefore use `&a[..]`."
|
|
msgstr "따라서 전체 배열에 대한 슬라이스는 `&a[..]`가 됩니다."
|
|
|
|
#: src/slices-and-lifetimes/slices.md
|
|
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."
|
|
msgstr ""
|
|
"`s`는 `i32`들로 이루어진 슬라이스에 대한 참조입니다. `s`의 타입(`&[i32]`)에 "
|
|
"배열의 크기가 빠져있음에 주목하시기 바랍니다. 즉, 슬라이스를 이용하면 다양한 "
|
|
"길이의 데이터를 다룰 수 있습니다."
|
|
|
|
#: src/slices-and-lifetimes/slices.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Slices always borrow from another object. In this example, `a` has to remain "
|
|
"'alive' (in scope) for at least as long as our slice."
|
|
msgstr ""
|
|
"슬라이스는 항상 다른 객체로부터 '빌려' 옵니다. 이 예시에서 객체 `a`는 슬라이"
|
|
"스 `s`보다 더 오래 살아 있어야만 합니다. "
|
|
|
|
#: src/slices-and-lifetimes/slices.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The question about modifying `a[3]` can spark an interesting discussion, but "
|
|
"the answer is that for memory safety reasons you cannot do it through `a` at "
|
|
"this point in the execution, but you can read the data from both `a` and `s` "
|
|
"safely. It works before you created the slice, and again after the "
|
|
"`println`, when the slice is no longer used."
|
|
msgstr ""
|
|
"`a[3]`의 값을 바꿀 수 있냐는 질문은 좋은 질문입니다. 여기에 대한 답은 `a`와 "
|
|
"`s`를 통해 데이터를 읽을 수는 있지만 수정할 수는 없으며, 이는 메모리 안전을 "
|
|
"위해서라는 것입니다. 그런데, 슬라이스가 사용되지 않을 때, 즉 슬라이스를 만들"
|
|
"기 전이나, 혹은 `println`이후에는 `a[3]`을 바꿀 수 있습니다. 왜 그런지에 대"
|
|
"한 좀더 구체적인 답은 빌림 검사 부분에서 자세히 설명합니다."
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
msgid ""
|
|
"We can now understand the two string types in Rust: `&str` is almost like "
|
|
"`&[char]`, but with its data stored in a variable-length encoding (UTF-8)."
|
|
msgstr ""
|
|
"이제 Rust의 두 가지 문자열 타입을 이해할 수 있습니다. `&str`은 거의 `&[char]`"
|
|
"와 비슷하지만 데이터가 가변 길이 인코딩(UTF-8)으로 저장됩니다."
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
msgid "\"s1: {s1}\""
|
|
msgstr "\"s1: {s1}\""
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
msgid "\"Hello \""
|
|
msgstr "\"Hello \""
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
msgid "\"s3: {s3}\""
|
|
msgstr "\"s3: {s3}\""
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
msgid "Rust terminology:"
|
|
msgstr "러스트 용어:"
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
msgid "`&str` an immutable reference to a string slice."
|
|
msgstr "`&str`은 문자열 슬라이스에 대한 (불변) 참조입니다."
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
msgid "`String` a mutable string buffer."
|
|
msgstr "`String`은 문자열을 담을 수 있는 버퍼입니다."
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
msgid ""
|
|
"`&str` introduces a string slice, which is an immutable reference to UTF-8 "
|
|
"encoded string data stored in a block of memory. String literals "
|
|
"(`”Hello”`), are stored in the program’s binary."
|
|
msgstr ""
|
|
"`&str`은 문자열 슬라이스입니다. 문자열 슬라이스는 UTF-8로 인코딩된 문자열 데"
|
|
"이터를 의미합니다. 문자열 리터럴(`\"Hello\"`)은 프로그램 바이너리에 저장됩니"
|
|
"다."
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
msgid ""
|
|
"Rust’s `String` type is a wrapper around a vector of bytes. As with a "
|
|
"`Vec<T>`, it is owned."
|
|
msgstr ""
|
|
"러스트의 `String`타입은 실제로는 문자열을 이루는 바이트에 대한 백터"
|
|
"(`Vec<u8>`)입니다. `Vec<T>`가 `T`를 소유하고 있듯이, `String`이 가리키고 있"
|
|
"는 문자열은 `String`의 소유입니다."
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"As with many other types `String::from()` creates a string from a string "
|
|
"literal; `String::new()` creates a new empty string, to which string data "
|
|
"can be added using the `push()` and `push_str()` methods."
|
|
msgstr ""
|
|
"다른 많은 타입들처럼 `String::from`는 문자열 리터럴로부터 문자열을 생성합니"
|
|
"다. `String::new()`는 새로운 빈 문자열을 생성합니다. `push()`와 `push_str()`"
|
|
"메서드를 사용하여 문자열 데이터를 추가 할 수 있습니다."
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The `format!()` macro is a convenient way to generate an owned string from "
|
|
"dynamic values. It accepts the same format specification as `println!()`."
|
|
msgstr ""
|
|
"`format!()` 매크로는 변수의 값을 문자열로 변환하는 편리한 방법입니다. 이 매크"
|
|
"로는 `println!()` 매크로와 동일한 포맷팅 형식을 지원합니다."
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"You can borrow `&str` slices from `String` via `&` and optionally range "
|
|
"selection. If you select a byte range that is not aligned to character "
|
|
"boundaries, the expression will panic. The `chars` iterator iterates over "
|
|
"characters and is preferred over trying to get character boundaries right."
|
|
msgstr ""
|
|
"`&` 및 선택적으로 범위 선택을 통해 `String`에서 `&str` 슬라이스를 빌릴 수 있"
|
|
"습니다. 문자 경계 범위를 올바로 선택하는 것보다, 문자 단위로 동작하는 "
|
|
"`chars` 반복자를 사용하는 것이 좋습니다."
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"For C++ programmers: think of `&str` as `std::string_view` from C++, but the "
|
|
"one that always points to a valid string in memory. Rust `String` is a rough "
|
|
"equivalent of `std::string` from C++ (main difference: it can only contain "
|
|
"UTF-8 encoded bytes and will never use a small-string optimization)."
|
|
msgstr ""
|
|
"당신이 C++ 프로그래머 라면: `&str`는 C++의 `const char*`와 유사하지만 항상 유"
|
|
"효한 문자열을 가리킨다는 점이 다릅니다. 러스트의 `String`은 C++의 `std::"
|
|
"string` 과 대략 거의 동일합니다. (주요 차이점: 러스트의 `String`은 UTF-8 인코"
|
|
"딩 바이트만 포함할 수 있으며 작은 문자열 최적화(small-string optimization)는 "
|
|
"구현하지 않습니다."
|
|
|
|
#: src/slices-and-lifetimes/str.md
|
|
#, fuzzy
|
|
msgid "Byte strings literals allow you to create a `&[u8]` value directly:"
|
|
msgstr "Byte strings allow you to create a `&[u8]` value directly:"
|
|
|
|
#: src/slices-and-lifetimes/lifetime-annotations.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"A reference has a _lifetime_, which must not \"outlive\" the value it refers "
|
|
"to. This is verified by the borrow checker."
|
|
msgstr ""
|
|
"참조에는 참조하는 값보다 '오래 지속'되어야 하는 _수명_이 있습니다. 이는 빌림 "
|
|
"검사기에서 확인합니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-annotations.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The lifetime can be implicit - this is what we have seen so far. Lifetimes "
|
|
"can also be explicit: `&'a Point`, `&'document str`. Lifetimes start with "
|
|
"`'` and `'a` is a typical default name. Read `&'a Point` as \"a borrowed "
|
|
"`Point` which is valid for at least the lifetime `a`\"."
|
|
msgstr ""
|
|
"수명은 암시적으로 표현할 수 있습니다 - 지금까지 이러한 경우들을 살펴보았습니"
|
|
"다. 수명을 다음과 같이 명시적으로 표현할 수도 있습니다: &'a Point, "
|
|
"&'document str. 수명은 ' 기호를 시작하며 일반적으로 'a 라는 이름을 사용합니"
|
|
"다. &'a Point는 \"최소한 a의 수명만큼 유효한 Point의 참조\"라고 이해할 수 있"
|
|
"습니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-annotations.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Lifetimes are always inferred by the compiler: you cannot assign a lifetime "
|
|
"yourself. Explicit lifetime annotations create constraints where there is "
|
|
"ambiguity; the compiler verifies that there is a valid solution."
|
|
msgstr ""
|
|
"수명 표기(`'`)은 수명 추론시 제약조건이 됩니다. 컴파일러는 이 제약조건을 만족"
|
|
"시키는 유요한 수명을 추론할 수 있는지 검사를 합니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-annotations.md
|
|
msgid ""
|
|
"Lifetimes become more complicated when considering passing values to and "
|
|
"returning values from functions."
|
|
msgstr ""
|
|
"수명은 함수에 값을 전달하고 함수에서 값을 반환하는 경우를 고려할 때 더 복잡해"
|
|
"집니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-annotations.md
|
|
msgid "// What is the lifetime of p3?\n"
|
|
msgstr "// p3의 수명은 어떻게 되나요?\n"
|
|
|
|
#: src/slices-and-lifetimes/lifetime-annotations.md
|
|
msgid "\"p3: {p3:?}\""
|
|
msgstr "\"p3: {p3:?}\""
|
|
|
|
#: src/slices-and-lifetimes/lifetime-annotations.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"In this example, the compiler does not know what lifetime to infer for `p3`. "
|
|
"Looking inside the function body shows that it can only safely assume that "
|
|
"`p3`'s lifetime is the shorter of `p1` and `p2`. But just like types, Rust "
|
|
"requires explicit annotations of lifetimes on function arguments and return "
|
|
"values."
|
|
msgstr ""
|
|
"이 예에서 컴파일러는 'p3'에 관해 어떤 수명을 추론할지 알지 못합니다. 함수 본"
|
|
"문을 살펴보면 `p3`의 수명이 `p1`과 `p2`보다 더 짧다고만 가정할 수 있다는 것"
|
|
"을 알 수 있습니다. 그러나 타입과 마찬가지로 Rust는 함수 인수와 반환 값에 관"
|
|
"한 수명의 명시적 주석이 필요합니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-annotations.md
|
|
msgid "Add `'a` appropriately to `left_most`:"
|
|
msgstr "`'a`를 `left_most`에 적절하게 추가합니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-annotations.md
|
|
msgid ""
|
|
"This says, \"given p1 and p2 which both outlive `'a`, the return value lives "
|
|
"for at least `'a`."
|
|
msgstr ""
|
|
"즉, \"`a`보다 오래 지속되는 p1과 p2가 있으면 반환 값은 최소한 `'a` 동안 유지"
|
|
"됩니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-annotations.md
|
|
msgid ""
|
|
"In common cases, lifetimes can be elided, as described on the next slide."
|
|
msgstr "일반적으로 수명은 다음 슬라이드에 설명된 대로 생략될 수 있습니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-elision.md
|
|
msgid "Lifetimes in Function Calls"
|
|
msgstr "함수 호출에서의 수명"
|
|
|
|
#: src/slices-and-lifetimes/lifetime-elision.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Lifetimes for function arguments and return values must be fully specified, "
|
|
"but Rust allows lifetimes to be elided in most cases with [a few simple "
|
|
"rules](https://doc.rust-lang.org/nomicon/lifetime-elision.html). This is not "
|
|
"inference -- it is just a syntactic shorthand."
|
|
msgstr ""
|
|
"원래, 함수의 인자와 리턴값에는 수명을 설정해야 합니다. 그러나 [몇 가지 조건]"
|
|
"(https://doc.rust-lang.org/nomicon/lifetime-elision.html)을 만족하는 대부분"
|
|
"의 경우에는 생략할 수 있습니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-elision.md
|
|
msgid "Each argument which does not have a lifetime annotation is given one."
|
|
msgstr "수명 주석이 없는 각 인수에 하나씩 제공됩니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-elision.md
|
|
msgid ""
|
|
"If there is only one argument lifetime, it is given to all un-annotated "
|
|
"return values."
|
|
msgstr ""
|
|
"인수 수명이 하나만 있는 경우 주석 처리되지 않은 모든 반환 값에 제공됩니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-elision.md
|
|
msgid ""
|
|
"If there are multiple argument lifetimes, but the first one is for `self`, "
|
|
"that lifetime is given to all un-annotated return values."
|
|
msgstr ""
|
|
"인수 수명이 여러 개 있지만 첫 번째가 'self'의 수명이면 해당 전체 기간은 주석 "
|
|
"처리되지 않은 모든 반환 값에 제공됩니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-elision.md
|
|
msgid "In this example, `cab_distance` is trivially elided."
|
|
msgstr "이 예에서 `cab_distance`는 간단히 생략됩니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-elision.md
|
|
msgid ""
|
|
"The `nearest` function provides another example of a function with multiple "
|
|
"references in its arguments that requires explicit annotation."
|
|
msgstr ""
|
|
"`nearest` 함수는 인수에 여러 참조가 포함되어 명시적 주석이 필요한 함수의 또 "
|
|
"다른 예를 제공합니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-elision.md
|
|
msgid "Try adjusting the signature to \"lie\" about the lifetimes returned:"
|
|
msgstr "반환된 수명에 관해 '거짓말'하도록 서명을 조정해 보세요."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-elision.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"This won't compile, demonstrating that the annotations are checked for "
|
|
"validity by the compiler. Note that this is not the case for raw pointers "
|
|
"(unsafe), and this is a common source of errors with unsafe Rust."
|
|
msgstr ""
|
|
"이는 컴파일되지 않아 컴파일러가 주석의 유효성을 검사함을 보여줍니다. 이는 원"
|
|
"시 포인터(안전하지 않음)의 경우에는 적용되지 않으며 안전하지 않은 Rust에서 발"
|
|
"생하는 일반적인 오류의 원인입니다."
|
|
|
|
#: src/slices-and-lifetimes/lifetime-elision.md
|
|
msgid ""
|
|
"Students may ask when to use lifetimes. Rust borrows _always_ have "
|
|
"lifetimes. Most of the time, elision and type inference mean these don't "
|
|
"need to be written out. In more complicated cases, lifetime annotations can "
|
|
"help resolve ambiguity. Often, especially when prototyping, it's easier to "
|
|
"just work with owned data by cloning values where necessary."
|
|
msgstr ""
|
|
|
|
#: src/slices-and-lifetimes/struct-lifetimes.md
|
|
msgid "Lifetimes in Data Structures"
|
|
msgstr "구조체에서의 수명"
|
|
|
|
#: src/slices-and-lifetimes/struct-lifetimes.md
|
|
msgid ""
|
|
"If a data type stores borrowed data, it must be annotated with a lifetime:"
|
|
msgstr ""
|
|
"어떤 타입이 빌려온 데이터를 저장하고 있다면, 반드시 수명을 표시해야 합니다:"
|
|
|
|
#: src/slices-and-lifetimes/struct-lifetimes.md
|
|
msgid "\"Bye {text}!\""
|
|
msgstr "\"안녕 {text}!\""
|
|
|
|
#: src/slices-and-lifetimes/struct-lifetimes.md
|
|
msgid "\"The quick brown fox jumps over the lazy dog.\""
|
|
msgstr "\"The quick brown fox jumps over the lazy dog.\""
|
|
|
|
#: src/slices-and-lifetimes/struct-lifetimes.md
|
|
msgid "// erase(text);\n"
|
|
msgstr "// erase(text);\n"
|
|
|
|
#: src/slices-and-lifetimes/struct-lifetimes.md
|
|
msgid "\"{fox:?}\""
|
|
msgstr "\"{fox:?}\""
|
|
|
|
#: src/slices-and-lifetimes/struct-lifetimes.md
|
|
msgid "\"{dog:?}\""
|
|
msgstr "\"{dog:?}\""
|
|
|
|
#: src/slices-and-lifetimes/struct-lifetimes.md
|
|
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."
|
|
msgstr ""
|
|
"위의 예제에서 `Highlight`의 어노테이션(`<'doc>`)은 적어도 `Highlight` 인스턴"
|
|
"스가 살아있는 동안에는 그 내부의 `&str`가 가리키는 데이터 역시 살아있어야 한"
|
|
"다는 것을 의미합니다."
|
|
|
|
#: src/slices-and-lifetimes/struct-lifetimes.md
|
|
msgid ""
|
|
"If `text` is consumed before the end of the lifetime of `fox` (or `dog`), "
|
|
"the borrow checker throws an error."
|
|
msgstr ""
|
|
"만약 `text`가 `fox` (혹은 `dog`)의 수명이 다하기 전에 `erase`함수 호출 등으"
|
|
"로 사라지게 된다면 빌림 검사기가 에러를 발생합니다."
|
|
|
|
#: src/slices-and-lifetimes/struct-lifetimes.md
|
|
msgid ""
|
|
"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."
|
|
msgstr ""
|
|
"빌린 데이터를 가지고 있는 타입은 사용자로 하여금 원본 데이터를 유지하도록 강"
|
|
"제합니다. 이런 타입은 경량 뷰(lightweight view)를 만드는데 유용하지만, 이 제"
|
|
"약 조건 때문에 이런 타입을 사용하는 것이 쉽지만은 않습니다."
|
|
|
|
#: src/slices-and-lifetimes/struct-lifetimes.md
|
|
msgid "When possible, make data structures own their data directly."
|
|
msgstr ""
|
|
"따라서, 가능하다면, 구조체가 자신의 데이터를 직접 소유하도록 하는 것이 좋습니"
|
|
"다."
|
|
|
|
#: src/slices-and-lifetimes/struct-lifetimes.md
|
|
msgid ""
|
|
"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."
|
|
msgstr ""
|
|
"한 구조체안에 여러 참조가 있으면서, 이 참조들의 수명이 서로 다르게 지정되는 "
|
|
"경우도 있습니다. 이는 참조와 그 구조체 간의 관계 뿐만이 아니라, 그 참조들 사"
|
|
"이의 수명 관계를 설명해야 할 경우에 필요합니다. 매우 고급 기술입니다."
|
|
|
|
#: src/slices-and-lifetimes/exercise.md
|
|
msgid ""
|
|
"In this exercise, you will build a parser for the [protobuf binary encoding]"
|
|
"(https://protobuf.dev/programming-guides/encoding/). Don't worry, it's "
|
|
"simpler than it seems! This illustrates a common parsing pattern, passing "
|
|
"slices of data. The underlying data itself is never copied."
|
|
msgstr ""
|
|
"이 연습에서는 [protobuf 바이너리 인코딩](https://protobuf.dev/programming-"
|
|
"guides/encoding/)용 파서를 빌드합니다. 생각보다 간단합니다. 이는 데이터 슬라"
|
|
"이스를 전달하는 일반적인 파싱 패턴을 보여줍니다. 기본 데이터 자체는 복사되지 "
|
|
"않습니다."
|
|
|
|
#: src/slices-and-lifetimes/exercise.md
|
|
msgid ""
|
|
"Fully parsing a protobuf message requires knowing the types of the fields, "
|
|
"indexed by their field numbers. That is typically provided in a `proto` "
|
|
"file. In this exercise, we'll encode that information into `match` "
|
|
"statements in functions that get called for each field."
|
|
msgstr ""
|
|
"protobuf 메시지를 완전히 파싱하려면 필드 번호로 색인이 생성된 필드의 타입을 "
|
|
"알아야 합니다. 이는 일반적으로 `proto` 파일에 제공됩니다. 이 연습에서는 이러"
|
|
"한 정보를 각 필드에 대해 호출되는 함수의 `match` 문으로 인코딩합니다."
|
|
|
|
#: src/slices-and-lifetimes/exercise.md
|
|
msgid "We'll use the following proto:"
|
|
msgstr "다음 proto를 사용합니다."
|
|
|
|
#: src/slices-and-lifetimes/exercise.md
|
|
msgid ""
|
|
"A proto message is encoded as a series of fields, one after the next. Each "
|
|
"is implemented as a \"tag\" followed by the value. The tag contains a field "
|
|
"number (e.g., `2` for the `id` field of a `Person` message) and a wire type "
|
|
"defining how the payload should be determined from the byte stream."
|
|
msgstr ""
|
|
"proto 메시지는 일련의 필드로 차례로 인코딩됩니다. 각각은 값이 뒤에 오는 '태"
|
|
"그'로 구현됩니다. 태그에는 필드 번호(예: `Person` 메시지의 `id` 필드에 대한 "
|
|
"`2`) 및 바이트 스트림에서 페이로드를 결정하는 방법을 정의하는 와이어 타입이 "
|
|
"포함됩니다."
|
|
|
|
#: src/slices-and-lifetimes/exercise.md
|
|
msgid ""
|
|
"Integers, including the tag, are represented with a variable-length encoding "
|
|
"called VARINT. Luckily, `parse_varint` is defined for you below. The given "
|
|
"code also defines callbacks to handle `Person` and `PhoneNumber` fields, and "
|
|
"to parse a message into a series of calls to those callbacks."
|
|
msgstr ""
|
|
"태그를 포함한 정수는 VARINT라는 가변 길이 인코딩으로 표시됩니다. 다행히 "
|
|
"`parse_varint`는 아래에 정의되어 있습니다. 또한 제공된 코드는 콜백을 정의하"
|
|
"여 `Person` 및 `PhoneNumber` 필드를 처리하고 메시지를 이러한 콜백에 대한 일련"
|
|
"의 호출로 파싱합니다."
|
|
|
|
#: src/slices-and-lifetimes/exercise.md
|
|
msgid ""
|
|
"What remains for you is to implement the `parse_field` function and the "
|
|
"`ProtoMessage` trait for `Person` and `PhoneNumber`."
|
|
msgstr ""
|
|
"이제 `parse_field` 함수를 구현하고 `Person`과 `PhoneNumber` 구조체애 대해 "
|
|
"`ProtoMessage` 트레잇만 구현하면 됩니다."
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "\"Invalid varint\""
|
|
msgstr "\"잘못된 varint\""
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "\"Invalid wire-type\""
|
|
msgstr "\"잘못된 wire-type\""
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "\"Unexpected EOF\""
|
|
msgstr "\"예상치 못한 EOF\""
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "\"Invalid length\""
|
|
msgstr "\"잘못된 길이\""
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "\"Unexpected wire-type)\""
|
|
msgstr "\"예상치 못한 wire-type\""
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "\"Invalid string (not UTF-8)\""
|
|
msgstr "\"잘못된 문자열(UTF-8 아님)\""
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "/// A wire type as seen on the wire.\n"
|
|
msgstr "/// 와이어에 표시된 와이어 타입입니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "/// The Varint WireType indicates the value is a single VARINT.\n"
|
|
msgstr "/// Varint WireType은 값이 단일 VARINT임을 나타냅니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"//I64, -- not needed for this exercise\n"
|
|
" /// The Len WireType indicates that the value is a length represented as "
|
|
"a\n"
|
|
" /// VARINT followed by exactly that number of bytes.\n"
|
|
msgstr ""
|
|
"//I64, -- 이 연습에는 필요하지 않습니다.\n"
|
|
" /// Len WireType은 값이 VARINT로 표시되는 길이임을 나타냅니다.\n"
|
|
" /// 뒤에 정확하게 해당 바이트 수가 나옵니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"/// The I32 WireType indicates that the value is precisely 4 bytes in\n"
|
|
" /// little-endian order containing a 32-bit signed integer.\n"
|
|
msgstr ""
|
|
"/// I32 WireType은 값이 little-endian 순서로 정확히 4바이트임을 나타냅니다.\n"
|
|
" /// 여기에는 32비트의 부호 있는 정수가 포함됩니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "/// A field's value, typed based on the wire type.\n"
|
|
msgstr "/// 와이어 타입에 따라 타입이 지정된 필드 값입니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "//I64(i64), -- not needed for this exercise\n"
|
|
msgstr "//I64(i64), -- 이 연습에서는 필요하지 않습니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "/// A field, containing the field number and its value.\n"
|
|
msgstr "/// 필드 번호 및 값을 포함하는 필드입니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "//1 => WireType::I64, -- not needed for this exercise\n"
|
|
msgstr "//1 => WireType::I64, -- 이 연습에서는 필요하지 않습니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid ""
|
|
"/// Parse a VARINT, returning the parsed value and the remaining bytes.\n"
|
|
msgstr "/// VARINT를 파싱하여 파싱된 값과 나머지 바이트를 반환합니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid ""
|
|
"// This is the last byte of the VARINT, so convert it to\n"
|
|
" // a u64 and return it.\n"
|
|
msgstr ""
|
|
"// 이는 VARINT의 마지막 바이트이므로\n"
|
|
" // u64로 변환하여 반환합니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "// More than 7 bytes is invalid.\n"
|
|
msgstr "// 7바이트를 초과하면 유효하지 않습니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "/// Convert a tag into a field number and a WireType.\n"
|
|
msgstr "/// 태그를 필드 번호와 WireType으로 변환합니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid "/// Parse a field, returning the remaining bytes\n"
|
|
msgstr "/// 필드를 파싱하여 나머지 바이트를 반환합니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md
|
|
msgid ""
|
|
"\"Based on the wire type, build a Field, consuming as many bytes as "
|
|
"necessary.\""
|
|
msgstr ""
|
|
|
|
#: src/slices-and-lifetimes/exercise.md
|
|
msgid "\"Return the field, and any un-consumed bytes.\""
|
|
msgstr ""
|
|
|
|
#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md
|
|
msgid ""
|
|
"/// Parse a message in the given data, calling `T::add_field` for each field "
|
|
"in\n"
|
|
"/// the message.\n"
|
|
"///\n"
|
|
"/// The entire input is consumed.\n"
|
|
msgstr ""
|
|
"/// 주어진 데이터에서 메시지를 파싱하여 메시지의 각 필드에 대해 `T::"
|
|
"add_field`를 호출합니다.\n"
|
|
"///\n"
|
|
"/// 전체 입력이 사용됩니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/exercise.md
|
|
msgid "// TODO: Implement ProtoMessage for Person and PhoneNumber.\n"
|
|
msgstr ""
|
|
|
|
#: src/slices-and-lifetimes/solution.md
|
|
msgid "// Unwrap error because `value` is definitely 4 bytes long.\n"
|
|
msgstr "// `value`의 길이가 4바이트이므로 오류를 래핑 해제합니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/solution.md
|
|
msgid "// skip everything else\n"
|
|
msgstr "// 나머지는 모두 건너뜁니다.\n"
|
|
|
|
#: src/slices-and-lifetimes/solution.md
|
|
msgid "b\"hello\""
|
|
msgstr "b\"hello\""
|
|
|
|
#: src/welcome-day-4.md
|
|
msgid "Welcome to Day 4"
|
|
msgstr "4일차 개요"
|
|
|
|
#: src/welcome-day-4.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Today we will cover topics relating to building large-scale software in Rust:"
|
|
msgstr "오늘은 몇 가지 고급 주제를 다룹니다:"
|
|
|
|
#: src/welcome-day-4.md
|
|
msgid "Iterators: a deep dive on the `Iterator` trait."
|
|
msgstr "반복자: `Iterator` 트레잇 심층 분석"
|
|
|
|
#: src/welcome-day-4.md
|
|
msgid "Modules and visibility."
|
|
msgstr "모듈과 가시성"
|
|
|
|
#: src/welcome-day-4.md
|
|
#, fuzzy
|
|
msgid "Testing."
|
|
msgstr "테스트"
|
|
|
|
#: src/welcome-day-4.md
|
|
msgid "Error handling: panics, `Result`, and the try operator `?`."
|
|
msgstr "오류처리(에러 핸들링): 패닉, `Result`, `?` 연산자."
|
|
|
|
#: src/welcome-day-4.md
|
|
msgid ""
|
|
"Unsafe Rust: the escape hatch when you can't express yourself in safe Rust."
|
|
msgstr ""
|
|
"안전하지 않은 Rust: 안전한 Rust로 원하는 것을 표현할 수 없을 때에만 사용하세"
|
|
"요."
|
|
|
|
#: src/welcome-day-4.md
|
|
msgid "[Welcome](./welcome-day-4.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-4.md
|
|
msgid "[Iterators](./iterators.md) (45 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-4.md
|
|
msgid "[Modules](./modules.md) (40 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-4.md
|
|
msgid "[Testing](./testing.md) (45 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-4.md
|
|
msgid ""
|
|
"Including 10 minute breaks, this session should take about 2 hours and 40 "
|
|
"minutes"
|
|
msgstr ""
|
|
|
|
#: src/iterators.md
|
|
msgid "[Iterator](./iterators/iterator.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/iterators.md
|
|
msgid "[IntoIterator](./iterators/intoiterator.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/iterators.md
|
|
msgid "[FromIterator](./iterators/fromiterator.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/iterators.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[Exercise: Iterator Method Chaining](./iterators/exercise.md) (30 minutes)"
|
|
msgstr "연습문제: 반복자 메서드 체이닝"
|
|
|
|
#: src/iterators/iterator.md
|
|
msgid ""
|
|
"The [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html) "
|
|
"trait supports iterating over values in a collection. It requires a `next` "
|
|
"method and provides lots of methods. Many standard library types implement "
|
|
"`Iterator`, and you can implement it yourself, too:"
|
|
msgstr ""
|
|
"컬랙션에 있는 값들을 접근하기 위해서는 [`Iterator`](https://doc.rust-lang."
|
|
"org/std/iter/trait.Iterator.html) 트레잇을 사용합니다. 이 트레잇은 `next` 메"
|
|
"서드를 비롯한 많은 메서드를 제공합니다. 많은 표준 라이브러리 타입이 "
|
|
"`Iterator`를 구현하고 있으며, 여러분도 여러분의 타입이 이 트레잇을 직접 구현"
|
|
"하도록 할 수 있습니다."
|
|
|
|
#: src/iterators/iterator.md
|
|
msgid "\"fib({i}): {n}\""
|
|
msgstr "\"fib({i}): {n}\""
|
|
|
|
#: src/iterators/iterator.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The `Iterator` trait implements many common functional programming "
|
|
"operations over collections (e.g. `map`, `filter`, `reduce`, etc). This is "
|
|
"the trait where you can find all the documentation about them. In Rust these "
|
|
"functions should produce the code as efficient as equivalent imperative "
|
|
"implementations."
|
|
msgstr ""
|
|
"`Iterator` 트레잇은 컬렉션에 대한 여러 일반적인 함수 프로그래밍 작업(예: "
|
|
"`map`, `filter`, `reduce` 등)을 구현합니다. 이는 관련 문서를 모두 찾을 수 있"
|
|
"는 트레잇입니다. Rust에서는 이러한 함수가, 이와 동일한 일을 하는 명령형 구현"
|
|
"만큼 효율적인 코드를 생성합니다."
|
|
|
|
#: src/iterators/iterator.md
|
|
msgid ""
|
|
"`IntoIterator` is the trait that makes for loops work. It is implemented by "
|
|
"collection types such as `Vec<T>` and references to them such as `&Vec<T>` "
|
|
"and `&[T]`. Ranges also implement it. This is why you can iterate over a "
|
|
"vector with `for i in some_vec { .. }` but `some_vec.next()` doesn't exist."
|
|
msgstr ""
|
|
"`IntoIterator`는 루프를 작동하게 만드는 트레잇입니다. 이는 `Vec<T>`와 같은 컬"
|
|
"렉션 타입과 `&Vec<T>` 및 `&[T]`와 같은 이에 대한 참조에 의해 구현됩니다. 범위"
|
|
"도 이를 구현합니다. 이런 이유로 `for i in some_vec { .. }`를 사용하여 벡터를 "
|
|
"반복할 수 있지만 `some_vec.next()`는 존재하지 않습니다."
|
|
|
|
#: src/iterators/intoiterator.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The `Iterator` trait tells you how to _iterate_ once you have created an "
|
|
"iterator. The related trait [`IntoIterator`](https://doc.rust-lang.org/std/"
|
|
"iter/trait.IntoIterator.html) defines how to create an iterator for a type. "
|
|
"It is used automatically by the `for` loop."
|
|
msgstr ""
|
|
"`Iterator` 트레잇은 생성된 반복자를 _사용_하는 방법을 알려줍니다. 반면 "
|
|
"`IntoIterator` 트레잇은 반복자를 _생성_하는 방법을 알려줍니다:"
|
|
|
|
#: src/iterators/intoiterator.md
|
|
msgid "\"point = {x}, {y}\""
|
|
msgstr "\"point = {x}, {y}\""
|
|
|
|
#: src/iterators/intoiterator.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Click through to the docs for `IntoIterator`. Every implementation of "
|
|
"`IntoIterator` must declare two types:"
|
|
msgstr "`IntoIterator`의 모든 구현은 반드시 다음의 두 타입을 선언해야합니다:"
|
|
|
|
#: src/iterators/intoiterator.md
|
|
#, fuzzy
|
|
msgid "`Item`: the type to iterate over, such as `i8`,"
|
|
msgstr "`Item`: `i8`과 같이 반복되는 값의 타입,"
|
|
|
|
#: src/iterators/intoiterator.md
|
|
msgid "`IntoIter`: the `Iterator` type returned by the `into_iter` method."
|
|
msgstr "`IntoIter`: `into_iter` 메서드에서 반환되는 `Iterator`타입."
|
|
|
|
#: src/iterators/intoiterator.md
|
|
msgid ""
|
|
"Note that `IntoIter` and `Item` are linked: the iterator must have the same "
|
|
"`Item` type, which means that it returns `Option<Item>`"
|
|
msgstr ""
|
|
"`IntoIter`에는 `Item`이 연결되어 있음을 주목하세요. `IntoIter` 반복자는 "
|
|
"`Item` 타입의 데이터를 가리켜야 합니다. 즉, 반복자는 `Option<Item>`을 리턴합"
|
|
"니다"
|
|
|
|
#: src/iterators/intoiterator.md
|
|
msgid "The example iterates over all combinations of x and y coordinates."
|
|
msgstr "이 예는 x 및 y 좌표의 모든 조합을 순회합니다."
|
|
|
|
#: src/iterators/intoiterator.md
|
|
msgid ""
|
|
"Try iterating over the grid twice in `main`. Why does this fail? Note that "
|
|
"`IntoIterator::into_iter` takes ownership of `self`."
|
|
msgstr ""
|
|
"`main`에서 그리드를 두 번 반복해 보세요. 왜 실패하나요? `IntoIterator::"
|
|
"into_iter`는 'self'의 소유권을 가져옵니다."
|
|
|
|
#: src/iterators/intoiterator.md
|
|
msgid ""
|
|
"Fix this issue by implementing `IntoIterator` for `&Grid` and storing a "
|
|
"reference to the `Grid` in `GridIter`."
|
|
msgstr ""
|
|
"`&Grid`에 `IntoIterator`를 구현하고 `GridIter`에 `Grid` 참조를 저장하여 이 문"
|
|
"제를 해결하세요."
|
|
|
|
#: src/iterators/intoiterator.md
|
|
msgid ""
|
|
"The same problem can occur for standard library types: `for e in "
|
|
"some_vector` will take ownership of `some_vector` and iterate over owned "
|
|
"elements from that vector. Use `for e in &some_vector` instead, to iterate "
|
|
"over references to elements of `some_vector`."
|
|
msgstr ""
|
|
"표준 라이브러리 타입에서 동일한 문제가 발생할 수 있습니다. `for e in "
|
|
"some_vector`는 `some_vector`의 소유권을 가져와 해당 벡터에서 소유한 요소를 반"
|
|
"복합니다. `some_vector`의 요소에 대한 참조를 반복하려면 대신 `for e in "
|
|
"&some_vector`를 사용하세요."
|
|
|
|
#: src/iterators/fromiterator.md
|
|
msgid "FromIterator"
|
|
msgstr "FromIterator"
|
|
|
|
#: src/iterators/fromiterator.md
|
|
msgid ""
|
|
"[`FromIterator`](https://doc.rust-lang.org/std/iter/trait.FromIterator.html) "
|
|
"lets you build a collection from an [`Iterator`](https://doc.rust-lang.org/"
|
|
"std/iter/trait.Iterator.html)."
|
|
msgstr ""
|
|
"어떤 컬렉션이 [`FromIterator`](https://doc.rust-lang.org/std/iter/trait."
|
|
"FromIterator.html)를 구현하고 있다면 [`Iterator`](https://doc.rust-lang.org/"
|
|
"std/iter/trait.Iterator.html)로부터 그 컬렉션을 만들 수 있습니다."
|
|
|
|
#: src/iterators/fromiterator.md
|
|
msgid "\"prime_squares: {prime_squares:?}\""
|
|
msgstr "\"prime_squares: {prime_squares:?}\""
|
|
|
|
#: src/iterators/fromiterator.md
|
|
#, fuzzy
|
|
msgid "`Iterator` implements"
|
|
msgstr "`Iterator`"
|
|
|
|
#: src/iterators/fromiterator.md
|
|
msgid "There are two ways to specify `B` for this method:"
|
|
msgstr "이 메서드에 `B`를 지정하는 방법에는 두 가지가 있습니다."
|
|
|
|
#: src/iterators/fromiterator.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"With the \"turbofish\": `some_iterator.collect::<COLLECTION_TYPE>()`, as "
|
|
"shown. The `_` shorthand used here lets Rust infer the type of the `Vec` "
|
|
"elements."
|
|
msgstr ""
|
|
"\"turbofish' 사용: 다음과 같이 `some_iterator.collect::<COLLECTION_TYPE>()`"
|
|
"을 사용합니다. 여기에 사용된 `_` 는 Rust가 `Vec` 에 들어갈 요소들의 타입을 추"
|
|
"론하도록합니다. "
|
|
|
|
#: src/iterators/fromiterator.md
|
|
msgid ""
|
|
"With type inference: `let prime_squares: Vec<_> = some_iterator.collect()`. "
|
|
"Rewrite the example to use this form."
|
|
msgstr ""
|
|
"타입 추론 사용: `let prime_squares: Vec<_> = some_iterator.collect()`를 사용"
|
|
"합니다. 이 방법으로 예제를 다시 작성해 보세요."
|
|
|
|
#: src/iterators/fromiterator.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"There are basic implementations of `FromIterator` for `Vec`, `HashMap`, etc. "
|
|
"There are also more specialized implementations which let you do cool things "
|
|
"like convert an `Iterator<Item = Result<V, E>>` into a `Result<Vec<V>, E>`."
|
|
msgstr ""
|
|
"`Iterator<Item = Result<V, E>>`을 `Result<Vec<V>, E>`로 변환할 수 있는 멋진 "
|
|
"기능들도 구현되어 있습니다."
|
|
|
|
#: src/iterators/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"In this exercise, you will need to find and use some of the provided methods "
|
|
"in the [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html) "
|
|
"trait to implement a complex calculation."
|
|
msgstr "`Iterator`트레잇을 여러분이 정의한 타입에서 구현해 보겠습니다:"
|
|
|
|
#: src/iterators/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Copy the following code to <https://play.rust-lang.org/> and make the tests "
|
|
"pass. Use an iterator expression and `collect` the result to construct the "
|
|
"return value."
|
|
msgstr ""
|
|
"아래 코드를 <https://play.rust-lang.org/>에 복사하고 테스트를 통과해 보시기 "
|
|
"바랍니다. 중간 결과값을 `Vec`에 할당하지 않도록 주의 하시기 바랍니다:"
|
|
|
|
#: src/iterators/exercise.md src/iterators/solution.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"/// Calculate the differences between elements of `values` offset by "
|
|
"`offset`,\n"
|
|
"/// wrapping around from the end of `values` to the beginning.\n"
|
|
"///\n"
|
|
"/// Element `n` of the result is `values[(n+offset)%len] - values[n]`.\n"
|
|
msgstr ""
|
|
"/// `values`의 끝에서 시작까지\n"
|
|
"/// 래핑하여 `offset`을 기준으로 `values` 오프셋 요소 간의 차이를 계산합니"
|
|
"다.\n"
|
|
"///\n"
|
|
"/// 결과의 요소 `n`은 `values[(n+offset)%len] - values[n]`입니다.\n"
|
|
|
|
#: src/modules.md
|
|
msgid "[Modules](./modules/modules.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/modules.md
|
|
msgid "[Filesystem Hierarchy](./modules/filesystem.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/modules.md
|
|
msgid "[Visibility](./modules/visibility.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/modules.md
|
|
msgid "[use, super, self](./modules/paths.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/modules.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[Exercise: Modules for a GUI Library](./modules/exercise.md) (15 minutes)"
|
|
msgstr "연습문제: GUI 라이브러리 모듈"
|
|
|
|
#: src/modules/modules.md
|
|
msgid "We have seen how `impl` blocks let us namespace functions to a type."
|
|
msgstr "`impl`블록은 해당 타입의 함수들에 대한 네임스페이스를 제공합니다."
|
|
|
|
#: src/modules/modules.md
|
|
msgid "Similarly, `mod` lets us namespace types and functions:"
|
|
msgstr "마찬가지로, `mod`는 타입과 함수들에 대해 네임스페이스를 제공합니다:"
|
|
|
|
#: src/modules/modules.md
|
|
msgid "\"In the foo module\""
|
|
msgstr "\"foo 모듈 내부\""
|
|
|
|
#: src/modules/modules.md
|
|
msgid "\"In the bar module\""
|
|
msgstr "\"bar 모듈 내부\""
|
|
|
|
#: src/modules/modules.md
|
|
msgid ""
|
|
"Packages provide functionality and include a `Cargo.toml` file that "
|
|
"describes how to build a bundle of 1+ crates."
|
|
msgstr ""
|
|
"패키지는 기능을 제공하며 하나의 대표 `Cargo.toml` 파일을 포함합니다. 패키지"
|
|
"를 구성하는 크레이트들을 빌드하는 방법이 이 파일에 기술됩니다."
|
|
|
|
#: src/modules/modules.md
|
|
msgid ""
|
|
"Crates are a tree of modules, where a binary crate creates an executable and "
|
|
"a library crate compiles to a library."
|
|
msgstr ""
|
|
"크레이트는 모듈의 트리입니다. 바이너리 크레이트는 실행파일로 빌드되고, 라이브"
|
|
"러리 크레이트는 라이브러리로 빌드됩니다."
|
|
|
|
#: src/modules/modules.md
|
|
msgid "Modules define organization, scope, and are the focus of this section."
|
|
msgstr "모듈은 코드를 조직화하고 스코프를 정의하는 단위입니다."
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid ""
|
|
"Omitting the module content will tell Rust to look for it in another file:"
|
|
msgstr ""
|
|
"모듈의 내용을 기술하지 않으면, 러스트는 다른 파일에서 그 내용을 읽습니다:"
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid ""
|
|
"This tells rust that the `garden` module content is found at `src/garden."
|
|
"rs`. Similarly, a `garden::vegetables` module can be found at `src/garden/"
|
|
"vegetables.rs`."
|
|
msgstr ""
|
|
"위 코드는 러스트로 하여금 `garden`모듈의 내용을 `src/garden.rs`에서 찾도록 합"
|
|
"니다. 비슷하게, `garden::vegetables` 모듈은 `src/garden/vegetables.rs`에서 찾"
|
|
"습니다."
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid "The `crate` root is in:"
|
|
msgstr "`crate(크레이트)`의 루트는 아래 경로 입니다:"
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid "`src/lib.rs` (for a library crate)"
|
|
msgstr "`src/lib.rs` (라이브러리 크레이트)"
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid "`src/main.rs` (for a binary crate)"
|
|
msgstr "`src/main.rs` (바이너리 크레이트)"
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid ""
|
|
"Modules defined in files can be documented, too, using \"inner doc "
|
|
"comments\". These document the item that contains them -- in this case, a "
|
|
"module."
|
|
msgstr ""
|
|
"모듈도 \"내부 문서 주석\"을 사용하여 문서화할 수 있습니다. 이러한 모듈은 모듈"
|
|
"이 포함된 항목(이 경우에는 모듈)을 문서화합니다."
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid ""
|
|
"//! This module implements the garden, including a highly performant "
|
|
"germination\n"
|
|
"//! implementation.\n"
|
|
msgstr "//! 이 모듈은 정원을 구현합니다.\n"
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid "// Re-export types from this module.\n"
|
|
msgstr "// 이 모듈에서 타입을 다시 내보냅니다.\n"
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid "/// Sow the given seed packets.\n"
|
|
msgstr "/// 주어진 씨앗 패킷을 뿌립니다.\n"
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid "/// Harvest the produce in the garden that is ready.\n"
|
|
msgstr "/// 준비된 농작물을 정원에서 수확합니다.\n"
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid ""
|
|
"Before Rust 2018, modules needed to be located at `module/mod.rs` instead of "
|
|
"`module.rs`, and this is still a working alternative for editions after 2018."
|
|
msgstr ""
|
|
"`module/mod.rs`를 `module.rs`로 바꾼다 하더라도 Rust 2018에서는 하위 모듈을 "
|
|
"사용할 수 있습니다."
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid ""
|
|
"The main reason to introduce `filename.rs` as alternative to `filename/mod."
|
|
"rs` was because many files named `mod.rs` can be hard to distinguish in IDEs."
|
|
msgstr ""
|
|
"`filename.rs`를 `filename/mod.rs`대신 사용할 수 있도록 하는 주된 이유는, "
|
|
"`mod.rs`라는 이름을 가진 파일이 많을 경우 IDE에서 이들을 서로 구별하는게 힘들"
|
|
"기 때문입니다."
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid "Deeper nesting can use folders, even if the main module is a file:"
|
|
msgstr ""
|
|
"폴더를 이용해서 더 깊은 계층 구조를 구현할 수 있습니다. 심지어는 메인 모듈이 "
|
|
"파일이더라도요:"
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid ""
|
|
"The place rust will look for modules can be changed with a compiler "
|
|
"directive:"
|
|
msgstr "러스트가 어디서 모듈들을 찾을지는 컴파일러 디렉티브로 변경 가능합니다:"
|
|
|
|
#: src/modules/filesystem.md
|
|
#, fuzzy
|
|
msgid "\"some/path.rs\""
|
|
msgstr "\"some/path.rs\""
|
|
|
|
#: src/modules/filesystem.md
|
|
msgid ""
|
|
"This is useful, for example, if you would like to place tests for a module "
|
|
"in a file named `some_module_test.rs`, similar to the convention in Go."
|
|
msgstr ""
|
|
"이는 Go언어 에서처럼 어떤 모듈의 테스트를 `some_module_test.rs` 같은 파일에 "
|
|
"두고 싶은 경우에 유용합니다."
|
|
|
|
#: src/modules/visibility.md
|
|
msgid "Modules are a privacy boundary:"
|
|
msgstr "모듈의 타입이나 함수는 기본적으로 바깥에 노출되지 않습니다:"
|
|
|
|
#: src/modules/visibility.md
|
|
msgid "Module items are private by default (hides implementation details)."
|
|
msgstr "따라서 모듈의 세부 구현 내용이 감춰집니다."
|
|
|
|
#: src/modules/visibility.md
|
|
msgid "Parent and sibling items are always visible."
|
|
msgstr "부모와 이웃 항목은 언제나 접근 가능합니다."
|
|
|
|
#: src/modules/visibility.md
|
|
msgid ""
|
|
"In other words, if an item is visible in module `foo`, it's visible in all "
|
|
"the descendants of `foo`."
|
|
msgstr ""
|
|
"즉, 모듈 `foo`에서 접근 가능한 항목이라면 `foo` 아래의 모든 모듈에서 접근가능"
|
|
"합니다."
|
|
|
|
#: src/modules/visibility.md
|
|
msgid "\"outer::private\""
|
|
msgstr "\"outer::private\""
|
|
|
|
#: src/modules/visibility.md
|
|
msgid "\"outer::public\""
|
|
msgstr "\"outer::public\""
|
|
|
|
#: src/modules/visibility.md
|
|
msgid "\"outer::inner::private\""
|
|
msgstr "\"outer::inner::private\""
|
|
|
|
#: src/modules/visibility.md
|
|
msgid "\"outer::inner::public\""
|
|
msgstr "\"outer::inner::public\""
|
|
|
|
#: src/modules/visibility.md
|
|
msgid "Use the `pub` keyword to make modules public."
|
|
msgstr "`pub` 키워드는 모듈에도 사용할 수 있습니다."
|
|
|
|
#: src/modules/visibility.md
|
|
msgid ""
|
|
"Additionally, there are advanced `pub(...)` specifiers to restrict the scope "
|
|
"of public visibility."
|
|
msgstr ""
|
|
"또한, 고급 기능으로 `pub(...)` 지정자를 사용하여 공개 범위를 제한할 수 있습니"
|
|
"다."
|
|
|
|
#: src/modules/visibility.md
|
|
msgid ""
|
|
"See the [Rust Reference](https://doc.rust-lang.org/reference/visibility-and-"
|
|
"privacy.html#pubin-path-pubcrate-pubsuper-and-pubself)."
|
|
msgstr ""
|
|
"[공식 문서](https://doc.rust-lang.org/reference/visibility-and-privacy."
|
|
"html#pubin-path-pubcrate-pubsuper-and-pubself)를 참고하세요."
|
|
|
|
#: src/modules/visibility.md
|
|
msgid "Configuring `pub(crate)` visibility is a common pattern."
|
|
msgstr "`pub(crate)`로 가시성을 지정하는 것이 자주 쓰입니다."
|
|
|
|
#: src/modules/visibility.md
|
|
msgid "Less commonly, you can give visibility to a specific path."
|
|
msgstr "자주 쓰이진 않지만 특정 경로에 대해서만 가시성을 부여할 수 있습니다."
|
|
|
|
#: src/modules/visibility.md
|
|
msgid ""
|
|
"In any case, visibility must be granted to an ancestor module (and all of "
|
|
"its descendants)."
|
|
msgstr ""
|
|
"어떤 경우이든 가시성이 부여되면 해당 모듈을 포함하여 하위의 모든 모듈이 적용"
|
|
"받습니다."
|
|
|
|
#: src/modules/paths.md
|
|
msgid "use, super, self"
|
|
msgstr "use, super, self"
|
|
|
|
#: src/modules/paths.md
|
|
msgid ""
|
|
"A module can bring symbols from another module into scope with `use`. You "
|
|
"will typically see something like this at the top of each module:"
|
|
msgstr ""
|
|
"모듈은 `use`를 사용하여 다른 모듈의 심볼을 내 스코프로 가져올 수 있습니다. 일"
|
|
"반적으로 각 모듈의 상단에 다음과 같은 내용이 옵니다:"
|
|
|
|
#: src/modules/paths.md
|
|
msgid "Paths"
|
|
msgstr "경로"
|
|
|
|
#: src/modules/paths.md
|
|
msgid "Paths are resolved as follows:"
|
|
msgstr "경로는 아래와 같이 구분합니다:"
|
|
|
|
#: src/modules/paths.md
|
|
msgid "As a relative path:"
|
|
msgstr "상대 경로:"
|
|
|
|
#: src/modules/paths.md
|
|
msgid "`foo` or `self::foo` refers to `foo` in the current module,"
|
|
msgstr "`foo` 또는 `self::foo`는 현재 모듈 내부의 `foo`를 가리킵니다,"
|
|
|
|
#: src/modules/paths.md
|
|
msgid "`super::foo` refers to `foo` in the parent module."
|
|
msgstr "`super::foo`는 부모 모듈의 `foo`를 가리킵니다."
|
|
|
|
#: src/modules/paths.md
|
|
msgid "As an absolute path:"
|
|
msgstr "절대 경로:"
|
|
|
|
#: src/modules/paths.md
|
|
msgid "`crate::foo` refers to `foo` in the root of the current crate,"
|
|
msgstr "`crate::foo`는 현재 크레이트 루트의 `foo`를 가리킵니다,"
|
|
|
|
#: src/modules/paths.md
|
|
msgid "`bar::foo` refers to `foo` in the `bar` crate."
|
|
msgstr "`bar::foo`는 `bar`크레이트의 `foo`를 가리킵니다."
|
|
|
|
#: src/modules/paths.md
|
|
msgid ""
|
|
"It is common to \"re-export\" symbols at a shorter path. For example, the "
|
|
"top-level `lib.rs` in a crate might have"
|
|
msgstr ""
|
|
"더 짧은 경로에서 기호를 '다시 내보내기'하는 것이 일반적입니다. 예를 들어 크레"
|
|
"이트의 최상위 `lib.rs`는"
|
|
|
|
#: src/modules/paths.md
|
|
msgid ""
|
|
"making `DiskStorage` and `NetworkStorage` available to other crates with a "
|
|
"convenient, short path."
|
|
msgstr ""
|
|
"편리하고 짧은 경로로 다른 크레이트에서 `DiskStorage` 및 `NetworkStorage`를 사"
|
|
"용할 수 있도록 할 수 있습니다."
|
|
|
|
#: src/modules/paths.md
|
|
msgid ""
|
|
"For the most part, only items that appear in a module need to be `use`'d. "
|
|
"However, a trait must be in scope to call any methods on that trait, even if "
|
|
"a type implementing that trait is already in scope. For example, to use the "
|
|
"`read_to_string` method on a type implementing the `Read` trait, you need to "
|
|
"`use std::io::Read`."
|
|
msgstr ""
|
|
"대부분의 경우 모듈에 나타나는 항목만 'use' 처리 되어야 합니다. 그러나 트레잇"
|
|
"을 구현하는 타입이 이미 범위 내에 있더라도 해당 트레잇에서 메서드를 호출하려"
|
|
"면 트레잇이 범위 내에 있어야 합니다. 예를 들어 `Read` 트레잇을 구현하는 타입"
|
|
"에서 `read_to_string` 메서드를 사용하려면 `use std::io::Read`를 사용해야 합니"
|
|
"다."
|
|
|
|
#: src/modules/paths.md
|
|
msgid ""
|
|
"The `use` statement can have a wildcard: `use std::io::*`. This is "
|
|
"discouraged because it is not clear which items are imported, and those "
|
|
"might change over time."
|
|
msgstr ""
|
|
"`use` 문에는 와일드 카드(`use std::io::*`)를 사용할 수 있습니다. 이는 가져오"
|
|
"는 항목이 명확하지 않고 시간이 지남에 따라 변경될 수 있으므로 권장되지 않습니"
|
|
"다."
|
|
|
|
#: src/modules/exercise.md
|
|
msgid ""
|
|
"In this exercise, you will reorganize a small GUI Library implementation. "
|
|
"This library defines a `Widget` trait and a few implementations of that "
|
|
"trait, as well as a `main` function."
|
|
msgstr ""
|
|
|
|
#: src/modules/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"It is typical to put each type or set of closely-related types into its own "
|
|
"module, so each widget type should get its own module."
|
|
msgstr ""
|
|
"이 연습에서는 '메서드 및 트레잇' 세그먼트의 GUI 라이브러리 연습을 모듈 컬렉션"
|
|
"으로 재구성합니다. 각 타입 또는 밀접하게 관련된 타입 집합을 자체 모듈에 배치"
|
|
"하는 것이 일반적이므로 각 위젯 타입은 자체 모듈을 가져야 합니다."
|
|
|
|
#: src/modules/exercise.md
|
|
#, fuzzy
|
|
msgid "Cargo Setup"
|
|
msgstr "설치"
|
|
|
|
#: src/modules/exercise.md
|
|
msgid ""
|
|
"The Rust playground only supports one file, so you will need to make a Cargo "
|
|
"project on your local filesystem:"
|
|
msgstr ""
|
|
"Rust 플레이그라운드는 하나의 파일만 지원하므로 로컬 파일 시스템에 Cargo 프로"
|
|
"젝트를 만들어야 합니다."
|
|
|
|
#: src/modules/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Edit the resulting `src/main.rs` to add `mod` statements, and add additional "
|
|
"files in the `src` directory."
|
|
msgstr ""
|
|
"`src/main.rs`를 수정하여 `mod` 문을 추가하고 `src` 디렉터리에 파일을 추가합니"
|
|
"다."
|
|
|
|
#: src/modules/exercise.md
|
|
msgid "Source"
|
|
msgstr ""
|
|
|
|
#: src/modules/exercise.md
|
|
msgid "Here's the single-module implementation of the GUI library:"
|
|
msgstr ""
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "/// Natural width of `self`.\n"
|
|
msgstr "/// `self`의 자연 너비\n"
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "/// Draw the widget into a buffer.\n"
|
|
msgstr "/// 버퍼에 위젯을 그립니다.\n"
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "/// Draw the widget on standard output.\n"
|
|
msgstr "/// 표준 출력에 위젯을 그립니다.\n"
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "\"{buffer}\""
|
|
msgstr "\"{buffer}\""
|
|
|
|
#: src/modules/exercise.md
|
|
msgid "// Add 4 paddings for borders\n"
|
|
msgstr "// 테두리용 패딩 4개 추가\n"
|
|
|
|
#: src/modules/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"// TODO: Change draw_into to return Result<(), std::fmt::Error>. Then use "
|
|
"the\n"
|
|
" // ?-operator here instead of .unwrap().\n"
|
|
msgstr ""
|
|
"// TODO: 오류 처리에 관해 알아본 후,\n"
|
|
" // Result<(), std::fmt::Error>를 반환하도록 draw_into를 변경할 수 있"
|
|
"습니다. 그런 다음\n"
|
|
" // .unwrap() 대신 ?-연산자를 여기에 사용하세요.\n"
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "\"+-{:-<inner_width$}-+\""
|
|
msgstr "\"+-{:-<inner_width$}-+\""
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md src/testing/unit-tests.md
|
|
#: src/testing/solution.md
|
|
msgid "\"\""
|
|
msgstr "\"\""
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "\"| {:^inner_width$} |\""
|
|
msgstr "\"| {:^inner_width$} |\""
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "\"+={:=<inner_width$}=+\""
|
|
msgstr "\"+={:=<inner_width$}=+\""
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "\"| {:inner_width$} |\""
|
|
msgstr "\"| {:inner_width$} |\""
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "// add a bit of padding\n"
|
|
msgstr "// 패딩을 약간 추가합니다.\n"
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "\"+{:-<width$}+\""
|
|
msgstr "\"+{:-<width$}+\""
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "\"|{:^width$}|\""
|
|
msgstr "\"|{:^width$}|\""
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "\"Rust GUI Demo 1.23\""
|
|
msgstr "\"Rust GUI 데모 1.23\""
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "\"This is a small text GUI demo.\""
|
|
msgstr "\"작은 텍스트 GUI 데모입니다.\""
|
|
|
|
#: src/modules/exercise.md src/modules/solution.md
|
|
msgid "\"Click me!\""
|
|
msgstr "\"클릭해 주세요!\""
|
|
|
|
#: src/modules/exercise.md
|
|
msgid ""
|
|
"Encourage students to divide the code in a way that feels natural for them, "
|
|
"and get accustomed to the required `mod`, `use`, and `pub` declarations. "
|
|
"Afterward, discuss what organizations are most idiomatic."
|
|
msgstr ""
|
|
"학생들에게는 본인에게 자연스러운 방식으로 코드를 나누도록 권장하세요. 그리고"
|
|
"나서 필요한 `mod`, `use`, `pub` 선언에 익숙해지도록 합니다. 그런 다음 어떤 구"
|
|
"성이 가장 자연스러운지 논의합니다."
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ---- src/widgets.rs ----\n"
|
|
msgstr "// ---- src/widgets.rs ----\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ---- src/widgets/label.rs ----\n"
|
|
msgstr "// ---- src/widgets/label.rs ----\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ANCHOR_END: Label-width\n"
|
|
msgstr "// ANCHOR_END: Label-width\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ANCHOR: Label-draw_into\n"
|
|
msgstr "// ANCHOR: Label-draw_into\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ANCHOR_END: Label-draw_into\n"
|
|
msgstr "// ANCHOR_END: Label-draw_into\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ---- src/widgets/button.rs ----\n"
|
|
msgstr "// ---- src/widgets/button.rs ----\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ANCHOR_END: Button-width\n"
|
|
msgstr "// ANCHOR_END: Button-width\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ANCHOR: Button-draw_into\n"
|
|
msgstr "// ANCHOR: Button-draw_into\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ANCHOR_END: Button-draw_into\n"
|
|
msgstr "// ANCHOR_END: Button-draw_into\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ---- src/widgets/window.rs ----\n"
|
|
msgstr "// ---- src/widgets/window.rs ----\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid ""
|
|
"// ANCHOR_END: Window-width\n"
|
|
" // Add 4 paddings for borders\n"
|
|
msgstr ""
|
|
"// ANCHOR_END: Window-width\n"
|
|
" // 테두리에 패딩 4개 추가\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ANCHOR: Window-draw_into\n"
|
|
msgstr "// ANCHOR: Window-draw_into\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ANCHOR_END: Window-draw_into\n"
|
|
msgstr "// ANCHOR_END: Window-draw_into\n"
|
|
|
|
#: src/modules/solution.md
|
|
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"
|
|
msgstr ""
|
|
"// TODO: 오류 처리에 관해 알아본 후,\n"
|
|
" // Result<(), std::fmt::Error>를 반환하도록 draw_into를 변경할 수 있"
|
|
"습니다. 그런 다음\n"
|
|
" // .unwrap() 대신 ?-연산자를 여기에 사용하세요.\n"
|
|
|
|
#: src/modules/solution.md
|
|
msgid "// ---- src/main.rs ----\n"
|
|
msgstr "// ---- src/main.rs ----\n"
|
|
|
|
#: src/testing.md
|
|
msgid "[Test Modules](./testing/unit-tests.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/testing.md
|
|
msgid "[Other Types of Tests](./testing/other.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/testing.md
|
|
msgid "[Compiler Lints and Clippy](./testing/lints.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/testing.md
|
|
msgid "[Exercise: Luhn Algorithm](./testing/exercise.md) (30 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/testing/unit-tests.md
|
|
msgid "Unit Tests"
|
|
msgstr "단위 테스트"
|
|
|
|
#: src/testing/unit-tests.md
|
|
msgid "Rust and Cargo come with a simple unit test framework:"
|
|
msgstr ""
|
|
"러스트와 카고(cargo)는 간단한 단위 테스트 프레임워크와 함께 제공됩니다:"
|
|
|
|
#: src/testing/unit-tests.md
|
|
msgid "Unit tests are supported throughout your code."
|
|
msgstr "단위 테스트는 코드 전반에서 지원됩니다."
|
|
|
|
#: src/testing/unit-tests.md
|
|
msgid "Integration tests are supported via the `tests/` directory."
|
|
msgstr "통합 테스트는 `tests/` 디렉터리를 통해 지원됩니다."
|
|
|
|
#: src/testing/unit-tests.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Tests are marked with `#[test]`. Unit tests are often put in a nested "
|
|
"`tests` module, using `#[cfg(test)]` to conditionally compile them only when "
|
|
"building tests."
|
|
msgstr ""
|
|
"테스트는 `#[test]`로 표시됩니다. 단위 테스트는 종종 중첩된 `tests` 모듈에 배"
|
|
"치되며 테스트를 빌드할 때만 `#[cfg(test)]`를 사용하여 조건부로 컴파일합니다."
|
|
|
|
#: src/testing/unit-tests.md
|
|
#, fuzzy
|
|
msgid "\"Hello World\""
|
|
msgstr "Hello World!"
|
|
|
|
#: src/testing/unit-tests.md
|
|
msgid "This lets you unit test private helpers."
|
|
msgstr ""
|
|
"이렇게 서브 모듈로 테스트를 만들면 private한 헬퍼 함수에 대한 단위 테스트도 "
|
|
"가능합니다."
|
|
|
|
#: src/testing/unit-tests.md
|
|
msgid "The `#[cfg(test)]` attribute is only active when you run `cargo test`."
|
|
msgstr ""
|
|
"`#[cfg(test)]` 어트리뷰트가 추가된 항목은 `cargo test`를 수행했을 경우에만 동"
|
|
"작합니다."
|
|
|
|
#: src/testing/unit-tests.md
|
|
msgid "Run the tests in the playground in order to show their results."
|
|
msgstr "플레이그라운드에서 테스트를 실행하여 결과를 표시합니다."
|
|
|
|
#: src/testing/other.md
|
|
msgid "Integration Tests"
|
|
msgstr "통합 테스트"
|
|
|
|
#: src/testing/other.md
|
|
msgid "If you want to test your library as a client, use an integration test."
|
|
msgstr "라이브러리를 사용자 입장에서 테스트 하려면, 통합 테스트를 해야 합니다."
|
|
|
|
#: src/testing/other.md
|
|
msgid "Create a `.rs` file under `tests/`:"
|
|
msgstr "`test/`디렉터리 아래에 `.rs`파일을 하나 만드세요:"
|
|
|
|
#: src/testing/other.md
|
|
msgid "// tests/my_library.rs\n"
|
|
msgstr "// tests/my_library.rs\n"
|
|
|
|
#: src/testing/other.md
|
|
msgid "These tests only have access to the public API of your crate."
|
|
msgstr "이 테스트는 크레이트의 공개 API에만 접근할 수 있습니다."
|
|
|
|
#: src/testing/other.md
|
|
msgid "Documentation Tests"
|
|
msgstr "문서화주석 테스트"
|
|
|
|
#: src/testing/other.md
|
|
msgid "Rust has built-in support for documentation tests:"
|
|
msgstr "러스트는 문서화주석에 대한 테스트를 내장하여 제공합니다:"
|
|
|
|
#: src/testing/other.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"/// 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"
|
|
msgstr ""
|
|
"```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"
|
|
"```"
|
|
|
|
#: src/testing/other.md
|
|
msgid "Code blocks in `///` comments are automatically seen as Rust code."
|
|
msgstr "`///` 주석안의 코드 블록은 자동으로 러스트 코드로 인식됩니다."
|
|
|
|
#: src/testing/other.md
|
|
msgid "The code will be compiled and executed as part of `cargo test`."
|
|
msgstr "이 코드 블록은 `cargo test` 호출하면 자동으로 컴파일되고 실행됩니다."
|
|
|
|
#: src/testing/other.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Adding `#` in the code will hide it from the docs, but will still compile/"
|
|
"run it."
|
|
msgstr "코드에 `# `을 추가하면 문서에서는 숨겨지지만 컴파일/실행됩니다."
|
|
|
|
#: src/testing/other.md
|
|
msgid ""
|
|
"Test the above code on the [Rust Playground](https://play.rust-lang.org/?"
|
|
"version=stable&mode=debug&edition=2021&gist=3ce2ad13ea1302f6572cb15cd96becf0)."
|
|
msgstr ""
|
|
"위 코드를 [Rust Playground](https://play.rust-lang.org/?"
|
|
"version=stable&mode=debug&edition=2021&gist=3ce2ad13ea1302f6572cb15cd96becf0)"
|
|
"에서 테스트 해 보시기 바랍니다."
|
|
|
|
#: src/testing/lints.md
|
|
msgid ""
|
|
"The Rust compiler produces fantastic error messages, as well as helpful "
|
|
"built-in lints. [Clippy](https://doc.rust-lang.org/clippy/) provides even "
|
|
"more lints, organized into groups that can be enabled per-project."
|
|
msgstr ""
|
|
"Rust 컴파일러는 유용한 내장 린트뿐 아니라 멋진 오류 메시지를 생성합니다. "
|
|
"[Clippy](https://doc.rust-lang.org/clippy/)는 프로젝트별로 사용 설정할 수 있"
|
|
"는 그룹으로 구성된 더 많은 린트를 제공합니다."
|
|
|
|
#: src/testing/lints.md
|
|
msgid "\"X probably fits in a u16, right? {}\""
|
|
msgstr "\"X는 u16에 맞지 않을까요? {}\""
|
|
|
|
#: src/testing/lints.md
|
|
msgid ""
|
|
"Run the code sample and examine the error message. There are also lints "
|
|
"visible here, but those will not be shown once the code compiles. Switch to "
|
|
"the Playground site to show those lints."
|
|
msgstr ""
|
|
"코드 샘플을 실행하고 오류 메시지를 확인합니다. 여기에도 린트가 표시되지만 코"
|
|
"드가 컴파일되고 나면 표시되지 않습니다. 플레이그라운드 사이트로 전환하여 이러"
|
|
"한 린트를 표시합니다."
|
|
|
|
#: src/testing/lints.md
|
|
msgid ""
|
|
"After resolving the lints, run `clippy` on the playground site to show "
|
|
"clippy warnings. Clippy has extensive documentation of its lints, and adds "
|
|
"new lints (including default-deny lints) all the time."
|
|
msgstr ""
|
|
"린트를 해결한 후 플레이그라운드 사이트에서 `clippy`를 실행하여 clippy 경고를 "
|
|
"표시합니다. Clippy는 린트에 관한 광범위한 문서를 보유하고 있으며 항상 새로운 "
|
|
"린트(default-deny 린트 포함)를 추가합니다."
|
|
|
|
#: src/testing/lints.md
|
|
msgid ""
|
|
"Note that errors or warnings with `help: ...` can be fixed with `cargo fix` "
|
|
"or via your editor."
|
|
msgstr ""
|
|
"`help: ...`가 포함된 오류나 경고는 `cargo fix` 또는 편집기를 통해 수정할 수 "
|
|
"있습니다."
|
|
|
|
#: src/testing/exercise.md
|
|
msgid "Luhn Algorithm"
|
|
msgstr "룬 알고리즘"
|
|
|
|
#: src/testing/exercise.md
|
|
msgid ""
|
|
"The [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm) is used "
|
|
"to validate credit card numbers. The algorithm takes a string as input and "
|
|
"does the following to validate the credit card number:"
|
|
msgstr ""
|
|
"[룬(Luhn) 알고리즘](https://ko.wikipedia.org/wiki/"
|
|
"%EB%A3%AC_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98)은 신용카드 번호 검증에 사용되"
|
|
"는 알고리즘 입니다. 이 알고리즘은 신용카드 번호를 `문자열`로 입력받고, 아래"
|
|
"의 순서에 따라 신용카드 번호의 유효성을 확인합니다:"
|
|
|
|
#: src/testing/exercise.md
|
|
#, fuzzy
|
|
msgid "Ignore all spaces. Reject number with fewer than two digits."
|
|
msgstr "모든 공백을 무시합니다. 2자리 미만 숫자는 무시합니다."
|
|
|
|
#: src/testing/exercise.md
|
|
msgid ""
|
|
"Moving from **right to left**, double every second digit: for the number "
|
|
"`1234`, we double `3` and `1`. For the number `98765`, we double `6` and `8`."
|
|
msgstr ""
|
|
"**오른쪽에서 왼쪽으로** 이동하며 2번째 자리마다 숫자를 2배 증가시킵니다. 예"
|
|
"를 들어 `1234`에서 `3`과 `1`에 각각 2를 곱합니다."
|
|
|
|
#: src/testing/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"After doubling a digit, sum the digits if the result is greater than 9. So "
|
|
"doubling `7` becomes `14` which becomes `1 + 4 = 5`."
|
|
msgstr ""
|
|
"두배로 만든 숫자가 2자리라면 각 자리 숫자를 더합니다. 예를 들어, `7`은 두배"
|
|
"로 만들면 `14`이므로 `5`가 됩니다."
|
|
|
|
#: src/testing/exercise.md
|
|
msgid "Sum all the undoubled and doubled digits."
|
|
msgstr "모든 자리의 숫자를 더합니다."
|
|
|
|
#: src/testing/exercise.md
|
|
msgid "The credit card number is valid if the sum ends with `0`."
|
|
msgstr "합계의 끝자리가 `0`인 경우 유효한 신용카드 번호입니다."
|
|
|
|
#: src/testing/exercise.md
|
|
msgid ""
|
|
"The provided code provides a buggy implementation of the luhn algorithm, "
|
|
"along with two basic unit tests that confirm that most the algorithm is "
|
|
"implemented correctly."
|
|
msgstr ""
|
|
"제공된 코드는 대부분의 알고리즘이 올바르게 구현되었는지 확인하는 두 가지 기"
|
|
"본 단위 테스트와 함께 luhn 알고리즘의 버그가 있는 구현을 제공합니다."
|
|
|
|
#: src/testing/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Copy the code below to <https://play.rust-lang.org/> and write additional "
|
|
"tests to uncover bugs in the provided implementation, fixing any bugs you "
|
|
"find."
|
|
msgstr ""
|
|
"아래 코드를 <https://play.rust-lang.org/>에 복사하고 빠진 함수와 메서드를 채"
|
|
"워봅니다:"
|
|
|
|
#: src/testing/exercise.md src/testing/solution.md
|
|
msgid "\"4263 9826 4026 9299\""
|
|
msgstr "\"4263 9826 4026 9299\""
|
|
|
|
#: src/testing/exercise.md src/testing/solution.md
|
|
msgid "\"4539 3195 0343 6467\""
|
|
msgstr "\"4539 3195 0343 6467\""
|
|
|
|
#: src/testing/exercise.md src/testing/solution.md
|
|
msgid "\"7992 7398 713\""
|
|
msgstr "\"7992 7398 713\""
|
|
|
|
#: src/testing/exercise.md src/testing/solution.md
|
|
msgid "\"4223 9826 4026 9299\""
|
|
msgstr "\"4223 9826 4026 9299\""
|
|
|
|
#: src/testing/exercise.md src/testing/solution.md
|
|
msgid "\"4539 3195 0343 6476\""
|
|
msgstr "\"4539 3195 0343 6476\""
|
|
|
|
#: src/testing/exercise.md src/testing/solution.md
|
|
msgid "\"8273 1232 7352 0569\""
|
|
msgstr "\"8273 1232 7352 0569\""
|
|
|
|
#: src/testing/solution.md
|
|
msgid "// This is the buggy version that appears in the problem.\n"
|
|
msgstr "// 문제에 표시되는 버그가 있는 버전입니다.\n"
|
|
|
|
#: src/testing/solution.md
|
|
msgid "// This is the solution and passes all of the tests below.\n"
|
|
msgstr "// 솔루션이며 아래의 모든 테스트를 통과합니다.\n"
|
|
|
|
#: src/testing/solution.md
|
|
msgid "\"1234 5678 1234 5670\""
|
|
msgstr "\"1234 5678 1234 5670\""
|
|
|
|
#: src/testing/solution.md
|
|
msgid "\"Is {cc_number} a valid credit card number? {}\""
|
|
msgstr "\"{cc_number}은(는) 유효한 신용카드 번호인가요? {}\""
|
|
|
|
#: src/testing/solution.md
|
|
msgid "\"yes\""
|
|
msgstr "\"예\""
|
|
|
|
#: src/testing/solution.md
|
|
msgid "\"no\""
|
|
msgstr "\"아니요\""
|
|
|
|
#: src/testing/solution.md
|
|
msgid "\"foo 0 0\""
|
|
msgstr "\"foo 0 0\""
|
|
|
|
#: src/testing/solution.md
|
|
msgid "\" \""
|
|
msgstr "\" \""
|
|
|
|
#: src/testing/solution.md
|
|
msgid "\" \""
|
|
msgstr "\" \""
|
|
|
|
#: src/testing/solution.md
|
|
msgid "\" \""
|
|
msgstr "\" \""
|
|
|
|
#: src/testing/solution.md
|
|
msgid "\"0\""
|
|
msgstr "\"0\""
|
|
|
|
#: src/testing/solution.md
|
|
msgid "\" 0 0 \""
|
|
msgstr "\" 0 0 \""
|
|
|
|
#: src/welcome-day-4-afternoon.md
|
|
msgid "[Error Handling](./error-handling.md) (55 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/welcome-day-4-afternoon.md
|
|
msgid "[Unsafe Rust](./unsafe-rust.md) (1 hour and 5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/error-handling.md
|
|
msgid "[Panics](./error-handling/panics.md) (3 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/error-handling.md
|
|
msgid "[Try Operator](./error-handling/try.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/error-handling.md
|
|
msgid "[Try Conversions](./error-handling/try-conversions.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/error-handling.md
|
|
msgid "[Error Trait](./error-handling/error.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/error-handling.md
|
|
msgid ""
|
|
"[thiserror and anyhow](./error-handling/thiserror-and-anyhow.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/error-handling.md
|
|
msgid ""
|
|
"[Exercise: Rewriting with Result](./error-handling/exercise.md) (30 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid "Rust handles fatal errors with a \"panic\"."
|
|
msgstr "Rust는 '패닉'으로 치명적인 오류를 처리합니다."
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid "Rust will trigger a panic if a fatal error happens at runtime:"
|
|
msgstr "러스트는 수행 중 치명적인 오류를 만나면 패닉을 발생할 것입니다:"
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid "\"v[100]: {}\""
|
|
msgstr "\"v[100]: {}\""
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid "Panics are for unrecoverable and unexpected errors."
|
|
msgstr "패닉은 복구할 수 없고 예상치 못한 오류입니다."
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid "Panics are symptoms of bugs in the program."
|
|
msgstr "패닉은 프로그램에 버그가 있다는 것을 나타냅니다."
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid "Runtime failures like failed bounds checks can panic"
|
|
msgstr "경계 검사 실패와 같은 런타임 실패로 인해 패닉이 발생할 수 있습니다."
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid "Assertions (such as `assert!`) panic on failure"
|
|
msgstr "실패 시 어설션(예: `assert!`) 패닉"
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid "Purpose-specific panics can use the `panic!` macro."
|
|
msgstr "목적별 패닉은 `panic!` 매크로를 사용할 수 있습니다."
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid ""
|
|
"A panic will \"unwind\" the stack, dropping values just as if the functions "
|
|
"had returned."
|
|
msgstr "패닉은 스택을 '해제'하여 함수가 반환된 것처럼 값을 삭제합니다."
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid ""
|
|
"Use non-panicking APIs (such as `Vec::get`) if crashing is not acceptable."
|
|
msgstr ""
|
|
"충돌(크래시)을 허용하지 않아야 하는 경우, 패닉을 유발하지 않는 API(`Vec::get`"
|
|
"등)를 사용하면 됩니다."
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid ""
|
|
"By default, a panic will cause the stack to unwind. The unwinding can be "
|
|
"caught:"
|
|
msgstr ""
|
|
"기본적으로, 패닉이 발생하면 스택 되감기를 합니다. 스택 되감기는 다음과 같이 "
|
|
"캐치가 가능합니다:"
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid "\"No problem here!\""
|
|
msgstr "\"괜찮습니다.\""
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid "\"{result:?}\""
|
|
msgstr "\"{result:?}\""
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid "\"oh no!\""
|
|
msgstr "\"이런\""
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid ""
|
|
"Catching is unusual; do not attempt to implement exceptions with "
|
|
"`catch_unwind`!"
|
|
msgstr ""
|
|
"포착은 흔하지 않습니다. `catch_unwind`로 예외를 구현하려고 시도하지 마세요."
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid ""
|
|
"This can be useful in servers which should keep running even if a single "
|
|
"request crashes."
|
|
msgstr ""
|
|
"이것은 단일 요청이 크래시 되더라도 프로그램이 계속 실행되야 하는 서버에 유용"
|
|
"합니다."
|
|
|
|
#: src/error-handling/panics.md
|
|
msgid "This does not work if `panic = 'abort'` is set in your `Cargo.toml`."
|
|
msgstr ""
|
|
"만약 `Cargo.toml`설정파일에 `panic = abort`을 설정했다면 크래시를 캐치할 수 "
|
|
"없습니다."
|
|
|
|
#: src/error-handling/try.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Runtime errors like connection-refused or file-not-found are handled with "
|
|
"the `Result` type, but matching this type on every call can be cumbersome. "
|
|
"The try-operator `?` is used to return errors to the caller. It lets you "
|
|
"turn the common"
|
|
msgstr ""
|
|
"연결 거부 또는 파일을 찾을 수 없음과 같은 런타임 오류는 `Result` 타입으로 처"
|
|
"리되지만 모든 호출에서 이 타입을 일치시키는 것은 번거로울 수 있습니다. try "
|
|
"연산자 `?`는 호출자에게 오류를 반환하는 데 사용됩니다. 이를 통해 일반적인"
|
|
|
|
#: src/error-handling/try.md
|
|
msgid "into the much simpler"
|
|
msgstr "이렇게 짧게 쓸 수 있습니다"
|
|
|
|
#: src/error-handling/try.md
|
|
msgid "We can use this to simplify our error handling code:"
|
|
msgstr "이제 우리 예제에 적용해 보겠습니다:"
|
|
|
|
#: src/error-handling/try.md
|
|
msgid "//fs::write(\"config.dat\", \"alice\").unwrap();\n"
|
|
msgstr "//fs::write(\"config.dat\", \"alice\").unwrap();\n"
|
|
|
|
#: src/error-handling/try.md src/error-handling/try-conversions.md
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid "\"config.dat\""
|
|
msgstr "\"config.dat\""
|
|
|
|
#: src/error-handling/try.md src/error-handling/try-conversions.md
|
|
msgid "\"username or error: {username:?}\""
|
|
msgstr "\"사용자 이름 또는 오류: {username:?}\""
|
|
|
|
#: src/error-handling/try.md
|
|
msgid "Simplify the `read_username` function to use `?`."
|
|
msgstr "`?`를 사용하도록 `read_username` 함수를 단순화합니다."
|
|
|
|
#: src/error-handling/try.md
|
|
msgid "The `username` variable can be either `Ok(string)` or `Err(error)`."
|
|
msgstr "`username` 변수는 `Ok(string)`이거나 `Err(error)`일 수 있습니다."
|
|
|
|
#: src/error-handling/try.md
|
|
msgid ""
|
|
"Use the `fs::write` call to test out the different scenarios: no file, empty "
|
|
"file, file with username."
|
|
msgstr ""
|
|
"`fs::write` 메서드를 사용하여 파일이 없거나, 비었거나, 중복되는 경우 등을 테"
|
|
"스트해 봅니다."
|
|
|
|
#: src/error-handling/try.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Note that `main` can return a `Result<(), E>` as long as it implements `std::"
|
|
"process::Termination`. In practice, this means that `E` implements `Debug`. "
|
|
"The executable will print the `Err` variant and return a nonzero exit status "
|
|
"on error."
|
|
msgstr ""
|
|
"`main`은 `std::process:Termination`을 구현하는 한 `Result<(), E>`를 반환할 "
|
|
"수 있습니다. 실제로는 `E`가 `Debug`를 구현한다는 것을 의미합니다. 실행 파일"
|
|
"은 `Err` 변형을 출력하고 오류 발생 시 0이 아닌 종료 상태를 반환합니다."
|
|
|
|
#: src/error-handling/try-conversions.md
|
|
msgid ""
|
|
"The effective expansion of `?` is a little more complicated than previously "
|
|
"indicated:"
|
|
msgstr "실제로 `?`가 적용되는 과정은 아까 설명한 것 보다 좀 더 복잡합니다:"
|
|
|
|
#: src/error-handling/try-conversions.md
|
|
msgid "works the same as"
|
|
msgstr "위 표현은 아래와 같습니다"
|
|
|
|
#: src/error-handling/try-conversions.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The `From::from` call here means we attempt to convert the error type to the "
|
|
"type returned by the function. This makes it easy to encapsulate errors into "
|
|
"higher-level errors."
|
|
msgstr ""
|
|
"`From::from`을 통해 원래의 에러 타입을 이 함수가 반환하는 에러 타입으로 변환"
|
|
"하고 있습니다:"
|
|
|
|
#: src/error-handling/try-conversions.md
|
|
msgid "\"IO error: {e}\""
|
|
msgstr "\"IO 오류: {e}\""
|
|
|
|
#: src/error-handling/try-conversions.md
|
|
#, fuzzy
|
|
msgid "\"Found no username in {path}\""
|
|
msgstr "\"{0}에서 사용자 이름을 찾을 수 없습니다.\""
|
|
|
|
#: src/error-handling/try-conversions.md
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid "//fs::write(\"config.dat\", \"\").unwrap();\n"
|
|
msgstr "//fs::write(\"config.dat\", \"\").unwrap();\n"
|
|
|
|
#: src/error-handling/try-conversions.md
|
|
msgid ""
|
|
"The `?` operator must return a value compatible with the return type of the "
|
|
"function. For `Result`, it means that the error types have to be compatible. "
|
|
"A function that returns `Result<T, ErrorOuter>` can only use `?` on a value "
|
|
"of type `Result<U, ErrorInner>` if `ErrorOuter` and `ErrorInner` are the "
|
|
"same type or if `ErrorOuter` implements `From<ErrorInner>`."
|
|
msgstr ""
|
|
|
|
#: src/error-handling/try-conversions.md
|
|
msgid ""
|
|
"A common alternative to a `From` implementation is `Result::map_err`, "
|
|
"especially when the conversion only happens in one place."
|
|
msgstr ""
|
|
"`From` 구현의 일반적인 대안은 특히 변환이 한 곳에서만 발생하는 경우 `Result::"
|
|
"map_err`입니다."
|
|
|
|
#: src/error-handling/try-conversions.md
|
|
msgid ""
|
|
"There is no compatibility requirement for `Option`. A function returning "
|
|
"`Option<T>` can use the `?` operator on `Option<U>` for arbitrary `T` and "
|
|
"`U` types."
|
|
msgstr ""
|
|
|
|
#: src/error-handling/try-conversions.md
|
|
msgid ""
|
|
"A function that returns `Result` cannot use `?` on `Option` and vice versa. "
|
|
"However, `Option::ok_or` converts `Option` to `Result` whereas `Result::ok` "
|
|
"turns `Result` into `Option`."
|
|
msgstr ""
|
|
|
|
#: src/error-handling/error.md
|
|
msgid "Dynamic Error Types"
|
|
msgstr "동적인 에러 타입"
|
|
|
|
#: src/error-handling/error.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Sometimes we want to allow any type of error to be returned without writing "
|
|
"our own enum covering all the different possibilities. The `std::error::"
|
|
"Error` trait makes it easy to create a trait object that can contain any "
|
|
"error."
|
|
msgstr ""
|
|
"때때로 우리는, 발생 가능한 모든 에러를 일일히 열거하지 않고, 어떤 종류의 에러"
|
|
"라도 상관없이 리턴하고 싶을 때가 있습니다. `std::error::Error`를 이용하면 쉽"
|
|
"습니다."
|
|
|
|
#: src/error-handling/error.md
|
|
msgid "\"count.dat\""
|
|
msgstr "\"count.dat\""
|
|
|
|
#: src/error-handling/error.md
|
|
msgid "\"1i3\""
|
|
msgstr "\"1i3\""
|
|
|
|
#: src/error-handling/error.md
|
|
msgid "\"Count: {count}\""
|
|
msgstr "\"개수: {count}\""
|
|
|
|
#: src/error-handling/error.md
|
|
msgid "\"Error: {err}\""
|
|
msgstr "\"오류: {err}\""
|
|
|
|
#: src/error-handling/error.md
|
|
msgid ""
|
|
"The `read_count` function can return `std::io::Error` (from file operations) "
|
|
"or `std::num::ParseIntError` (from `String::parse`)."
|
|
msgstr ""
|
|
"`read_count` 함수는 `std::io::Error`(파일 작업에서) 또는 `std::num::"
|
|
"ParseIntError`(`String::parse`에서)를 반환할 수 있습니다."
|
|
|
|
#: src/error-handling/error.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Boxing errors saves on code, but gives up the ability to cleanly handle "
|
|
"different error cases differently in the program. As such it's generally not "
|
|
"a good idea to use `Box<dyn Error>` in the public API of a library, but it "
|
|
"can be a good option in a program where you just want to display the error "
|
|
"message somewhere."
|
|
msgstr ""
|
|
"이렇게 하면 코드의 양을 줄일 수 있습니다. 그러나 서로 다른 종류의 에러를 구별"
|
|
"하여 다르게 처리하는 것이 불가능해 집니다. 때문에, `Box<dyn Error>`를 라이브"
|
|
"러리의 API로 노출하는게 좋은 디자인은 아닙니다. 에러 발생 시, 그저 에러 메시"
|
|
"지를 출력하고 싶은 경우와 같이 제한된 상황에서는 유용할 수 있습니다."
|
|
|
|
#: src/error-handling/error.md
|
|
msgid ""
|
|
"Make sure to implement the `std::error::Error` trait when defining a custom "
|
|
"error type so it can be boxed. But if you need to support the `no_std` "
|
|
"attribute, keep in mind that the `std::error::Error` trait is currently "
|
|
"compatible with `no_std` in [nightly](https://github.com/rust-lang/rust/"
|
|
"issues/103765) only."
|
|
msgstr ""
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The [`thiserror`](https://docs.rs/thiserror/) and [`anyhow`](https://docs.rs/"
|
|
"anyhow/) crates are widely used to simplify error handling."
|
|
msgstr ""
|
|
"[`thiserror`](https://docs.rs/thiserror/) 및 [`anyhow`](https://docs.rs/"
|
|
"anyhow/) 크레이트는 오류 처리를 단순화하는 데 널리 사용됩니다. `thiserror`는 "
|
|
"`From<T>`를 구현하는 맞춤 오류 타입을 만드는 데 도움이 됩니다. `anyhow`를 사"
|
|
"용하면 오류에 컨텍스트 정보를 추가하는 등 함수의 오류 처리에 도움이 됩니다."
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid ""
|
|
"`thiserror` is often used in libraries to create custom error types that "
|
|
"implement `From<T>`."
|
|
msgstr ""
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid ""
|
|
"`anyhow` is often used by applications to help with error handling in "
|
|
"functions, including adding contextual information to your errors."
|
|
msgstr ""
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid "\"Found no username in {0}\""
|
|
msgstr "\"{0}에서 사용자 이름을 찾을 수 없습니다.\""
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid "\"Failed to open {path}\""
|
|
msgstr "\"{path}을(를) 열지 못했습니다.\""
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid "\"Failed to read\""
|
|
msgstr "\"읽지 못했습니다.\""
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid "\"Username: {username}\""
|
|
msgstr "\"사용자 이름: {username}\""
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid "\"Error: {err:?}\""
|
|
msgstr "\"오류: {err:?}\""
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
#, fuzzy
|
|
msgid "`thiserror`"
|
|
msgstr "`Error`"
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The `Error` derive macro is provided by `thiserror`, and has lots of useful "
|
|
"attributes to help define error types in a compact way."
|
|
msgstr ""
|
|
"`Error` 파생 매크로는 `thiserror`에서 제공하며 유용한 오류 타입을 정의하는 "
|
|
"데 도움이 되는 `#[error]`와 같은 유용한 속성이 많습니다."
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid "The `std::error::Error` trait is derived automatically."
|
|
msgstr ""
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid "The message from `#[error]` is used to derive the `Display` trait."
|
|
msgstr ""
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid "`anyhow`"
|
|
msgstr ""
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid ""
|
|
"`anyhow::Error` is essentially a wrapper around `Box<dyn Error>`. As such "
|
|
"it's again generally not a good choice for the public API of a library, but "
|
|
"is widely used in applications."
|
|
msgstr ""
|
|
"`anyhow::Error`는 `Box<dyn Error>`의 래퍼 타입이라 할 수 있습니다. 따라서 라"
|
|
"이브러리의 공개 API로서 사용하기에 부적합하다고 할 수 있지만 많은 애플리케이"
|
|
"션에 널리 사용되고 있습니다."
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid "`anyhow::Result<V>` is a type alias for `Result<V, anyhow::Error>`."
|
|
msgstr ""
|
|
"`anyhow::Result<V>`는 `Result<V, anyhow::Error>`의 타입 앨리어스(alias)입니"
|
|
"다."
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid ""
|
|
"Actual error type inside of it can be extracted for examination if necessary."
|
|
msgstr ""
|
|
"필요하다면 `anyhow::Error`에 저장된 진짜 에러 타입을 꺼내어 검사할 수도 있습"
|
|
"니다."
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid ""
|
|
"Functionality provided by `anyhow::Result<T>` may be familiar to Go "
|
|
"developers, as it provides similar usage patterns and ergonomics to `(T, "
|
|
"error)` from Go."
|
|
msgstr ""
|
|
"`anyhow::Result<T>`가 제공하는 기능들이 Go 언어 개발자들에게는 익숙할 것입니"
|
|
"다. Go언어에서 반환 값으로 사용하는 `(T, error)` 패턴과 비슷하기 때문입니다."
|
|
|
|
#: src/error-handling/thiserror-and-anyhow.md
|
|
msgid ""
|
|
"`anyhow::Context` is a trait implemented for the standard `Result` and "
|
|
"`Option` types. `use anyhow::Context` is necessary to enable `.context()` "
|
|
"and `.with_context()` on those types."
|
|
msgstr ""
|
|
|
|
#: src/error-handling/exercise.md
|
|
#, fuzzy
|
|
msgid "Exercise: Rewriting with Result"
|
|
msgstr "연습문제: 결과로 다시 작성"
|
|
|
|
#: src/error-handling/exercise.md
|
|
msgid ""
|
|
"The following implements a very simple parser for an expression language. "
|
|
"However, it handles errors by panicking. Rewrite it to instead use idiomatic "
|
|
"error handling and propagate errors to a return from `main`. Feel free to "
|
|
"use `thiserror` and `anyhow`."
|
|
msgstr ""
|
|
"다음은 표현식 언어의 매우 간단한 파서를 구현합니다. 그러나 패닉을 통해 오류"
|
|
"를 처리합니다. 대신 관용적인 오류 처리를 사용하고 오류를 `main`의 반환으로 전"
|
|
"파하도록 다시 작성합니다. `thiserror` 및 `anyhow`를 얼마든지 사용하세요."
|
|
|
|
#: src/error-handling/exercise.md
|
|
msgid ""
|
|
"HINT: start by fixing error handling in the `parse` function. Once that is "
|
|
"working correctly, update `Tokenizer` to implement "
|
|
"`Iterator<Item=Result<Token, TokenizerError>>` and handle that in the parser."
|
|
msgstr ""
|
|
"힌트: 먼저 `parse` 함수에서 오류 처리를 수정하세요. 제대로 작동하면 "
|
|
"`Iterator<Item=Result<Token, TokenizerError>>`를 구현하도록 `Tokenizer`를 업"
|
|
"데이트하고 파서에서 처리합니다."
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "/// An arithmetic operator.\n"
|
|
msgstr "/// 산술 연산자입니다.\n"
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "/// A token in the expression language.\n"
|
|
msgstr "/// 표현식 언어의 토큰입니다.\n"
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "/// An expression in the expression language.\n"
|
|
msgstr "/// 표현식 언어의 표현식입니다.\n"
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "/// A reference to a variable.\n"
|
|
msgstr "/// 변수 참조입니다.\n"
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "/// A literal number.\n"
|
|
msgstr "/// 리터럴 숫자입니다.\n"
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "/// A binary operation.\n"
|
|
msgstr "/// 이진 연산입니다.\n"
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "'_'"
|
|
msgstr "'_'"
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "'+'"
|
|
msgstr "'+'"
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "'-'"
|
|
msgstr "'-'"
|
|
|
|
#: src/error-handling/exercise.md
|
|
msgid "\"Unexpected character {c}\""
|
|
msgstr "\"예기치 않은 문자 {c}\""
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "\"Unexpected end of input\""
|
|
msgstr "\"예기치 않은 입력 종료\""
|
|
|
|
#: src/error-handling/exercise.md
|
|
msgid "\"Invalid 32-bit integer'\""
|
|
msgstr "\"잘못된 32비트 정수입니다.'\""
|
|
|
|
#: src/error-handling/exercise.md
|
|
msgid "\"Unexpected token {tok:?}\""
|
|
msgstr "\"예기치 않은 토큰 {tok:?}\""
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "// Look ahead to parse a binary operation if present.\n"
|
|
msgstr "// 이진 연산이 있는 경우 이를 파싱합니다.\n"
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "\"10+foo+20-30\""
|
|
msgstr "\"10+foo+20-30\""
|
|
|
|
#: src/error-handling/exercise.md src/error-handling/solution.md
|
|
msgid "\"{expr:?}\""
|
|
msgstr "\"{expr:?}\""
|
|
|
|
#: src/error-handling/solution.md
|
|
msgid "\"Unexpected character '{0}' in input\""
|
|
msgstr "\"입력에 예상치 못한 문자 '{0}'이(가) 있습니다.\""
|
|
|
|
#: src/error-handling/solution.md
|
|
msgid "\"Tokenizer error: {0}\""
|
|
msgstr "\"토큰나이저 오류: {0}\""
|
|
|
|
#: src/error-handling/solution.md
|
|
msgid "\"Unexpected token {0:?}\""
|
|
msgstr "\"예기치 않은 토큰 {0:?}\""
|
|
|
|
#: src/error-handling/solution.md
|
|
msgid "\"Invalid number\""
|
|
msgstr "\"잘못된 번호\""
|
|
|
|
#: src/unsafe-rust.md
|
|
msgid "[Unsafe](./unsafe-rust/unsafe.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/unsafe-rust.md
|
|
msgid ""
|
|
"[Dereferencing Raw Pointers](./unsafe-rust/dereferencing.md) (10 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/unsafe-rust.md
|
|
msgid "[Mutable Static Variables](./unsafe-rust/mutable-static.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/unsafe-rust.md
|
|
msgid "[Unions](./unsafe-rust/unions.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/unsafe-rust.md
|
|
msgid "[Unsafe Functions](./unsafe-rust/unsafe-functions.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/unsafe-rust.md
|
|
msgid "[Unsafe Traits](./unsafe-rust/unsafe-traits.md) (5 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/unsafe-rust.md
|
|
msgid "[Exercise: FFI Wrapper](./unsafe-rust/exercise.md) (30 minutes)"
|
|
msgstr ""
|
|
|
|
#: src/unsafe-rust.md
|
|
msgid "This segment should take about 1 hour and 5 minutes"
|
|
msgstr ""
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
msgid "The Rust language has two parts:"
|
|
msgstr "러스트로 작성된 프로그램은 크게 두 부분으로 나뉩니다:"
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
msgid "**Safe Rust:** memory safe, no undefined behavior possible."
|
|
msgstr ""
|
|
"**안전한 러스트:** 메모리 관련 오류 발생 불가능, 정의되지 않은 동작 없음."
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
msgid ""
|
|
"**Unsafe Rust:** can trigger undefined behavior if preconditions are "
|
|
"violated."
|
|
msgstr ""
|
|
"**안전하지 않은 러스트:** 특별한 조건을 만족하지 않은채로 사용되면 정의되지 "
|
|
"않은 동작을 유발할 수 있음."
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"We saw mostly safe Rust in this course, but it's important to know what "
|
|
"Unsafe Rust is."
|
|
msgstr ""
|
|
"이 강의는 대부분 안전한 러스트에 대해 다루지만 안전하지 않은 러스트가 무엇인"
|
|
"지는 알아 두어야 합니다."
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
msgid ""
|
|
"Unsafe code is usually small and isolated, and its correctness should be "
|
|
"carefully documented. It is usually wrapped in a safe abstraction layer."
|
|
msgstr ""
|
|
"보통, 안전하지 않은 러스트 코드는 크기가 작으며, 독립적으로 존재합니다. 그리"
|
|
"고 코드가 왜 잘 작동하는지에 대해 세밀하게 문서화가 되어 있습니다. 그리고, 많"
|
|
"은 경우 안전한 러스트 코드를 통해서 추상화를 시킨 후 사용하게 됩니다."
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
msgid "Unsafe Rust gives you access to five new capabilities:"
|
|
msgstr ""
|
|
"안전하지 않은 러스트를 이용하면 다음과 같은 다섯 가지 것들이 가능해 집니다:"
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
msgid "Dereference raw pointers."
|
|
msgstr "원시 포인터 역참조(따라가기)"
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
msgid "Access or modify mutable static variables."
|
|
msgstr "정적 가변변수 접근 및 수정."
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
msgid "Access `union` fields."
|
|
msgstr "`union` 필드 접근."
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
msgid "Call `unsafe` functions, including `extern` functions."
|
|
msgstr "`extern` 함수를 포함한 `unsafe` 함수 호출."
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
msgid "Implement `unsafe` traits."
|
|
msgstr "`unsafe` 트레잇 구현."
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
msgid ""
|
|
"We will briefly cover unsafe capabilities next. For full details, please see "
|
|
"[Chapter 19.1 in the Rust Book](https://doc.rust-lang.org/book/ch19-01-"
|
|
"unsafe-rust.html) and the [Rustonomicon](https://doc.rust-lang.org/nomicon/)."
|
|
msgstr ""
|
|
"위 기능들에 대해 간략히 살펴보겠습니다. 자세한 내용은 [러스트 프로그래밍 언"
|
|
"어, 19.1절](https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html)과 "
|
|
"[Rustonomicon](https://doc.rust-lang.org/nomicon/)를 참조하세요."
|
|
|
|
#: src/unsafe-rust/unsafe.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Unsafe Rust does not mean the code is incorrect. It means that developers "
|
|
"have turned off some compiler safety features and have to write correct code "
|
|
"by themselves. It means the compiler no longer enforces Rust's memory-safety "
|
|
"rules."
|
|
msgstr ""
|
|
"안전하지 않은 러스트라고 해서 코드가 부정확 하다는 뜻은 아닙니다. 여기서 안전"
|
|
"하지 않다의 의미는 컴파일러가 제공해주는 안전 장치들이 꺼진 상태이며, 개발자"
|
|
"가 스스로 정확하고 안전한 코드를 작성해야 함을 의미합니다. 이는 컴파일러가 "
|
|
"더 이상 러스트의 메모리 안전과 관련된 규칙들을 적용하지 않는다는 것입니다."
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid "Creating pointers is safe, but dereferencing them requires `unsafe`:"
|
|
msgstr ""
|
|
"포인터를 만드는 것은 안전합니다. 하지만 역참조(따라가기)할 경우 `unsafe`가 필"
|
|
"요합니다:"
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid "\"careful!\""
|
|
msgstr "\"조심하세요!\""
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"// Safe because r1 and r2 were obtained from references and so are\n"
|
|
" // guaranteed to be non-null and properly aligned, the objects "
|
|
"underlying\n"
|
|
" // the references from which they were obtained are live throughout the\n"
|
|
" // whole unsafe block, and they are not accessed either through the\n"
|
|
" // references or concurrently through any other pointers.\n"
|
|
msgstr ""
|
|
"```rust,editable\n"
|
|
"fn main() {\n"
|
|
" let mut num = 5;\n"
|
|
"\n"
|
|
" let r1 = &mut num as *mut i32;\n"
|
|
" let r2 = r1 as *const i32;\n"
|
|
"\n"
|
|
" // Safe because r1 and r2 were obtained from references and so are\n"
|
|
" // guaranteed to be non-null and properly aligned, the objects "
|
|
"underlying\n"
|
|
" // the references from which they were obtained are live throughout the\n"
|
|
" // whole unsafe block, and they are not accessed either through the\n"
|
|
" // references or concurrently through any other pointers.\n"
|
|
" unsafe {\n"
|
|
" println!(\"r1 is: {}\", *r1);\n"
|
|
" *r1 = 10;\n"
|
|
" println!(\"r2 is: {}\", *r2);\n"
|
|
" }\n"
|
|
"}\n"
|
|
"```"
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid "\"r1 is: {}\""
|
|
msgstr "\"r1은 {}입니다.\""
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid "\"uhoh\""
|
|
msgstr "\"이런\""
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid "\"r2 is: {}\""
|
|
msgstr "\"r2는 {}입니다.\""
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid ""
|
|
"// NOT SAFE. DO NOT DO THIS.\n"
|
|
" /*\n"
|
|
" let r3: &String = unsafe { &*r1 };\n"
|
|
" drop(s);\n"
|
|
" println!(\"r3 is: {}\", *r3);\n"
|
|
" */"
|
|
msgstr ""
|
|
"// 안전하지 않음. 이렇게 하지 마세요.\n"
|
|
" /*\n"
|
|
" let r3: &String = unsafe { &*r1 };\n"
|
|
" drop(s);\n"
|
|
" println!(\"r3 is: {}\", *r3);\n"
|
|
" */"
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid ""
|
|
"It is good practice (and required by the Android Rust style guide) to write "
|
|
"a comment for each `unsafe` block explaining how the code inside it "
|
|
"satisfies the safety requirements of the unsafe operations it is doing."
|
|
msgstr ""
|
|
"모든 `unsafe` 블록에 대해 왜 그 코드가 안전한지에 대한 설명을 주석으로 다는 "
|
|
"것은 좋은 습관입니다(사실 안드로이드의 러스트 스타일 가이드에서는 이게 필수입"
|
|
"니다)."
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid ""
|
|
"In the case of pointer dereferences, this means that the pointers must be "
|
|
"[_valid_](https://doc.rust-lang.org/std/ptr/index.html#safety), i.e.:"
|
|
msgstr ""
|
|
"포인터 역참조를 할 경우, 포인터가 [_유효_](https://doc.rust-lang.org/std/ptr/"
|
|
"index.html#safety)해야 합니다. 예를 들어:"
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid "The pointer must be non-null."
|
|
msgstr "포인터는 null이면 안됩니다."
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid ""
|
|
"The pointer must be _dereferenceable_ (within the bounds of a single "
|
|
"allocated object)."
|
|
msgstr ""
|
|
"포인터는 따라가기가 가능해야 합니다 (객체의 어느 한 부분을 가리키고 있어야 합"
|
|
"니다)."
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid "The object must not have been deallocated."
|
|
msgstr "이미 반환된 객체를 가리키면 안됩니다."
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid "There must not be concurrent accesses to the same location."
|
|
msgstr "같은 위치에 대해 동시적인 접근이 있으면 안됩니다."
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid ""
|
|
"If the pointer was obtained by casting a reference, the underlying object "
|
|
"must be live and no reference may be used to access the memory."
|
|
msgstr ""
|
|
"참조를 캐스팅 해서 포인터를 만들었다면, 그 참조가 가리키는 객체는 살아 있어"
|
|
"야 하며, 그 객체의 메모리를 접근하는 참조가 하나도 없어야 합니다."
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
msgid "In most cases the pointer must also be properly aligned."
|
|
msgstr "대부분의 경우 포인터는 align되어 있어야 합니다."
|
|
|
|
#: src/unsafe-rust/dereferencing.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The \"NOT SAFE\" section gives an example of a common kind of UB bug: `*r1` "
|
|
"has the `'static` lifetime, so `r3` has type `&'static String`, and thus "
|
|
"outlives `s`. Creating a reference from a pointer requires _great care_."
|
|
msgstr ""
|
|
"\"안전하지 않음' 섹션은 일반적인 UB 버그의 예를 제공합니다. `*r1`은 "
|
|
"`'static` 전체 기간을 가지므로 `r3`의 타입은 `&'static String`이며 `s`보다 오"
|
|
"래 지속됩니다. 포인터에서 참조를 만들려면 _주의가 필요합니다_."
|
|
|
|
#: src/unsafe-rust/mutable-static.md
|
|
msgid "It is safe to read an immutable static variable:"
|
|
msgstr "불변 정적변수를 읽는 것은 안전합니다:"
|
|
|
|
#: src/unsafe-rust/mutable-static.md
|
|
#, fuzzy
|
|
msgid "\"Hello, world!\""
|
|
msgstr "Hello World!"
|
|
|
|
#: src/unsafe-rust/mutable-static.md
|
|
msgid "\"HELLO_WORLD: {HELLO_WORLD}\""
|
|
msgstr "\"HELLO_WORLD: {HELLO_WORLD}\""
|
|
|
|
#: src/unsafe-rust/mutable-static.md
|
|
msgid ""
|
|
"However, since data races can occur, it is unsafe to read and write mutable "
|
|
"static variables:"
|
|
msgstr ""
|
|
"하지만, 데이터 레이스가 발생할 수 있으므로 정적 가변변수를 읽고 쓰는 것은 안"
|
|
"전하지 않습니다:"
|
|
|
|
#: src/unsafe-rust/mutable-static.md
|
|
msgid "\"COUNTER: {COUNTER}\""
|
|
msgstr "\"COUNTER: {COUNTER}\""
|
|
|
|
#: src/unsafe-rust/mutable-static.md
|
|
msgid ""
|
|
"The program here is safe because it is single-threaded. However, the Rust "
|
|
"compiler is conservative and will assume the worst. Try removing the "
|
|
"`unsafe` and see how the compiler explains that it is undefined behavior to "
|
|
"mutate a static from multiple threads."
|
|
msgstr ""
|
|
"이 프로그램은 단일 스레드이므로 안전합니다. 그러나 Rust 컴파일러는 보수적이"
|
|
"며 최악의 상황을 가정합니다. `unsafe`를 삭제해 보고 컴파일러가 여러 스레드에"
|
|
"서 static을 변경하는 것이 정의되지 않은 동작이라고 어떻게 설명하는지 확인하세"
|
|
"요."
|
|
|
|
#: src/unsafe-rust/mutable-static.md
|
|
msgid ""
|
|
"Using a mutable static is generally a bad idea, but there are some cases "
|
|
"where it might make sense in low-level `no_std` code, such as implementing a "
|
|
"heap allocator or working with some C APIs."
|
|
msgstr ""
|
|
"일반적으로 이야기 해서, 정적 가변 변수를 쓰는 것은 좋은 아이디어가 아닙니다. "
|
|
"그러나 `no_std`와 같은 저수준 코딩을 할 경우에는 필요하기도 합니다. 예를 들"
|
|
"어 힙 할당기를 구현하거나, C API를 사용하는 게 그런 경우입니다."
|
|
|
|
#: src/unsafe-rust/unions.md
|
|
msgid "Unions are like enums, but you need to track the active field yourself:"
|
|
msgstr ""
|
|
"유니온 타입은 열거형(enum)과 비슷하지만, 어떤 필드에 해당하는 값을 가지고 있"
|
|
"는지 여부를 프로그래머가 수동으로 추적해야 합니다:"
|
|
|
|
#: src/unsafe-rust/unions.md
|
|
msgid "\"int: {}\""
|
|
msgstr "\"int: {}\""
|
|
|
|
#: src/unsafe-rust/unions.md
|
|
msgid "\"bool: {}\""
|
|
msgstr "\"부울: {}\""
|
|
|
|
#: src/unsafe-rust/unions.md
|
|
#, fuzzy
|
|
msgid "// Undefined behavior!\n"
|
|
msgstr "런타임 시 정의되지 않음(undefined) 동작 없음:"
|
|
|
|
#: src/unsafe-rust/unions.md
|
|
msgid ""
|
|
"Unions are very rarely needed in Rust as you can usually use an enum. They "
|
|
"are occasionally needed for interacting with C library APIs."
|
|
msgstr ""
|
|
"러스트에는 열거형이 있기 때문에 유니온이 필요한 경우는 극히 드뭅니다. 유니온"
|
|
"은 C 라이브러리 API를 사용할 때 가끔 필요합니다."
|
|
|
|
#: src/unsafe-rust/unions.md
|
|
msgid ""
|
|
"If you just want to reinterpret bytes as a different type, you probably want "
|
|
"[`std::mem::transmute`](https://doc.rust-lang.org/stable/std/mem/fn."
|
|
"transmute.html) or a safe wrapper such as the [`zerocopy`](https://crates.io/"
|
|
"crates/zerocopy) crate."
|
|
msgstr ""
|
|
"바이트들을 특정 타입으로 재해석 하고 싶다면 [`std::mem::transmute`](https://"
|
|
"doc.rust-lang.org/stable/std/mem/fn.transmute.html)나 좀 더 안전한 "
|
|
"[`zerocopy`](https://crates.io/crates/zerocopy) 크레이트를 사용하세요."
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid "Calling Unsafe Functions"
|
|
msgstr "안전하지 않은 함수 호출"
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid ""
|
|
"A function or method can be marked `unsafe` if it has extra preconditions "
|
|
"you must uphold to avoid undefined behaviour:"
|
|
msgstr ""
|
|
"함수나 메서드가 정의되지 않은 동작으로 빠지지 않게 하기 위해서 만족해야 하는 "
|
|
"전제 조건이 있는 경우, 그 함수나 메서드를 `unsafe`로 표시할 수 있습니다:"
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md src/unsafe-rust/exercise.md
|
|
#: src/unsafe-rust/solution.md src/android/interoperability/with-c.md
|
|
#: src/android/interoperability/with-c/rust.md
|
|
#: src/android/interoperability/cpp/cpp-bridge.md
|
|
#: src/exercises/chromium/build-rules.md src/bare-metal/aps/inline-assembly.md
|
|
#: src/bare-metal/aps/better-uart/using.md src/bare-metal/aps/logging/using.md
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "\"C\""
|
|
msgstr "\"C\""
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid "\"🗻∈🌏\""
|
|
msgstr "\"🗻∈🌏\""
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid ""
|
|
"// Safe because the indices are in the correct order, within the bounds of\n"
|
|
" // the string slice, and lie on UTF-8 sequence boundaries.\n"
|
|
msgstr ""
|
|
"// 색인이 올바른 순서이고 문자열 슬라이스의 경계 내에\n"
|
|
" // 있으며 UTF-8 시퀀스 경계에 있으므로 안전합니다.\n"
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid "\"emoji: {}\""
|
|
msgstr "\"이모티콘: {}\""
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid "\"char count: {}\""
|
|
msgstr "\"문자 수: {}\""
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
#, fuzzy
|
|
msgid "// Undefined behavior if abs misbehaves.\n"
|
|
msgstr "런타임 시 정의되지 않음(undefined) 동작 없음:"
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid "\"Absolute value of -3 according to C: {}\""
|
|
msgstr "\"C에 따른 절댓값 -3: {}\""
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"// Not upholding the UTF-8 encoding requirement breaks memory safety!\n"
|
|
" // println!(\"emoji: {}\", unsafe { emojis.get_unchecked(0..3) });\n"
|
|
" // println!(\"char count: {}\", count_chars(unsafe {\n"
|
|
" // emojis.get_unchecked(0..3) }));\n"
|
|
msgstr ""
|
|
"// UTF-8 인코딩 요구사항을 준수하지 않으면 메모리 안전이 중단됩니다.\n"
|
|
" // println!(\"emoji: {}\", unsafe { emojis.get_unchecked(0..3) });\n"
|
|
" // println!(\"char count: {}\", count_chars(unsafe { emojis."
|
|
"get_unchecked(0..3) }));\n"
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid "Writing Unsafe Functions"
|
|
msgstr "안전하지 않은 함수 작성하기"
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid ""
|
|
"You can mark your own functions as `unsafe` if they require particular "
|
|
"conditions to avoid undefined behaviour."
|
|
msgstr ""
|
|
"여러분이 작성한 함수를 사용할 때 어떤 특별한 조건을 만족해야 한다면, `unsafe`"
|
|
"로 마킹할 수 있습니다."
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid ""
|
|
"/// Swaps the values pointed to by the given pointers.\n"
|
|
"///\n"
|
|
"/// # Safety\n"
|
|
"///\n"
|
|
"/// The pointers must be valid and properly aligned.\n"
|
|
msgstr ""
|
|
"/// 지정된 포인터가 가리키는 값을 바꿉니다.\n"
|
|
"///\n"
|
|
"/// # Safety\n"
|
|
"///\n"
|
|
"/// 포인터는 유효하고 올바르게 정렬되어야 합니다.\n"
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid "// Safe because ...\n"
|
|
msgstr "// 다음과 같은 이유로 안전합니다.\n"
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid "\"a = {}, b = {}\""
|
|
msgstr "\"a = {}, b = {}\""
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`get_unchecked`, like most `_unchecked` functions, is unsafe, because it can "
|
|
"create UB if the range is incorrect. `abs` is incorrect for a different "
|
|
"reason: it is an external function (FFI). Calling external functions is "
|
|
"usually only a problem when those functions do things with pointers which "
|
|
"might violate Rust's memory model, but in general any C function might have "
|
|
"undefined behaviour under any arbitrary circumstances."
|
|
msgstr ""
|
|
"이게 문제가 되는 경우는 대부분 외부 함수가 러스트의 메모리 모델을 위반하고 있"
|
|
"을 경우입니다. 그러나 어떤 C함수라도 어떤 임의의 상황에서는 정의되지 않은 동"
|
|
"작을 할 수 있기 때문에, 엄밀히 말해서는 모든 외부 함수에 대해서 문제입니다."
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
msgid ""
|
|
"The `\"C\"` in this example is the ABI; [other ABIs are available too]"
|
|
"(https://doc.rust-lang.org/reference/items/external-blocks.html)."
|
|
msgstr ""
|
|
"위 예제 코드에서 `\"C\"`는 ABI를 의미합니다. [다른 ABI도 있습니다.](https://"
|
|
"doc.rust-lang.org/reference/items/external-blocks.html)"
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"We wouldn't actually use pointers for a `swap` function - it can be done "
|
|
"safely with references."
|
|
msgstr ""
|
|
"참조를 사용하면 안전하게 구현할 수 있기 때문에, 실제로 포인터를 사용할 필요"
|
|
"는 없습니다."
|
|
|
|
#: src/unsafe-rust/unsafe-functions.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Note that unsafe code is allowed within an unsafe function without an "
|
|
"`unsafe` block. We can prohibit this with `#[deny(unsafe_op_in_unsafe_fn)]`. "
|
|
"Try adding it and see what happens. This will likely change in a future Rust "
|
|
"edition."
|
|
msgstr ""
|
|
"안전하지 않은(unsafe) 코드가 안전하지 않은(unsafe) 함수의 내부에서 호출될 경"
|
|
"우에는 `unsafe`블록을 지정하지 않아도 됩니다. `unsafe`블록을 항상 지정하도록 "
|
|
"하고 싶다면 `#[deny(unsafe_op_in_unsafe_fn)]`를 이용하세요. 이 어트리뷰트를 "
|
|
"추가해 보고 어떤 일이 일어나는지 확인해 보세요."
|
|
|
|
#: src/unsafe-rust/unsafe-traits.md
|
|
msgid "Implementing Unsafe Traits"
|
|
msgstr "안전하지 않은 트레잇 구현하기"
|
|
|
|
#: src/unsafe-rust/unsafe-traits.md
|
|
msgid ""
|
|
"Like with functions, you can mark a trait as `unsafe` if the implementation "
|
|
"must guarantee particular conditions to avoid undefined behaviour."
|
|
msgstr ""
|
|
"함수에서와 마찬가지로 트레잇도 `unsafe`로 마킹 가능합니다. 만약 그 트레잇을 "
|
|
"구현할 때 정의되지 않은 동작을 피하기 위해 특별한 조건이 필요하다면 말이지요."
|
|
|
|
#: src/unsafe-rust/unsafe-traits.md
|
|
msgid ""
|
|
"For example, the `zerocopy` crate has an unsafe trait that looks [something "
|
|
"like this](https://docs.rs/zerocopy/latest/zerocopy/trait.AsBytes.html):"
|
|
msgstr ""
|
|
"예를 들어 `zerocopy` 크레이트에는 [안전하지 않은 트레잇](https://docs.rs/"
|
|
"zerocopy/latest/zerocopy/trait.AsBytes.html)이 있습니다:"
|
|
|
|
#: src/unsafe-rust/unsafe-traits.md
|
|
msgid ""
|
|
"/// ...\n"
|
|
"/// # Safety\n"
|
|
"/// The type must have a defined representation and no padding.\n"
|
|
msgstr ""
|
|
"/// ...\n"
|
|
"/// # Safety\n"
|
|
"/// 타입에는 정의된 표현이 있어야 하며 패딩은 없어야 합니다.\n"
|
|
|
|
#: src/unsafe-rust/unsafe-traits.md
|
|
msgid "// Safe because u32 has a defined representation and no padding.\n"
|
|
msgstr "// u32에 정의된 표현이 있고 패딩이 없으므로 안전합니다.\n"
|
|
|
|
#: src/unsafe-rust/unsafe-traits.md
|
|
msgid ""
|
|
"There should be a `# Safety` section on the Rustdoc for the trait explaining "
|
|
"the requirements for the trait to be safely implemented."
|
|
msgstr ""
|
|
"안전하지 않은 트레잇을 만들 때에는 주석에 `# Safety` 항목이 있어서 이 트레잇"
|
|
"을 안전하게 구현하려면 어떤 요구사항들을 만족해야 하는지를 설명해야 합니다."
|
|
|
|
#: src/unsafe-rust/unsafe-traits.md
|
|
msgid ""
|
|
"The actual safety section for `AsBytes` is rather longer and more "
|
|
"complicated."
|
|
msgstr ""
|
|
"`AsBytes`에서 지켜야 할 안전성에 대한 실제 설명은 좀 더 길고 복잡합니다."
|
|
|
|
#: src/unsafe-rust/unsafe-traits.md
|
|
msgid "The built-in `Send` and `Sync` traits are unsafe."
|
|
msgstr "빌트인 트레잇인 `Send`와 `Sync`는 안전하지 않은 트레잇 입니다."
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "Safe FFI Wrapper"
|
|
msgstr "FFI래퍼"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Rust has great support for calling functions through a _foreign function "
|
|
"interface_ (FFI). We will use this to build a safe wrapper for the `libc` "
|
|
"functions you would use from C to read the names of files in a directory."
|
|
msgstr ""
|
|
"러스트는 \\_외부 기능 호출(FFI)\\_을 지원합니다. 우리는 이를 이용하여 디렉터"
|
|
"리에서 파일 이름을 읽어오는 `libc` 함수에 대한 안전한 래퍼를 만들 것입니다."
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "You will want to consult the manual pages:"
|
|
msgstr "아래 리눅스 메뉴얼 문서들을 참조하시기 바랍니다:"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "[`opendir(3)`](https://man7.org/linux/man-pages/man3/opendir.3.html)"
|
|
msgstr "[`opendir(3)`](https://man7.org/linux/man-pages/man3/opendir.3.html)"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "[`readdir(3)`](https://man7.org/linux/man-pages/man3/readdir.3.html)"
|
|
msgstr "[`readdir(3)`](https://man7.org/linux/man-pages/man3/readdir.3.html)"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "[`closedir(3)`](https://man7.org/linux/man-pages/man3/closedir.3.html)"
|
|
msgstr "[`closedir(3)`](https://man7.org/linux/man-pages/man3/closedir.3.html)"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid ""
|
|
"You will also want to browse the [`std::ffi`](https://doc.rust-lang.org/std/"
|
|
"ffi/) module. There you find a number of string types which you need for the "
|
|
"exercise:"
|
|
msgstr ""
|
|
"아마 [`std::ffi`](https://doc.rust-lang.org/std/ffi/)모듈을 참조할 필요가 있"
|
|
"을 것입니다. 거기에는 이번 예제를 수행하는데 필요한 다양한 종류의 문자열 타입"
|
|
"들이 소개되어 있습니다:"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "Encoding"
|
|
msgstr "인코딩"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "Use"
|
|
msgstr "사용"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid ""
|
|
"[`str`](https://doc.rust-lang.org/std/primitive.str.html) and [`String`]"
|
|
"(https://doc.rust-lang.org/std/string/struct.String.html)"
|
|
msgstr ""
|
|
"[`str`](https://doc.rust-lang.org/std/primitive.str.html)과 [`String`]"
|
|
"(https://doc.rust-lang.org/std/string/struct.String.html)"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "UTF-8"
|
|
msgstr "UTF-8"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "Text processing in Rust"
|
|
msgstr "러스트에서의 문자열 처리"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid ""
|
|
"[`CStr`](https://doc.rust-lang.org/std/ffi/struct.CStr.html) and [`CString`]"
|
|
"(https://doc.rust-lang.org/std/ffi/struct.CString.html)"
|
|
msgstr ""
|
|
"[`CStr`](https://doc.rust-lang.org/std/ffi/struct.CStr.html)과 [`CString`]"
|
|
"(https://doc.rust-lang.org/std/ffi/struct.CString.html)"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "NUL-terminated"
|
|
msgstr "널(NUL)로 끝남"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "Communicating with C functions"
|
|
msgstr "C함수와 연동하기"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid ""
|
|
"[`OsStr`](https://doc.rust-lang.org/std/ffi/struct.OsStr.html) and "
|
|
"[`OsString`](https://doc.rust-lang.org/std/ffi/struct.OsString.html)"
|
|
msgstr ""
|
|
"[`OsStr`](https://doc.rust-lang.org/std/ffi/struct.OsStr.html)와 [`OsString`]"
|
|
"(https://doc.rust-lang.org/std/ffi/struct.OsString.html)"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "OS-specific"
|
|
msgstr "OS가 정의함"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "Communicating with the OS"
|
|
msgstr "OS와 연동하기 위한 문자열"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "You will convert between all these types:"
|
|
msgstr "이 타입들 간의 변환은 다음과 같습니다:"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid ""
|
|
"`&str` to `CString`: you need to allocate space for a trailing `\\0` "
|
|
"character,"
|
|
msgstr ""
|
|
"`&str`에서 `CString`으로의 변환: 맨 마지막의 `\\0` 문자를 저장하기 위한 공간"
|
|
"을 할당해야 합니다,"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "`CString` to `*const i8`: you need a pointer to call C functions,"
|
|
msgstr ""
|
|
"`CString`에서 `*const i8`로의 변환: C함수를 호출하기 위해서는 포인터가 필요합"
|
|
"니다,"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid ""
|
|
"`*const i8` to `&CStr`: you need something which can find the trailing `\\0` "
|
|
"character,"
|
|
msgstr ""
|
|
"`*const i8`에서 `&CStr`로의 변환: 주어진 바이트 시퀀스가 `\\0`로 끝나는지 확"
|
|
"인하고 싶은 경우,"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`&CStr` to `&[u8]`: a slice of bytes is the universal interface for \"some "
|
|
"unknown data\","
|
|
msgstr ""
|
|
"`&CStr`에서 `&[u8]`로의 변환: 바이트 슬라이스는 \"알수없는 데이터\"에 대한 일"
|
|
"반적인 인터페이스입니다,"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid ""
|
|
"`&[u8]` to `&OsStr`: `&OsStr` is a step towards `OsString`, use [`OsStrExt`]"
|
|
"(https://doc.rust-lang.org/std/os/unix/ffi/trait.OsStrExt.html) to create it,"
|
|
msgstr ""
|
|
"`&[u8]`에서 `&OsStr`로의 변환: `&OsStr`는 `OsString`으로 가기 위한 중간 단계 "
|
|
"입니다. [`OsStrExt`](https://doc.rust-lang.org/std/os/unix/ffi/trait."
|
|
"OsStrExt.html)를 사용해서 `OsStr`를 생성하세요,"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid ""
|
|
"`&OsStr` to `OsString`: you need to clone the data in `&OsStr` to be able to "
|
|
"return it and call `readdir` again."
|
|
msgstr ""
|
|
"`&OsStr`에서 `OsString`으로의 변환: `&OsStr`이 가리키고 있는 데이터를 복사함"
|
|
"으로써, 이 데이터를 리턴하고, `readdir`함수를 호출할 때 사용할 수 있게 해 줍"
|
|
"니다."
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid ""
|
|
"The [Nomicon](https://doc.rust-lang.org/nomicon/ffi.html) also has a very "
|
|
"useful chapter about FFI."
|
|
msgstr ""
|
|
"[Nomicon](https://doc.rust-lang.org/nomicon/ffi.html)에 FFI와 관련한 아주 유"
|
|
"용한 챕터가 있습니다."
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid ""
|
|
"Copy the code below to <https://play.rust-lang.org/> and fill in the missing "
|
|
"functions and methods:"
|
|
msgstr ""
|
|
"아래 코드를 <https://play.rust-lang.org/>에 복사하고 빠진 함수와 메서드를 채"
|
|
"워봅니다:"
|
|
|
|
#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md
|
|
msgid "\"macos\""
|
|
msgstr "\"매크로\""
|
|
|
|
#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md
|
|
msgid "// Opaque type. See https://doc.rust-lang.org/nomicon/ffi.html.\n"
|
|
msgstr ""
|
|
"// 불투명 타입입니다. https://doc.rust-lang.org/nomicon/ffi.html을 참고하세"
|
|
"요.\n"
|
|
|
|
#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md
|
|
msgid ""
|
|
"// Layout according to the Linux man page for readdir(3), where ino_t and\n"
|
|
" // off_t are resolved according to the definitions in\n"
|
|
" // /usr/include/x86_64-linux-gnu/{sys/types.h, bits/typesizes.h}.\n"
|
|
msgstr ""
|
|
"// readdir(3)의 Linux man 페이지에 따른 레이아웃입니다.\n"
|
|
" // 여기서 ino_t 및 off_t는\n"
|
|
" // /usr/include/x86_64-linux-gnu/{sys/types.h, bits/typesizes.h}의 정의"
|
|
"에 따라 확인됩니다.\n"
|
|
|
|
#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md
|
|
msgid "// Layout according to the macOS man page for dir(5).\n"
|
|
msgstr "// dir(5)의 macOS man 페이지에 따른 레이아웃입니다.\n"
|
|
|
|
#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md
|
|
msgid "\"x86_64\""
|
|
msgstr "\"x86_64\""
|
|
|
|
#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md
|
|
msgid ""
|
|
"// See https://github.com/rust-lang/libc/issues/414 and the section on\n"
|
|
" // _DARWIN_FEATURE_64_BIT_INODE in the macOS man page for stat(2).\n"
|
|
" //\n"
|
|
" // \"Platforms that existed before these updates were available\" "
|
|
"refers\n"
|
|
" // to macOS (as opposed to iOS / wearOS / etc.) on Intel and "
|
|
"PowerPC.\n"
|
|
msgstr ""
|
|
"// https://github.com/rust-lang/libc/issues/414 및\n"
|
|
" // stat(2)에 관한 macOS man 페이지의 _DARWIN_FEATURE_64_BIT_INODE 섹션을 참"
|
|
"고하세요.\n"
|
|
" //\n"
|
|
" // ' 이 업데이트가 제공되기 전에 존재했던 플랫폼은'\n"
|
|
" // Intel 및 PowerPC의 macOS (iOS/wearOS 등이 아님)를 의미합니다.\n"
|
|
|
|
#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md
|
|
msgid "\"readdir$INODE64\""
|
|
msgstr "\"readdir$INODE64\""
|
|
|
|
#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md
|
|
msgid ""
|
|
"// Call opendir and return a Ok value if that worked,\n"
|
|
" // otherwise return Err with a message.\n"
|
|
msgstr ""
|
|
"// opendir을 호출하고 제대로 작동하면 Ok 값을 반환하고\n"
|
|
" // 그렇지 않으면 메시지와 함께 Err을 반환합니다.\n"
|
|
|
|
#: src/unsafe-rust/exercise.md
|
|
msgid "// Keep calling readdir until we get a NULL pointer back.\n"
|
|
msgstr "// NULL 포인터를 다시 가져올 때까지 readdir을 계속 호출합니다.\n"
|
|
|
|
#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md
|
|
msgid "// Call closedir as needed.\n"
|
|
msgstr "// 필요에 따라 closedir을 호출합니다.\n"
|
|
|
|
#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "\".\""
|
|
msgstr "\".\""
|
|
|
|
#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md
|
|
msgid "\"files: {:#?}\""
|
|
msgstr "\"파일: {:#?}\""
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "\"Invalid path: {err}\""
|
|
msgstr "\"잘못된 경로: {err}\""
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "// SAFETY: path.as_ptr() cannot be NULL.\n"
|
|
msgstr "// SAFETY: path.as_ptr()은 NULL일 수 없습니다.\n"
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "\"Could not open {:?}\""
|
|
msgstr "\"{:?}을(를) 열 수 없습니다.\""
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid ""
|
|
"// Keep calling readdir until we get a NULL pointer back.\n"
|
|
" // SAFETY: self.dir is never NULL.\n"
|
|
msgstr ""
|
|
"// NULL 포인터를 다시 얻을 때까지 readdir을 계속 호출합니다.\n"
|
|
" // SAFETY: self.dir은 NULL이 아닙니다.\n"
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "// We have reached the end of the directory.\n"
|
|
msgstr "// 디렉터리의 끝에 도달했습니다.\n"
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid ""
|
|
"// SAFETY: dirent is not NULL and dirent.d_name is NUL\n"
|
|
" // terminated.\n"
|
|
msgstr ""
|
|
"// SAFETY: dirent는 NULL이 아니며 dirent.d_name은 NUL\n"
|
|
" // 종료됩니다.\n"
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "// SAFETY: self.dir is not NULL.\n"
|
|
msgstr "// SAFETY: self.dir은 NULL이 아닙니다.\n"
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "\"Could not close {:?}\""
|
|
msgstr "\"{:?}을(를) 닫을 수 없습니다.\""
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "\"no-such-directory\""
|
|
msgstr "\"no-such-directory\""
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "\"Non UTF-8 character in path\""
|
|
msgstr "\"경로에 UTF-8이 아닌 문자가 있음\""
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "\"..\""
|
|
msgstr "\"..\""
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "\"foo.txt\""
|
|
msgstr "\"foo.txt\""
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "\"The Foo Diaries\\n\""
|
|
msgstr "\"Foo 다이어리\\n\""
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "\"bar.png\""
|
|
msgstr "\"bar.png\""
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "\"<PNG>\\n\""
|
|
msgstr "\"<PNG>\\n\""
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
#, fuzzy
|
|
msgid "\"crab.rs\""
|
|
msgstr "\"crab.rs\""
|
|
|
|
#: src/unsafe-rust/solution.md
|
|
msgid "\"//! Crab\\n\""
|
|
msgstr "\"//! Crab\\n\""
|
|
|
|
#: src/android.md
|
|
#, fuzzy
|
|
msgid "Welcome to Rust in Android"
|
|
msgstr "1일차 개요"
|
|
|
|
#: src/android.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Rust is supported for system software on Android. This means that you can "
|
|
"write new services, libraries, drivers or even firmware in Rust (or improve "
|
|
"existing code as needed)."
|
|
msgstr ""
|
|
"러스트는 안드로이드 네이티브 플랫폼 개발을 지원합니다. 기존의 OS 서비스를 확"
|
|
"장하거나, 새로운 서비스를 만드는데 러스트를 쓸 수 있습니다."
|
|
|
|
#: src/android.md
|
|
msgid ""
|
|
"We will attempt to call Rust from one of your own projects today. So try to "
|
|
"find a little corner of your code base where we can move some lines of code "
|
|
"to Rust. The fewer dependencies and \"exotic\" types the better. Something "
|
|
"that parses some raw bytes would be ideal."
|
|
msgstr ""
|
|
"우리는 오늘 여러분의 프로젝트에서 러스트 코드를 호출해볼 것입니다. 그 프로젝"
|
|
"트에서 러스트로 옮길만 한 작은 부분을 정하세요. 의존성이 적고 \"특이한\" 타입"
|
|
"이 적을 수록 좋습니다. 바이트 몇 개를 파싱하는 코드라면 완벽합니다."
|
|
|
|
#: src/android.md
|
|
msgid ""
|
|
"The speaker may mention any of the following given the increased use of Rust "
|
|
"in Android:"
|
|
msgstr ""
|
|
"Android에서 Rust 사용이 늘어난 점을 감안할 때 발표자는 다음 내용을 언급할 수 "
|
|
"있습니다."
|
|
|
|
#: src/android.md
|
|
msgid ""
|
|
"Service example: [DNS over HTTP](https://security.googleblog.com/2022/07/dns-"
|
|
"over-http3-in-android.html)"
|
|
msgstr ""
|
|
"서비스 예: [DNS over HTTP](https://security.googleblog.com/2022/07/dns-over-"
|
|
"http3-in-android.html)"
|
|
|
|
#: src/android.md
|
|
msgid ""
|
|
"Libraries: [Rutabaga Virtual Graphics Interface](https://crosvm.dev/book/"
|
|
"appendix/rutabaga_gfx.html)"
|
|
msgstr ""
|
|
"라이브러리: [Rutabaga 가상 그래픽 인터페이스](https://crosvm.dev/book/"
|
|
"appendix/rutabaga_gfx.html)"
|
|
|
|
#: src/android.md
|
|
msgid ""
|
|
"Kernel Drivers: [Binder](https://lore.kernel.org/rust-for-linux/20231101-"
|
|
"rust-binder-v1-0-08ba9197f637@google.com/)"
|
|
msgstr ""
|
|
"커널 드라이버: [바인더](https://lore.kernel.org/rust-for-linux/20231101-rust-"
|
|
"binder-v1-0-08ba9197f637@google.com/)"
|
|
|
|
#: src/android.md
|
|
msgid ""
|
|
"Firmware: [pKVM firmware](https://security.googleblog.com/2023/10/bare-metal-"
|
|
"rust-in-android.html)"
|
|
msgstr ""
|
|
"펌웨어: [pKVM 펌웨어](https://security.googleblog.com/2023/10/bare-metal-"
|
|
"rust-in-android.html)"
|
|
|
|
#: src/android/setup.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"We will be using a Cuttlefish Android Virtual Device to test our code. Make "
|
|
"sure you have access to one or create a new one with:"
|
|
msgstr ""
|
|
"안드로이드 가상 디바이스(Android Virtual Device)를 사용하여 여러분의 코드를 "
|
|
"수행할 겁니다. 새로운 가상 디바이스를 생성하려면 아래의 명령어를 사용하세요:"
|
|
|
|
#: src/android/setup.md
|
|
msgid ""
|
|
"Please see the [Android Developer Codelab](https://source.android.com/docs/"
|
|
"setup/start) for details."
|
|
msgstr ""
|
|
"자세한 내용은 [Android Developer Codelab](https://source.android.com/docs/"
|
|
"setup/start)을 참조하십시오."
|
|
|
|
#: src/android/setup.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Cuttlefish is a reference Android device designed to work on generic Linux "
|
|
"desktops. MacOS support is also planned."
|
|
msgstr ""
|
|
"Cuttlefish는 일반적인 Linux 데스크톱에서 작동하도록 설계된 참조 Android 기기"
|
|
"입니다. MacOS 지원도 계획되어 있습니다."
|
|
|
|
#: src/android/setup.md
|
|
msgid ""
|
|
"The Cuttlefish system image maintains high fidelity to real devices, and is "
|
|
"the ideal emulator to run many Rust use cases."
|
|
msgstr ""
|
|
"Cuttlefish는 실제 하드웨어를 매우 충실히 재현하고 있으며, Rust 를 사용해 보기"
|
|
"에이상적인 에뮬레이터입니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "The Android build system (Soong) supports Rust via a number of modules:"
|
|
msgstr ""
|
|
"안드로이드 빌드 시스템(Soong)은 다음과 같은 여러 모듈을 통해 러스트를 지원합"
|
|
"니다:"
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "Module Type"
|
|
msgstr "Module Type"
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "Description"
|
|
msgstr "Description"
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "`rust_binary`"
|
|
msgstr "`rust_binary`"
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "Produces a Rust binary."
|
|
msgstr "러스트 바이너리를 생성합니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "`rust_library`"
|
|
msgstr "`rust_library`"
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "Produces a Rust library, and provides both `rlib` and `dylib` variants."
|
|
msgstr "러스트 라이브러리(rlib혹은 dylib)를 생성합니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "`rust_ffi`"
|
|
msgstr "`rust_ffi`"
|
|
|
|
#: src/android/build-rules.md
|
|
msgid ""
|
|
"Produces a Rust C library usable by `cc` modules, and provides both static "
|
|
"and shared variants."
|
|
msgstr "cc 모듈에서 사용할 수 있는 C library (정적 혹은 동적)를 생성합니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "`rust_proc_macro`"
|
|
msgstr "`rust_proc_macro`"
|
|
|
|
#: src/android/build-rules.md
|
|
msgid ""
|
|
"Produces a `proc-macro` Rust library. These are analogous to compiler "
|
|
"plugins."
|
|
msgstr ""
|
|
"`proc-macro`를 구현하는 러스트 라이브러리를 생성합니다. 컴파일러의 플러그인으"
|
|
"로 생각해도 좋습니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "`rust_test`"
|
|
msgstr "`rust_test`"
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "Produces a Rust test binary that uses the standard Rust test harness."
|
|
msgstr "표준 러스트 테스트 러너를 사용하는 테스트 바이너리를 생성합니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "`rust_fuzz`"
|
|
msgstr "`rust_fuzz`"
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "Produces a Rust fuzz binary leveraging `libfuzzer`."
|
|
msgstr "`libfuzzer`를 사용하여 fuzz 바이너리를 생성합니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "`rust_protobuf`"
|
|
msgstr "`rust_protobuf`"
|
|
|
|
#: src/android/build-rules.md
|
|
msgid ""
|
|
"Generates source and produces a Rust library that provides an interface for "
|
|
"a particular protobuf."
|
|
msgstr ""
|
|
"프로토버프(protobuf) 인터페이스를 제공하는 러스트 라이브러리를 생성합니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "`rust_bindgen`"
|
|
msgstr "`rust_bindgen`"
|
|
|
|
#: src/android/build-rules.md
|
|
msgid ""
|
|
"Generates source and produces a Rust library containing Rust bindings to C "
|
|
"libraries."
|
|
msgstr ""
|
|
"C 라이브러리에 대한 러스트 바인딩을 제공하는 러스트 라이브러리를 생성합니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "We will look at `rust_binary` and `rust_library` next."
|
|
msgstr "다음은 `rust_binary`와 `rust_library`를 살펴봅니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "Additional items speaker may mention:"
|
|
msgstr "발표자가 언급할 수 있는 추가 항목:"
|
|
|
|
#: src/android/build-rules.md
|
|
msgid ""
|
|
"Cargo is not optimized for multi-language repos, and also downloads packages "
|
|
"from the internet."
|
|
msgstr ""
|
|
"Cargo는 다국어 저장소에 최적화되지 않았으며 인터넷에서 패키지를 다운로드합니"
|
|
"다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid ""
|
|
"For compliance and performance, Android must have crates in-tree. It must "
|
|
"also interop with C/C++/Java code. Soong fills that gap."
|
|
msgstr ""
|
|
"Android에서는 규정상, 그리고 빌드 속도를 위해, 크레이트들이 Android 소스코드 "
|
|
"트리 안에 미리 포함되어 있어야 합니다. 빌드 시 다운로드 받을 수 없습니다. 또"
|
|
"한 C/C++/Java 코드와 상호 운용되어야 합니다. Android 빌드 시스템인 Soong이 "
|
|
"이 공백을 메웁니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid ""
|
|
"Soong has many similarities to Bazel, which is the open-source variant of "
|
|
"Blaze (used in google3)."
|
|
msgstr ""
|
|
"Soong은 Blaze(google3에서 사용됨)의 오픈소스 변형인 Bazel과 많이 비슷합니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid ""
|
|
"There is a plan to transition [Android](https://source.android.com/docs/"
|
|
"setup/build/bazel/introduction), [ChromeOS](https://chromium.googlesource."
|
|
"com/chromiumos/bazel/), and [Fuchsia](https://source.android.com/docs/setup/"
|
|
"build/bazel/introduction) to Bazel."
|
|
msgstr ""
|
|
"[Android](https://source.android.com/docs/setup/build/bazel/introduction), "
|
|
"[ChromeOS](https://chromium.googlesource.com/chromiumos/bazel/), [Fuchsia]"
|
|
"(https://source.android.com/docs/setup/build/bazel/introduction)를 Bazel로 전"
|
|
"환할 계획입니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "Learning Bazel-like build rules is useful for all Rust OS developers."
|
|
msgstr ""
|
|
"Bazel과 유사한 빌드 규칙을 배우는 것은 모든 Rust OS 개발자에게 유용합니다."
|
|
|
|
#: src/android/build-rules.md
|
|
msgid "Fun fact: Data from Star Trek is a Soong-type Android."
|
|
msgstr ""
|
|
"재미있는 사실: 스타트렉의 캐릭터 중 한명인 데이터(Data)는 사실 Soong 타입의 "
|
|
"안드로이드(Android)입니다."
|
|
|
|
#: src/android/build-rules/binary.md
|
|
msgid "Rust Binaries"
|
|
msgstr "러스트 바이너리"
|
|
|
|
#: src/android/build-rules/binary.md
|
|
msgid ""
|
|
"Let us start with a simple application. At the root of an AOSP checkout, "
|
|
"create the following files:"
|
|
msgstr ""
|
|
"간단한 응용 프로그램으로 시작해 보겠습니다. AOSP 체크아웃의 루트에서 다음 파"
|
|
"일을 생성합니다:"
|
|
|
|
#: src/android/build-rules/binary.md src/android/build-rules/library.md
|
|
msgid "_hello_rust/Android.bp_:"
|
|
msgstr "_hello_rust/Android.bp_:"
|
|
|
|
#: src/android/build-rules/binary.md
|
|
msgid "\"hello_rust\""
|
|
msgstr "\"hello_rust\""
|
|
|
|
#: src/android/build-rules/binary.md src/android/build-rules/library.md
|
|
#: src/android/logging.md
|
|
msgid "\"src/main.rs\""
|
|
msgstr "\"src/main.rs\""
|
|
|
|
#: src/android/build-rules/binary.md src/android/build-rules/library.md
|
|
msgid "_hello_rust/src/main.rs_:"
|
|
msgstr "_hello_rust/src/main.rs_:"
|
|
|
|
#: src/android/build-rules/binary.md src/android/build-rules/library.md
|
|
msgid "//! Rust demo.\n"
|
|
msgstr "//! Rust 데모입니다.\n"
|
|
|
|
#: src/android/build-rules/binary.md src/android/build-rules/library.md
|
|
msgid "/// Prints a greeting to standard output.\n"
|
|
msgstr "/// 인사말을 표준 출력으로 인쇄합니다.\n"
|
|
|
|
#: src/android/build-rules/binary.md src/exercises/chromium/build-rules.md
|
|
#, fuzzy
|
|
msgid "\"Hello from Rust!\""
|
|
msgstr "\"Hello from Rust!\""
|
|
|
|
#: src/android/build-rules/binary.md
|
|
msgid "You can now build, push, and run the binary:"
|
|
msgstr "그런 다음, 이 바이너리를 빌드하고, 가상 디바이스에 넣고, 실행합니다:"
|
|
|
|
#: src/android/build-rules/binary.md
|
|
#, fuzzy
|
|
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"
|
|
"```"
|
|
msgstr ""
|
|
"```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"
|
|
"```"
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "Rust Libraries"
|
|
msgstr "러스트 라이브러리"
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "You use `rust_library` to create a new Rust library for Android."
|
|
msgstr ""
|
|
"`rust_library`를 사용하여 안드로이드용 새 러스트 라이브러리를 만듭니다."
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "Here we declare a dependency on two libraries:"
|
|
msgstr "여기서 두 개의 라이브러리에 대한 의존성을 선언합니다:"
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "`libgreeting`, which we define below,"
|
|
msgstr "아래에 정의한 `libgreeting`."
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid ""
|
|
"`libtextwrap`, which is a crate already vendored in [`external/rust/crates/`]"
|
|
"(https://cs.android.com/android/platform/superproject/+/master:external/rust/"
|
|
"crates/)."
|
|
msgstr ""
|
|
"[`external/rust/crates/`](https://cs.android.com/android/platform/"
|
|
"superproject/+/master:external/rust/crates/)에 존재하는 `libtextwrap`."
|
|
|
|
#: src/android/build-rules/library.md
|
|
#, fuzzy
|
|
msgid "\"hello_rust_with_dep\""
|
|
msgstr "\"hello_rust_with_dep\""
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "\"libgreetings\""
|
|
msgstr "\"libgreetings\""
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "\"libtextwrap\""
|
|
msgstr "\"libtextwrap\""
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "// Need this to avoid dynamic link error.\n"
|
|
msgstr ""
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "\"greetings\""
|
|
msgstr "\"인사말\""
|
|
|
|
#: src/android/build-rules/library.md
|
|
#: src/android/aidl/example-service/service.md src/android/testing.md
|
|
#: src/android/interoperability/java.md
|
|
#, fuzzy
|
|
msgid "\"src/lib.rs\""
|
|
msgstr "\"src/lib.rs\""
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "_hello_rust/src/lib.rs_:"
|
|
msgstr "_hello_rust/src/lib.rs_:"
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "//! Greeting library.\n"
|
|
msgstr "//! 인사말 라이브러리입니다.\n"
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "/// Greet `name`.\n"
|
|
msgstr "/// `name`에게 인사합니다.\n"
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "\"Hello {name}, it is very nice to meet you!\""
|
|
msgstr "\"{name}님, 안녕하세요. 만나서 반갑습니다.\""
|
|
|
|
#: src/android/build-rules/library.md
|
|
msgid "You build, push, and run the binary like before:"
|
|
msgstr "이전처럼, 빌드하고, 가상 디바이스로 넣고, 실행합니다:"
|
|
|
|
#: src/android/build-rules/library.md
|
|
#, fuzzy
|
|
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"
|
|
"```"
|
|
msgstr ""
|
|
"```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"
|
|
"```"
|
|
|
|
#: src/android/aidl.md
|
|
msgid ""
|
|
"The [Android Interface Definition Language (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
|
|
msgid "Rust code can call existing AIDL servers,"
|
|
msgstr "러스트 코드에서 기존 AIDL 서버를 호출 할 수 있습니다. "
|
|
|
|
#: src/android/aidl.md
|
|
msgid "You can create new AIDL servers in Rust."
|
|
msgstr "러스트에서 새로운 AIDL 서버를 생성할 수 있습니다."
|
|
|
|
#: src/android/aidl/birthday-service.md
|
|
msgid ""
|
|
"To illustrate how to use Rust with Binder, we're going to walk through the "
|
|
"process of creating a Binder interface. We're then going to both implement "
|
|
"the described service and write client code that talks to that service."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/interface.md
|
|
msgid "AIDL Interfaces"
|
|
msgstr "AIDL 인터페이스"
|
|
|
|
#: src/android/aidl/example-service/interface.md
|
|
msgid "You declare the API of your service using an AIDL interface:"
|
|
msgstr "AIDL 인터페이스를 이용해서 서비스의 API를 선언합니다:"
|
|
|
|
#: src/android/aidl/example-service/interface.md
|
|
#: src/android/aidl/example-service/service-bindings.md
|
|
msgid ""
|
|
"_birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl_:"
|
|
msgstr ""
|
|
"_birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl_:"
|
|
|
|
#: src/android/aidl/example-service/interface.md
|
|
#: src/android/aidl/example-service/service-bindings.md
|
|
#: src/android/aidl/example-service/changing-definition.md
|
|
msgid "/** Birthday service interface. */"
|
|
msgstr "/** 생일 서비스 인터페이스입니다. */"
|
|
|
|
#: src/android/aidl/example-service/interface.md
|
|
#: src/android/aidl/example-service/service-bindings.md
|
|
#: src/android/aidl/example-service/changing-definition.md
|
|
msgid "/** Generate a Happy Birthday message. */"
|
|
msgstr "/** 생일 축하 메시지를 생성합니다. */"
|
|
|
|
#: src/android/aidl/example-service/interface.md
|
|
#, fuzzy
|
|
msgid "_birthday_service/aidl/Android.bp_:"
|
|
msgstr "_interoperability/bindgen/Android.bp_:"
|
|
|
|
#: src/android/aidl/example-service/interface.md
|
|
#, fuzzy
|
|
msgid "\"com.example.birthdayservice\""
|
|
msgstr "\"com.example.birthdayservice\""
|
|
|
|
#: src/android/aidl/example-service/interface.md
|
|
#, fuzzy
|
|
msgid "\"com/example/birthdayservice/*.aidl\""
|
|
msgstr "\"com.example.birthdayservice\""
|
|
|
|
#: src/android/aidl/example-service/interface.md
|
|
msgid "// Rust is not enabled by default\n"
|
|
msgstr "// Rust는 기본적으로 사용 설정되지 않습니다.\n"
|
|
|
|
#: src/android/aidl/example-service/interface.md
|
|
msgid ""
|
|
"Note that the directory structure under the `aidl/` directory needs to match "
|
|
"the package name used in the AIDL file, i.e. the package is `com.example."
|
|
"birthdayservice` and the file is at `aidl/com/example/IBirthdayService.aidl`."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/service-bindings.md
|
|
msgid "Generated Service API"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/service-bindings.md
|
|
msgid ""
|
|
"Binder generates a trait corresponding to the interface definition. trait to "
|
|
"talk to the service."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/service-bindings.md
|
|
#, fuzzy
|
|
msgid "_Generated trait_:"
|
|
msgstr "생성된 러스트:"
|
|
|
|
#: src/android/aidl/example-service/service-bindings.md
|
|
msgid ""
|
|
"Your service will need to implement this trait, and your client will use "
|
|
"this trait to talk to the service."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/service-bindings.md
|
|
msgid ""
|
|
"The generated bindings can be found at `out/soong/.intermediates/<path to "
|
|
"module>/`."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/service-bindings.md
|
|
msgid ""
|
|
"Point out how the generated function signature, specifically the argument "
|
|
"and return types, correspond the interface definition."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/service-bindings.md
|
|
msgid ""
|
|
"`String` for an argument results in a different Rust type than `String` as a "
|
|
"return type."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/service.md
|
|
msgid "Service Implementation"
|
|
msgstr "서비스 구현"
|
|
|
|
#: src/android/aidl/example-service/service.md
|
|
msgid "We can now implement the AIDL service:"
|
|
msgstr "이제 AIDL서비스를 구현할 수 있습니다:"
|
|
|
|
#: src/android/aidl/example-service/service.md
|
|
#: src/android/aidl/example-service/changing-implementation.md
|
|
msgid "_birthday_service/src/lib.rs_:"
|
|
msgstr "_birthday_service/src/lib.rs_:"
|
|
|
|
#: src/android/aidl/example-service/service.md
|
|
#, fuzzy
|
|
msgid "/// The `IBirthdayService` implementation.\n"
|
|
msgstr "/// HelloWorld::hello 메서드 구현입니다.\n"
|
|
|
|
#: src/android/aidl/example-service/service.md
|
|
#: src/android/aidl/example-service/changing-implementation.md
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
msgid "\"Happy Birthday {name}, congratulations with the {years} years!\""
|
|
msgstr "\"{name}님의 생일을 축하합니다. {years}주년을 축하합니다.\""
|
|
|
|
#: src/android/aidl/example-service/service.md
|
|
#: src/android/aidl/example-service/server.md
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid "_birthday_service/Android.bp_:"
|
|
msgstr "_birthday_service/Android.bp_:"
|
|
|
|
#: src/android/aidl/example-service/service.md
|
|
#: src/android/aidl/example-service/server.md
|
|
#, fuzzy
|
|
msgid "\"libbirthdayservice\""
|
|
msgstr "\"libbirthday.c\""
|
|
|
|
#: src/android/aidl/example-service/service.md
|
|
#: src/android/aidl/example-service/server.md
|
|
#: src/android/aidl/example-service/client.md
|
|
#, fuzzy
|
|
msgid "\"birthdayservice\""
|
|
msgstr "\"com.example.birthdayservice\""
|
|
|
|
#: src/android/aidl/example-service/service.md
|
|
#: src/android/aidl/example-service/server.md
|
|
#: src/android/aidl/example-service/client.md
|
|
#, fuzzy
|
|
msgid "\"com.example.birthdayservice-rust\""
|
|
msgstr "\"com.example.birthdayservice-rust\""
|
|
|
|
#: src/android/aidl/example-service/service.md
|
|
#: src/android/aidl/example-service/server.md
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid "\"libbinder_rs\""
|
|
msgstr "\"libbinder_rs\""
|
|
|
|
#: src/android/aidl/example-service/service.md
|
|
msgid ""
|
|
"Point out the path to the generated `IBirthdayService` trait, and explain "
|
|
"why each of the segments is necessary."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/service.md
|
|
msgid ""
|
|
"TODO: What does the `binder::Interface` trait do? Are there methods to "
|
|
"override? Where source?"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
msgid "AIDL Server"
|
|
msgstr "AIDL 서버"
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
msgid "Finally, we can create a server which exposes the service:"
|
|
msgstr "마지막으로 서비스를 제공하는 서버를 만들 수 있습니다:"
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
msgid "_birthday_service/src/server.rs_:"
|
|
msgstr "_birthday_service/src/server.rs_:"
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
#, fuzzy
|
|
msgid "//! Birthday service.\n"
|
|
msgstr "//! 생일 서비스입니다.\n"
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
msgid "/// Entry point for birthday service.\n"
|
|
msgstr "/// 생일 서비스의 진입점입니다.\n"
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
msgid "\"Failed to register service\""
|
|
msgstr "\"서비스 등록 실패\""
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
#, fuzzy
|
|
msgid "\"birthday_server\""
|
|
msgstr "\"libbirthday_wrapper.h\""
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
#, fuzzy
|
|
msgid "\"src/server.rs\""
|
|
msgstr "서버."
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid "// To avoid dynamic link error.\n"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
msgid ""
|
|
"The process for taking a user-defined service implementation (in this case "
|
|
"the `BirthdayService` type, which implements the `IBirthdayService`) and "
|
|
"starting it as a Binder service has multiple steps, and may appear more "
|
|
"complicated than students are used to if they've used Binder from C++ or "
|
|
"another language. Explain to students why each step is necessary."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
msgid "Create an instance of your service type (`BirthdayService`)."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
msgid ""
|
|
"Wrap the service object in corresponding `Bn*` type (`BnBirthdayService` in "
|
|
"this case). This type is generated by Binder and provides the common Binder "
|
|
"functionality that would be provided by the `BnBinder` base class in C++. We "
|
|
"don't have inheritance in Rust, so instead we use composition, putting our "
|
|
"`BirthdayService` within the generated `BnBinderService`."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
msgid ""
|
|
"Call `add_service`, giving it a service identifier and your service object "
|
|
"(the `BnBirthdayService` object in the example)."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/server.md
|
|
msgid ""
|
|
"Call `join_thread_pool` to add the current thread to Binder's thread pool "
|
|
"and start listening for connections."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/deploy.md
|
|
msgid "We can now build, push, and start the service:"
|
|
msgstr "서비스를 빌드하고, 가상 디바이스에 넣고, 시작 할 수 있습니다:"
|
|
|
|
#: src/android/aidl/example-service/deploy.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"```shell\n"
|
|
"m birthday_server\n"
|
|
"adb push \"$ANDROID_PRODUCT_OUT/system/bin/birthday_server\" /data/local/"
|
|
"tmp\n"
|
|
"adb root\n"
|
|
"adb shell /data/local/tmp/birthday_server\n"
|
|
"```"
|
|
msgstr ""
|
|
"```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"
|
|
"```"
|
|
|
|
#: src/android/aidl/example-service/deploy.md
|
|
msgid "In another terminal, check that the service runs:"
|
|
msgstr "다른 터미널을 띄워서 서비스가 잘 수행되고 있는지 확인합니다:"
|
|
|
|
#: src/android/aidl/example-service/deploy.md
|
|
msgid "You can also call the service with `service call`:"
|
|
msgstr "`service call`명렁어로 서비스를 호출할 수도 있습니다:"
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid "AIDL Client"
|
|
msgstr "AIDL 클라이언트"
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid "Finally, we can create a Rust client for our new service."
|
|
msgstr ""
|
|
"마지막으로, 아까 추가한 서비스에 대한 클라이언트를 러스트로 만들겠습니다."
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
#: src/android/aidl/example-service/changing-implementation.md
|
|
msgid "_birthday_service/src/client.rs_:"
|
|
msgstr "_birthday_service/src/client.rs_:"
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid "/// Call the birthday service.\n"
|
|
msgstr "/// 생일 서비스를 호출합니다.\n"
|
|
|
|
#: src/android/aidl/example-service/client.md src/android/aidl/types/objects.md
|
|
#: src/android/aidl/types/parcelables.md
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
msgid "\"Failed to connect to BirthdayService\""
|
|
msgstr "\"BirthdayService에 연결할 수 없습니다.\""
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
#, fuzzy
|
|
msgid "// Call the service.\n"
|
|
msgstr "/// 생일 서비스를 호출합니다.\n"
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid "\"{msg}\""
|
|
msgstr "\"{msg}\""
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid "\"birthday_client\""
|
|
msgstr "\"birthday_client\""
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid "\"src/client.rs\""
|
|
msgstr "\"src/client.rs\""
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid "Notice that the client does not depend on `libbirthdayservice`."
|
|
msgstr "클라이언트는 `libbirthdayservice`에 의존하지 않음에 주목하세요."
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid "Build, push, and run the client on your device:"
|
|
msgstr "빌드하고, 가상 디바이스로 넣고, 실행합니다:"
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
#, fuzzy
|
|
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"
|
|
"```"
|
|
msgstr ""
|
|
"```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"
|
|
"```"
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid ""
|
|
"`Strong<dyn IBirthdayService>` is the trait object representing the service "
|
|
"that the client has connected to."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid ""
|
|
"`Strong` is a custom smart pointer type for Binder. It handles both an in-"
|
|
"process ref count for the service trait object, and the global Binder ref "
|
|
"count that tracks how many processes have a reference to the object."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid ""
|
|
"Note that the trait object that the client uses to talk to the service uses "
|
|
"the exact same trait that the server implements. For a given Binder "
|
|
"interface, there is a single Rust trait generated that both client and "
|
|
"server use."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/client.md
|
|
msgid ""
|
|
"Use the same service identifier used when registering the service. This "
|
|
"should ideally be defined in a common crate that both the client and server "
|
|
"can depend on."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/changing-definition.md
|
|
msgid ""
|
|
"Let us extend the API with more functionality: we want to let clients "
|
|
"specify a list of lines for the birthday card:"
|
|
msgstr ""
|
|
"API를 확장하여 더 많은 기능을 제공해 봅시다. 클라이언트가 생일 카드에 담길 내"
|
|
"용을 지정할 수 있도록 하겠습니다:"
|
|
|
|
#: src/android/aidl/example-service/changing-definition.md
|
|
msgid "This results in an updated trait definition for `IBirthdayService`:"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/changing-definition.md
|
|
msgid ""
|
|
"Note how the `String[]` in the AIDL definition is translated as a "
|
|
"`&[String]` in Rust, i.e. that idiomatic Rust types are used in the "
|
|
"generated bindings wherever possible:"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/changing-definition.md
|
|
msgid "`in` array arguments are translated to slices."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/changing-definition.md
|
|
msgid "`out` and `inout` args are translated to `&mut Vec<T>`."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/changing-definition.md
|
|
msgid "Return values are translated to returning a `Vec<T>`."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/changing-implementation.md
|
|
msgid "Updating Client and Service"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/changing-implementation.md
|
|
msgid "Update the client and server code to account for the new API."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/changing-implementation.md
|
|
msgid "'\\n'"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/changing-implementation.md
|
|
msgid "\"Habby birfday to yuuuuu\""
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/changing-implementation.md
|
|
msgid "\"And also: many more\""
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/example-service/changing-implementation.md
|
|
msgid ""
|
|
"TODO: Move code snippets into project files where they'll actually be built?"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types.md
|
|
msgid "Working With AIDL Types"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types.md
|
|
msgid "AIDL types translate into the appropriate idiomatic Rust type:"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types.md
|
|
msgid "Primitive types map (mostly) to idiomatic Rust types."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types.md
|
|
msgid "Collection types like slices, `Vec`s and string types are supported."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types.md
|
|
msgid ""
|
|
"References to AIDL objects and file handles can be sent between clients and "
|
|
"services."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types.md
|
|
msgid "File handles and parcelables are fully supported."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "Primitive types map (mostly) idiomatically:"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
#, fuzzy
|
|
msgid "AIDL Type"
|
|
msgstr "AIDL"
|
|
|
|
#: src/android/aidl/types/primitives.md src/android/aidl/types/arrays.md
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "Rust Type"
|
|
msgstr "Rust by Example"
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "Note"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
#, fuzzy
|
|
msgid "`boolean`"
|
|
msgstr "`bool`"
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "`byte`"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "`i8`"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
#, fuzzy
|
|
msgid "Note that bytes are signed."
|
|
msgstr "// 7바이트를 초과하면 유효하지 않습니다.\n"
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "`u16`"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "Note the usage of `u16`, NOT `u32`."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "`int`"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "`i32`"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "`long`"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "`i64`"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "`float`"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "`f32`"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "`double`"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/primitives.md
|
|
msgid "`f64`"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/arrays.md
|
|
msgid ""
|
|
"The array types (`T[]`, `byte[]`, and `List<T>`) get translated to the "
|
|
"appropriate Rust array type depending on how they are used in the function "
|
|
"signature:"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/arrays.md
|
|
#, fuzzy
|
|
msgid "Position"
|
|
msgstr "Description"
|
|
|
|
#: src/android/aidl/types/arrays.md
|
|
msgid "`in` argument"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/arrays.md
|
|
#, fuzzy
|
|
msgid "`&[T]`"
|
|
msgstr "슬라이스"
|
|
|
|
#: src/android/aidl/types/arrays.md
|
|
msgid "`out`/`inout` argument"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/arrays.md
|
|
#, fuzzy
|
|
msgid "`&mut Vec<T>`"
|
|
msgstr "`Vec`"
|
|
|
|
#: src/android/aidl/types/arrays.md
|
|
msgid "Return"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/arrays.md
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`Vec<T>`"
|
|
msgstr "`Vec`"
|
|
|
|
#: src/android/aidl/types/arrays.md
|
|
msgid ""
|
|
"In Android 13 or higher, fixed-size arrays are supported, i.e. `T[N]` "
|
|
"becomes `[T; N]`. Fixed-size arrays can have multiple dimensions (e.g. "
|
|
"int\\[3\\]\\[4\\]). In the Java backend, fixed-size arrays are represented "
|
|
"as array types."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/arrays.md
|
|
msgid "Arrays in parcelable fields always get translated to `Vec<T>`."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/objects.md
|
|
msgid ""
|
|
"AIDL objects can be sent either as a concrete AIDL type or as the type-"
|
|
"erased `IBinder` interface:"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/objects.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"**birthday_service/aidl/com/example/birthdayservice/IBirthdayInfoProvider."
|
|
"aidl**:"
|
|
msgstr ""
|
|
"_birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl_:"
|
|
|
|
#: src/android/aidl/types/objects.md src/android/aidl/types/parcelables.md
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"**birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl**:"
|
|
msgstr ""
|
|
"_birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl_:"
|
|
|
|
#: src/android/aidl/types/objects.md
|
|
msgid "/** The same thing, but using a binder object. */"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/objects.md
|
|
msgid "/** The same thing, but using `IBinder`. */"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/objects.md src/android/aidl/types/parcelables.md
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
#, fuzzy
|
|
msgid "**birthday_service/src/client.rs**:"
|
|
msgstr "_birthday_service/src/client.rs_:"
|
|
|
|
#: src/android/aidl/types/objects.md
|
|
#, fuzzy
|
|
msgid "/// Rust struct implementing the `IBirthdayInfoProvider` interface.\n"
|
|
msgstr "//! `IBirthdayService` AIDL 인터페이스의 구현입니다.\n"
|
|
|
|
#: src/android/aidl/types/objects.md
|
|
#, fuzzy
|
|
msgid "// Create a binder object for the `IBirthdayInfoProvider` interface.\n"
|
|
msgstr "//! `IBirthdayService` AIDL 인터페이스의 구현입니다.\n"
|
|
|
|
#: src/android/aidl/types/objects.md
|
|
#, fuzzy
|
|
msgid "// Send the binder object to the service.\n"
|
|
msgstr "/// 생일 서비스를 호출합니다.\n"
|
|
|
|
#: src/android/aidl/types/objects.md
|
|
msgid ""
|
|
"// Perform the same operation but passing the provider as an `SpIBinder`.\n"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/objects.md
|
|
msgid ""
|
|
"Note the usage of `BnBirthdayInfoProvider`. This serves the same purpose as "
|
|
"`BnBirthdayService` that we saw previously."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/parcelables.md
|
|
msgid "Binder for Rust supports sending parcelables directly:"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/parcelables.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"**birthday_service/aidl/com/example/birthdayservice/BirthdayInfo.aidl**:"
|
|
msgstr ""
|
|
"_birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl_:"
|
|
|
|
#: src/android/aidl/types/parcelables.md
|
|
msgid "/** The same thing, but with a parcelable. */"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
msgid ""
|
|
"Files can be sent between Binder clients/servers using the "
|
|
"`ParcelFileDescriptor` type:"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
msgid "/** The same thing, but loads info from a file. */"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
msgid "// Open a file and put the birthday info in it.\n"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
msgid "\"/data/local/tmp/birthday.info\""
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
#, fuzzy
|
|
msgid "\"{name}\""
|
|
msgstr "\"안녕하세요 {name}\""
|
|
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
msgid "\"{years}\""
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
msgid "// Create a `ParcelFileDescriptor` from the file and send it.\n"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
#, fuzzy
|
|
msgid "**birthday_service/src/lib.rs**:"
|
|
msgstr "_birthday_service/src/lib.rs_:"
|
|
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
msgid ""
|
|
"// Convert the file descriptor to a `File`. `ParcelFileDescriptor` wraps\n"
|
|
" // an `OwnedFd`, which can be cloned and then used to create a "
|
|
"`File`\n"
|
|
" // object.\n"
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
#, fuzzy
|
|
msgid "\"Invalid file handle\""
|
|
msgstr "\"잘못된 길이\""
|
|
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
msgid ""
|
|
"`ParcelFileDescriptor` wraps an `OwnedFd`, and so can be created from a "
|
|
"`File` (or any other type that wraps an `OwnedFd`), and can be used to "
|
|
"create a new `File` handle on the other side."
|
|
msgstr ""
|
|
|
|
#: src/android/aidl/types/file-descriptor.md
|
|
msgid ""
|
|
"Other types of file descriptors can be wrapped and sent, e.g. TCP, UDP, and "
|
|
"UNIX sockets."
|
|
msgstr ""
|
|
|
|
#: src/android/testing.md
|
|
#, fuzzy
|
|
msgid "Testing in Android"
|
|
msgstr "1일차 개요"
|
|
|
|
#: src/android/testing.md
|
|
msgid ""
|
|
"Building on [Testing](../testing.md), we will now look at how unit tests "
|
|
"work in AOSP. Use the `rust_test` module for your unit tests:"
|
|
msgstr ""
|
|
|
|
#: src/android/testing.md
|
|
#, fuzzy
|
|
msgid "_testing/Android.bp_:"
|
|
msgstr "_hello_rust/Android.bp_:"
|
|
|
|
#: src/android/testing.md
|
|
#, fuzzy
|
|
msgid "\"libleftpad\""
|
|
msgstr "\"libtextwrap\""
|
|
|
|
#: src/android/testing.md
|
|
msgid "\"leftpad\""
|
|
msgstr ""
|
|
|
|
#: src/android/testing.md
|
|
#, fuzzy
|
|
msgid "\"libleftpad_test\""
|
|
msgstr "\"libbirthday_bindgen_test\""
|
|
|
|
#: src/android/testing.md
|
|
msgid "\"leftpad_test\""
|
|
msgstr ""
|
|
|
|
#: src/android/testing.md src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
msgid "\"general-tests\""
|
|
msgstr "\"general-tests\""
|
|
|
|
#: src/android/testing.md
|
|
#, fuzzy
|
|
msgid "_testing/src/lib.rs_:"
|
|
msgstr "_hello_rust/src/lib.rs_:"
|
|
|
|
#: src/android/testing.md
|
|
#, fuzzy
|
|
msgid "//! Left-padding library.\n"
|
|
msgstr "//! 인사말 라이브러리입니다.\n"
|
|
|
|
#: src/android/testing.md
|
|
msgid "/// Left-pad `s` to `width`.\n"
|
|
msgstr ""
|
|
|
|
#: src/android/testing.md
|
|
#, fuzzy
|
|
msgid "\"{s:>width$}\""
|
|
msgstr "\"|{:^width$}|\""
|
|
|
|
#: src/android/testing.md
|
|
#, fuzzy
|
|
msgid "\" foo\""
|
|
msgstr "\"foo\""
|
|
|
|
#: src/android/testing.md
|
|
#, fuzzy
|
|
msgid "\"foobar\""
|
|
msgstr "\"foo\""
|
|
|
|
#: src/android/testing.md
|
|
#, fuzzy
|
|
msgid "You can now run the test with"
|
|
msgstr "이제 바인딩을 자동으로 생성할 수 있습니다:"
|
|
|
|
#: src/android/testing.md
|
|
#, fuzzy
|
|
msgid "The output looks like this:"
|
|
msgstr "전체적인 접근 방법은 다음과 같습니다:"
|
|
|
|
#: src/android/testing.md
|
|
msgid ""
|
|
"```text\n"
|
|
"INFO: Elapsed time: 2.666s, Critical Path: 2.40s\n"
|
|
"INFO: 3 processes: 2 internal, 1 linux-sandbox.\n"
|
|
"INFO: Build completed successfully, 3 total actions\n"
|
|
"//comprehensive-rust-android/testing:libleftpad_test_host PASSED "
|
|
"in 2.3s\n"
|
|
" PASSED libleftpad_test.tests::long_string (0.0s)\n"
|
|
" PASSED libleftpad_test.tests::short_string (0.0s)\n"
|
|
"Test cases: finished with 2 passing and 0 failing out of 2 test cases\n"
|
|
"```"
|
|
msgstr ""
|
|
|
|
#: src/android/testing.md
|
|
msgid ""
|
|
"Notice how you only mention the root of the library crate. Tests are found "
|
|
"recursively in nested modules."
|
|
msgstr ""
|
|
|
|
#: src/android/testing/googletest.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The [GoogleTest](https://docs.rs/googletest/) crate allows for flexible test "
|
|
"assertions using _matchers_:"
|
|
msgstr ""
|
|
"[googletest](https://docs.rs/googletest): C++용 GoogleTest의 방식을 따르는 테"
|
|
"스트 라이브러리 입니다."
|
|
|
|
#: src/android/testing/googletest.md
|
|
msgid "\"baz\""
|
|
msgstr "\"baz\""
|
|
|
|
#: src/android/testing/googletest.md
|
|
msgid "\"xyz\""
|
|
msgstr "\"xyz\""
|
|
|
|
#: src/android/testing/googletest.md
|
|
msgid ""
|
|
"If we change the last element to `\"!\"`, the test fails with a structured "
|
|
"error message pin-pointing the error:"
|
|
msgstr ""
|
|
"마지막 요소를 `'!'`로 변경하면 테스트가 실패하고 오류를 정확히 가리키는 구조"
|
|
"화된 오류 메시지가 표시됩니다."
|
|
|
|
#: src/android/testing/googletest.md
|
|
msgid ""
|
|
"GoogleTest is not part of the Rust Playground, so you need to run this "
|
|
"example in a local environment. Use `cargo add googletest` to quickly add it "
|
|
"to an existing Cargo project."
|
|
msgstr ""
|
|
"GoogleTest는 Rust 플레이그라운드의 일부가 아니므로 로컬 환경에서 이 예를 실행"
|
|
"해야 합니다. `cargo add googletest`를 사용하여 기존 Cargo 프로젝트에 빠르게 "
|
|
"추가하세요."
|
|
|
|
#: src/android/testing/googletest.md
|
|
msgid ""
|
|
"The `use googletest::prelude::*;` line imports a number of [commonly used "
|
|
"macros and types](https://docs.rs/googletest/latest/googletest/prelude/index."
|
|
"html)."
|
|
msgstr ""
|
|
"`use googletest::prelude::*;` 줄은 [일반적으로 사용되는 매크로 및 타입]"
|
|
"(https://docs.rs/googletest/latest/googletest/prelude/index.html)을 여러 개 "
|
|
"가져옵니다."
|
|
|
|
#: src/android/testing/googletest.md
|
|
msgid "This just scratches the surface, there are many builtin matchers."
|
|
msgstr "이는 일부일 뿐이며 내장된 매처가 많이 있습니다."
|
|
|
|
#: src/android/testing/googletest.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"A particularly nice feature is that mismatches in multi-line strings are "
|
|
"shown as a diff:"
|
|
msgstr "특히 좋은 기능은 여러 줄 문자열의 불일치가 diff로 표시된다는 것입니다."
|
|
|
|
#: src/android/testing/googletest.md
|
|
msgid ""
|
|
"\"Memory safety found,\\n\\\n"
|
|
" Rust's strong typing guides the way,\\n\\\n"
|
|
" Secure code you'll write.\""
|
|
msgstr ""
|
|
"\"Memory safete found,\\n\\\n"
|
|
" Rust's strong typing guides the way,\\n\\\n"
|
|
" Secure code you'll write.\""
|
|
|
|
#: src/android/testing/googletest.md
|
|
msgid ""
|
|
"\"Memory safety found,\\n\\\n"
|
|
" Rust's silly humor guides the way,\\n\\\n"
|
|
" Secure code you'll write.\""
|
|
msgstr ""
|
|
"\"Memory safety found,\\n\\\n"
|
|
" Rust's silly humor guides the way,\\n\\\n"
|
|
" Secure code you'll write.\""
|
|
|
|
#: src/android/testing/googletest.md
|
|
msgid "shows a color-coded diff (colors not shown here):"
|
|
msgstr ""
|
|
"색상으로 구분된 diff를 표시합니다(여기에서는 색상이 표시되지 않습니다)."
|
|
|
|
#: src/android/testing/googletest.md
|
|
msgid ""
|
|
"The crate is a Rust port of [GoogleTest for C++](https://google.github.io/"
|
|
"googletest/)."
|
|
msgstr ""
|
|
"크레이트는 [C++용 GoogleTest](https://google.github.io/googletest/)의 Rust 포"
|
|
"트입니다."
|
|
|
|
#: src/android/testing/mocking.md
|
|
msgid ""
|
|
"For mocking, [Mockall](https://docs.rs/mockall/) is a widely used library. "
|
|
"You need to refactor your code to use traits, which you can then quickly "
|
|
"mock:"
|
|
msgstr ""
|
|
"모의 처리의 경우 널리 사용되는 라이브러리인 [Mockall](https://docs.rs/"
|
|
"mockall/)이 있습니다. 트레잇을 사용하도록 코드를 리팩터링해야 합니다. 그런 다"
|
|
"음 빠르게 모의 처리할 수 있습니다."
|
|
|
|
#: src/android/testing/mocking.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Mockall is the recommended mocking library in Android (AOSP). There are "
|
|
"other [mocking libraries available on crates.io](https://crates.io/keywords/"
|
|
"mock), in particular in the area of mocking HTTP services. The other mocking "
|
|
"libraries work in a similar fashion as Mockall, meaning that they make it "
|
|
"easy to get a mock implementation of a given trait."
|
|
msgstr ""
|
|
"이 권장사항은 Mockall이 권장되는 모의 라이브러리인 Android(AOSP)를 위한 것입"
|
|
"니다. 특히 HTTP 서비스를 모의 처리하는 영역에는 다른 [crates.io에서 사용 가능"
|
|
"한 모의 라이브러리](https://crates.io/keywords/mock)가 있습니다. 다른 모의 라"
|
|
"이브러리는 Mockall과 비슷한 방식으로 작동합니다. 즉, 특정 트레잇의 모의 구현"
|
|
"을 쉽게 얻을 수 있습니다."
|
|
|
|
#: src/android/testing/mocking.md
|
|
msgid ""
|
|
"Note that mocking is somewhat _controversial_: mocks allow you to completely "
|
|
"isolate a test from its dependencies. The immediate result is faster and "
|
|
"more stable test execution. On the other hand, the mocks can be configured "
|
|
"wrongly and return output different from what the real dependencies would do."
|
|
msgstr ""
|
|
"모의 처리는 다소 _논란의 여지가 있습니다_. 모의를 사용하면 테스트를 종속 항목"
|
|
"에서 완전히 분리할 수 있습니다. 그 결과 테스트 실행이 더욱 빠르고 안정적으로 "
|
|
"이루어집니다. 반면에 모의는 잘못 구성되어 실제 종속 항목이 실행하는 것과 다"
|
|
"른 출력을 반환할 수 있습니다."
|
|
|
|
#: src/android/testing/mocking.md
|
|
msgid ""
|
|
"If at all possible, it is recommended that you use the real dependencies. As "
|
|
"an example, many databases allow you to configure an in-memory backend. This "
|
|
"means that you get the correct behavior in your tests, plus they are fast "
|
|
"and will automatically clean up after themselves."
|
|
msgstr ""
|
|
"가능하면 실제 종속 항목을 사용하는 것이 좋습니다. 예를 들어 많은 데이터베이스"
|
|
"에서는 메모리 내 백엔드를 구성할 수 있습니다. 즉, 테스트에서 올바른 동작을 가"
|
|
"져올 뿐만 아니라 속도가 빠르고 자동으로 정리됩니다."
|
|
|
|
#: src/android/testing/mocking.md
|
|
msgid ""
|
|
"Similarly, many web frameworks allow you to start an in-process server which "
|
|
"binds to a random port on `localhost`. Always prefer this over mocking away "
|
|
"the framework since it helps you test your code in the real environment."
|
|
msgstr ""
|
|
"마찬가지로 많은 웹 프레임워크에서도 `localhost`의 임의 포트에 바인딩되는 프로"
|
|
"세스 내 서버를 시작할 수 있습니다. 프레임워크를 모의 처리하는 것보다는 항상 "
|
|
"이 방법을 사용하는 것이 좋습니다. 실제 환경에서 코드를 테스트하는 데 도움이 "
|
|
"됩니다."
|
|
|
|
#: src/android/testing/mocking.md
|
|
msgid ""
|
|
"Mockall is not part of the Rust Playground, so you need to run this example "
|
|
"in a local environment. Use `cargo add mockall` to quickly add Mockall to an "
|
|
"existing Cargo project."
|
|
msgstr ""
|
|
"Mockall은 Rust 플레이그라운드의 일부가 아니므로 로컬 환경에서 이 예를 실행해"
|
|
"야 합니다. Mockall을 기존 Cargo 프로젝트에 빠르게 추가하려면 `cargo add "
|
|
"mockall`을 사용합니다."
|
|
|
|
#: src/android/testing/mocking.md
|
|
msgid ""
|
|
"Mockall has a lot more functionality. In particular, you can set up "
|
|
"expectations which depend on the arguments passed. Here we use this to mock "
|
|
"a cat which becomes hungry 3 hours after the last time it was fed:"
|
|
msgstr ""
|
|
"Mockall에는 더 많은 기능이 있습니다. 특히 전달된 인수에 따라 기대치를 설정할 "
|
|
"수 있습니다. 여기서는 마지막으로 먹이를 먹고 3시간이 지나면 배고파지는 고양이"
|
|
"를 모의하는 데 이를 사용합니다."
|
|
|
|
#: src/android/testing/mocking.md
|
|
msgid ""
|
|
"You can use `.times(n)` to limit the number of times a mock method can be "
|
|
"called to `n` --- the mock will automatically panic when dropped if this "
|
|
"isn't satisfied."
|
|
msgstr ""
|
|
"`.times(n)`를 사용하여 모의 메서드가 호출될 수 있는 횟수를 `n`으로 제한할 수 "
|
|
"있습니다. 이 조건이 충족되지 않으면 모의 메서드가 삭제될 때 자동으로 패닉 상"
|
|
"태가 됩니다."
|
|
|
|
#: src/android/logging.md
|
|
msgid ""
|
|
"You should use the `log` crate to automatically log to `logcat` (on-device) "
|
|
"or `stdout` (on-host):"
|
|
msgstr ""
|
|
"`log` 크레이트를 사용하면 안드로이드 디바이스 안에서 수행될 때에는 `logcat`으"
|
|
"로, 호스트에서 수행될 때에는 `stdout`으로 로그가 자동으로 출력이 되도록 할 "
|
|
"수 있습니다:"
|
|
|
|
#: src/android/logging.md
|
|
msgid "_hello_rust_logs/Android.bp_:"
|
|
msgstr "_hello_rust_logs/Android.bp_:"
|
|
|
|
#: src/android/logging.md
|
|
msgid "\"hello_rust_logs\""
|
|
msgstr "\"hello_rust_logs\""
|
|
|
|
#: src/android/logging.md
|
|
msgid "\"liblog_rust\""
|
|
msgstr "\"liblog_rust\""
|
|
|
|
#: src/android/logging.md
|
|
msgid "\"liblogger\""
|
|
msgstr "\"liblogger\""
|
|
|
|
#: src/android/logging.md
|
|
msgid "_hello_rust_logs/src/main.rs_:"
|
|
msgstr "_hello_rust_logs/src/main.rs_:"
|
|
|
|
#: src/android/logging.md
|
|
msgid "//! Rust logging demo.\n"
|
|
msgstr "//! Rust 로깅 데모입니다.\n"
|
|
|
|
#: src/android/logging.md
|
|
msgid "/// Logs a greeting.\n"
|
|
msgstr "/// 인사말을 기록합니다.\n"
|
|
|
|
#: src/android/logging.md
|
|
msgid "\"rust\""
|
|
msgstr "\"rust\""
|
|
|
|
#: src/android/logging.md
|
|
msgid "\"Starting program.\""
|
|
msgstr "\"프로그램을 시작하는 중입니다.\""
|
|
|
|
#: src/android/logging.md
|
|
msgid "\"Things are going fine.\""
|
|
msgstr "\"잘 진행되고 있습니다.\""
|
|
|
|
#: src/android/logging.md
|
|
msgid "\"Something went wrong!\""
|
|
msgstr "\"문제가 발생했습니다!\""
|
|
|
|
#: src/android/logging.md src/android/interoperability/with-c/bindgen.md
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "Build, push, and run the binary on your device:"
|
|
msgstr "빌드하고, 가상 디바이스에 넣고, 실행합니다:"
|
|
|
|
#: src/android/logging.md
|
|
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 ""
|
|
"```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"
|
|
"```"
|
|
|
|
#: src/android/logging.md
|
|
msgid "The logs show up in `adb logcat`:"
|
|
msgstr "`adb logcat`커맨드로 로그를 확인합니다:"
|
|
|
|
#: src/android/interoperability.md
|
|
msgid ""
|
|
"Rust has excellent support for interoperability with other languages. This "
|
|
"means that you can:"
|
|
msgstr "러스트는 다음과 같이 다른 언어와의 상호운용성을 훌륭히 지원합니다:"
|
|
|
|
#: src/android/interoperability.md
|
|
msgid "Call Rust functions from other languages."
|
|
msgstr "타 언어에서 러스트 함수를 호출합니다."
|
|
|
|
#: src/android/interoperability.md
|
|
msgid "Call functions written in other languages from Rust."
|
|
msgstr "타 언어의 함수를 러스트에서 호출합니다."
|
|
|
|
#: src/android/interoperability.md
|
|
msgid ""
|
|
"When you call functions in a foreign language we say that you're using a "
|
|
"_foreign function interface_, also known as FFI."
|
|
msgstr ""
|
|
"타 언어의 함수를 호출해서 사용하는 것을 FFI(foreign function interface)라고 "
|
|
"합니다."
|
|
|
|
#: src/android/interoperability/with-c.md
|
|
msgid "Interoperability with C"
|
|
msgstr "C와의 상호운용성"
|
|
|
|
#: src/android/interoperability/with-c.md
|
|
msgid ""
|
|
"Rust has full support for linking object files with a C calling convention. "
|
|
"Similarly, you can export Rust functions and call them from C."
|
|
msgstr ""
|
|
"러스트는 C 호출규약을 따르는 오브젝트 파일과 링킹할 수 있습니다. 또한, 반대"
|
|
"로 러스트 함수를 내보내서 C에서 호출 할 수 도 있습니다."
|
|
|
|
#: src/android/interoperability/with-c.md
|
|
msgid "You can do it by hand if you want:"
|
|
msgstr "원한다면 아래와 같이 수동으로 코딩할 수 있습니다:"
|
|
|
|
#: src/android/interoperability/with-c.md
|
|
msgid "\"{x}, {abs_x}\""
|
|
msgstr "\"{x}, {abs_x}\""
|
|
|
|
#: src/android/interoperability/with-c.md
|
|
msgid ""
|
|
"We already saw this in the [Safe FFI Wrapper exercise](../../exercises/day-3/"
|
|
"safe-ffi-wrapper.md)."
|
|
msgstr ""
|
|
"우리는 이미 [Safe FFI 래퍼 연습문제](../../exercises/day-3/safe-ffi-wrapper."
|
|
"md)에서 이를 다루었습니다."
|
|
|
|
#: src/android/interoperability/with-c.md
|
|
msgid ""
|
|
"This assumes full knowledge of the target platform. Not recommended for "
|
|
"production."
|
|
msgstr ""
|
|
"이러한 방법은 타겟 플랫폼의 모든 부분을 사전에 알고 있다는 전제를 깔고 있습니"
|
|
"다. 상용 프로젝트에서는 권장하지 않습니다."
|
|
|
|
#: src/android/interoperability/with-c.md
|
|
msgid "We will look at better options next."
|
|
msgstr "좀 더 나은 옵션을 살펴보겠습니다."
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "Using Bindgen"
|
|
msgstr "Bindgen 사용하기"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid ""
|
|
"The [bindgen](https://rust-lang.github.io/rust-bindgen/introduction.html) "
|
|
"tool 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
|
|
msgid "First create a small C library:"
|
|
msgstr "먼저 작은 C라이브러리를 만들어 보겠습니다:"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "_interoperability/bindgen/libbirthday.h_:"
|
|
msgstr "_interoperability/bindgen/libbirthday.h_:"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "_interoperability/bindgen/libbirthday.c_:"
|
|
msgstr "_interoperability/bindgen/libbirthday.c_:"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "<stdio.h>"
|
|
msgstr "<stdio.h>"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
msgid "\"libbirthday.h\""
|
|
msgstr "\"libbirthday.h\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "\"+--------------\\n\""
|
|
msgstr "\"+--------------\\n\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "\"| Happy Birthday %s!\\n\""
|
|
msgstr "\"| %s님, 생일 축하합니다.\\n\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "\"| Congratulations with the %i years!\\n\""
|
|
msgstr "\"| %i주년을 축하합니다!\\n\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "Add this to your `Android.bp` file:"
|
|
msgstr "`Android.bp` 파일에 아래를 추가합니다:"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "_interoperability/bindgen/Android.bp_:"
|
|
msgstr "_interoperability/bindgen/Android.bp_:"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
msgid "\"libbirthday\""
|
|
msgstr "\"libbirthday\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
msgid "\"libbirthday.c\""
|
|
msgstr "\"libbirthday.c\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid ""
|
|
"Create a wrapper header file for the library (not strictly needed in this "
|
|
"example):"
|
|
msgstr ""
|
|
"라이브러리에 대한 헤더 파일을 만듭니다(이 예시에서는 반드시 필요한 것은 아닙"
|
|
"니다.):"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "_interoperability/bindgen/libbirthday_wrapper.h_:"
|
|
msgstr "_interoperability/bindgen/libbirthday_wrapper.h_:"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "You can now auto-generate the bindings:"
|
|
msgstr "이제 바인딩을 자동으로 생성할 수 있습니다:"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
msgid "\"libbirthday_bindgen\""
|
|
msgstr "\"libbirthday_bindgen\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
msgid "\"birthday_bindgen\""
|
|
msgstr "\"libbirthday_bindgen\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
msgid "\"libbirthday_wrapper.h\""
|
|
msgstr "\"libbirthday_wrapper.h\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
msgid "\"bindings\""
|
|
msgstr "\"바인딩\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "Finally, we can use the bindings in our Rust program:"
|
|
msgstr "마침내, 러스트 프로그램에서 바인딩을 사용할 수 있습니다:"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
msgid "\"print_birthday_card\""
|
|
msgstr "\"print_birthday_card\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
msgid "\"main.rs\""
|
|
msgstr "\"main.c\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "_interoperability/bindgen/main.rs_:"
|
|
msgstr "_interoperability/bindgen/main.rs_:"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "//! Bindgen demo.\n"
|
|
msgstr "//! Bindgen 데모입니다.\n"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "// SAFETY: `print_card` is safe to call with a valid `card` pointer.\n"
|
|
msgstr ""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
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 ""
|
|
"```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"
|
|
"```"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "Finally, we can run auto-generated tests to ensure the bindings work:"
|
|
msgstr ""
|
|
"마지막으로, 바인딩이 잘 작동하는지 확인하기 위해, 자동 생성된 테스트를 실행"
|
|
"해 보겠습니다:"
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
msgid "\"libbirthday_bindgen_test\""
|
|
msgstr "\"libbirthday_bindgen_test\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
#, fuzzy
|
|
msgid "\":libbirthday_bindgen\""
|
|
msgstr "\":libbirthday_bindgen\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "\"none\""
|
|
msgstr "\"none\""
|
|
|
|
#: src/android/interoperability/with-c/bindgen.md
|
|
msgid "// Generated file, skip linting\n"
|
|
msgstr "// 생성된 파일, 린트 작업 건너뛰기\n"
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "Calling Rust"
|
|
msgstr "C에서 러스트 호출"
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "Exporting Rust functions and types to C is easy:"
|
|
msgstr "러스트에서 타입과 함수를 C로 내보내는 것은 간단합니다:"
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "_interoperability/rust/libanalyze/analyze.rs_"
|
|
msgstr "_interoperability/rust/libanalyze/analyze.rs_"
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "//! Rust FFI demo.\n"
|
|
msgstr "//! Rust FFI 데모입니다.\n"
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "/// Analyze the numbers.\n"
|
|
msgstr "/// 수치를 분석합니다.\n"
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "\"x ({x}) is smallest!\""
|
|
msgstr "\"x({x})가 가장 작습니다.\""
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "\"y ({y}) is probably larger than x ({x})\""
|
|
msgstr "\"y({y})는 x({x})보다 클 수 있습니다.\""
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "_interoperability/rust/libanalyze/analyze.h_"
|
|
msgstr "_interoperability/rust/libanalyze/analyze.h_"
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "_interoperability/rust/libanalyze/Android.bp_"
|
|
msgstr "_interoperability/rust/libanalyze/Android.bp_"
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "\"libanalyze_ffi\""
|
|
msgstr "\"libanalyze_ffi\""
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "\"analyze_ffi\""
|
|
msgstr "\"analyze_ffi\""
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
#, fuzzy
|
|
msgid "\"analyze.rs\""
|
|
msgstr "\"analyze.rs\""
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "We can now call this from a C binary:"
|
|
msgstr "이제 이 러스트 함수를 C바이너리에서 호출할 수 있습니다:"
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "_interoperability/rust/analyze/main.c_"
|
|
msgstr "_interoperability/rust/analyze/main.c_"
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "\"analyze.h\""
|
|
msgstr "\"analyze.h\""
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "_interoperability/rust/analyze/Android.bp_"
|
|
msgstr "_interoperability/rust/analyze/Android.bp_"
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid "\"analyze_numbers\""
|
|
msgstr "\"analyze_numbers\""
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
#, fuzzy
|
|
msgid "\"main.c\""
|
|
msgstr "\"main.c\""
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
#, fuzzy
|
|
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 ""
|
|
"```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"
|
|
"```"
|
|
|
|
#: src/android/interoperability/with-c/rust.md
|
|
msgid ""
|
|
"`#[no_mangle]` disables Rust's usual name mangling, so the exported symbol "
|
|
"will just be the name of the function. You can also use `#[export_name = "
|
|
"\"some_name\"]` to specify whatever name you want."
|
|
msgstr ""
|
|
"`#[no_mangle]`은 러스트의 네임 맹글링(name mangling)을 비활성화하므로 외부로 "
|
|
"노출되는 심볼의 이름은 함수의 이름 그대로가 됩니다. 심볼 이름을 바꾸고 싶다"
|
|
"면 `#[export_name = \"some_name\"]`을 사용합니다."
|
|
|
|
#: src/android/interoperability/cpp.md
|
|
msgid ""
|
|
"The [CXX crate](https://cxx.rs/) makes it possible to do safe "
|
|
"interoperability between Rust and C++."
|
|
msgstr ""
|
|
"[CXX 크레이트](https://cxx.rs/)는 러스트와 C++ 사이의 안전한 상호운용성을 가"
|
|
"능하게 해줍니다."
|
|
|
|
#: src/android/interoperability/cpp.md
|
|
msgid "The overall approach looks like this:"
|
|
msgstr "전체적인 접근 방법은 다음과 같습니다:"
|
|
|
|
#: src/android/interoperability/cpp/bridge.md
|
|
msgid ""
|
|
"CXX relies on a description of the function signatures that will be exposed "
|
|
"from each language to the other. You provide this description using extern "
|
|
"blocks in a Rust module annotated with the `#[cxx::bridge]` attribute macro."
|
|
msgstr ""
|
|
"CXX는 각 언어에서 다른 언어로 노출되는 함수 서명에 관한 설명을 사용합니다. "
|
|
"`#[cxx::bridge]` 속성 매크로로 주석이 달린 Rust 모듈에서 extern 블록을 사용하"
|
|
"여 이 설명을 제공합니다."
|
|
|
|
#: src/android/interoperability/cpp/bridge.md
|
|
msgid "\"org::blobstore\""
|
|
msgstr "\"org::blobstore\""
|
|
|
|
#: src/android/interoperability/cpp/bridge.md
|
|
msgid "// Shared structs with fields visible to both languages.\n"
|
|
msgstr "// 두 언어 모두에 표시되는 필드가 있는 공유 구조체입니다.\n"
|
|
|
|
#: src/android/interoperability/cpp/bridge.md
|
|
#: src/android/interoperability/cpp/generated-cpp.md
|
|
msgid "// Rust types and signatures exposed to C++.\n"
|
|
msgstr "// C++에 노출된 Rust 타입 및 메서드 시그니쳐입니다.\n"
|
|
|
|
#: src/android/interoperability/cpp/bridge.md
|
|
#: src/android/interoperability/cpp/rust-bridge.md
|
|
#: src/android/interoperability/cpp/generated-cpp.md
|
|
#: src/android/interoperability/cpp/rust-result.md
|
|
#: src/chromium/interoperability-with-cpp/example-bindings.md
|
|
#: src/chromium/interoperability-with-cpp/error-handling-qr.md
|
|
#: src/chromium/interoperability-with-cpp/error-handling-png.md
|
|
msgid "\"Rust\""
|
|
msgstr "\"Rust\""
|
|
|
|
#: src/android/interoperability/cpp/bridge.md
|
|
#: src/android/interoperability/cpp/cpp-bridge.md
|
|
msgid "// C++ types and signatures exposed to Rust.\n"
|
|
msgstr "// Rust에 노출된 C++ 타입 및 함수 시그니쳐입니다.\n"
|
|
|
|
#: src/android/interoperability/cpp/bridge.md
|
|
#: src/android/interoperability/cpp/cpp-bridge.md
|
|
#: src/android/interoperability/cpp/cpp-exception.md
|
|
#: src/chromium/interoperability-with-cpp/example-bindings.md
|
|
msgid "\"C++\""
|
|
msgstr "\"C++\""
|
|
|
|
#: src/android/interoperability/cpp/bridge.md
|
|
#: src/android/interoperability/cpp/cpp-bridge.md
|
|
msgid "\"include/blobstore.h\""
|
|
msgstr "\"include/blobstore.h\""
|
|
|
|
#: src/android/interoperability/cpp/bridge.md
|
|
msgid "The bridge is generally declared in an `ffi` module within your crate."
|
|
msgstr "브리지는 일반적으로 크레이트 내의 `ffi` 모듈에 선언됩니다."
|
|
|
|
#: src/android/interoperability/cpp/bridge.md
|
|
msgid ""
|
|
"From the declarations made in the bridge module, CXX will generate matching "
|
|
"Rust and C++ type/function definitions in order to expose those items to "
|
|
"both languages."
|
|
msgstr ""
|
|
"브리지 모듈에서 이루어진 선언으로부터 CXX는 일치하는 Rust 및 C++ 타입/함수 정"
|
|
"의를 생성하여 이러한 항목을 두 언어 모두에 노출합니다."
|
|
|
|
#: src/android/interoperability/cpp/bridge.md
|
|
msgid ""
|
|
"To view the generated Rust code, use [cargo-expand](https://github.com/"
|
|
"dtolnay/cargo-expand) to view the expanded proc macro. For most of the "
|
|
"examples you would use `cargo expand ::ffi` to expand just the `ffi` module "
|
|
"(though this doesn't apply for Android projects)."
|
|
msgstr ""
|
|
"생성된 Rust 코드를 보려면 [cargo-expand](https://github.com/dtolnay/cargo-"
|
|
"expand)를 사용하여 확장된 proc 매크로를 확인하세요. 대부분의 예에서는 `cargo "
|
|
"expand ::ffi`를 사용하여 `ffi` 모듈만 확장합니다(Android 프로젝트에는 적용되"
|
|
"지 않음)."
|
|
|
|
#: src/android/interoperability/cpp/bridge.md
|
|
msgid "To view the generated C++ code, look in `target/cxxbridge`."
|
|
msgstr "생성된 C++ 코드를 보려면 `target/cxxbridge`를 확인하세요."
|
|
|
|
#: src/android/interoperability/cpp/rust-bridge.md
|
|
#, fuzzy
|
|
msgid "Rust Bridge Declarations"
|
|
msgstr "Rust 브리지 선언"
|
|
|
|
#: src/android/interoperability/cpp/rust-bridge.md
|
|
msgid "// Opaque type\n"
|
|
msgstr "// 불투명 타입입니다.\n"
|
|
|
|
#: src/android/interoperability/cpp/rust-bridge.md
|
|
msgid "// Method on `MyType`\n"
|
|
msgstr "// `MyType`의 메서드입니다.\n"
|
|
|
|
#: src/android/interoperability/cpp/rust-bridge.md
|
|
#, fuzzy
|
|
msgid "// Free function\n"
|
|
msgstr "함수"
|
|
|
|
#: src/android/interoperability/cpp/rust-bridge.md
|
|
msgid ""
|
|
"Items declared in the `extern \"Rust\"` reference items that are in scope in "
|
|
"the parent module."
|
|
msgstr ""
|
|
"`extern \"Rust\"`에 선언된 항목은 상위 모듈의 범위 내에 있는 항목을 참조합니"
|
|
"다."
|
|
|
|
#: src/android/interoperability/cpp/rust-bridge.md
|
|
msgid ""
|
|
"The CXX code generator uses your `extern \"Rust\"` section(s) to produce a C+"
|
|
"+ header file containing the corresponding C++ declarations. The generated "
|
|
"header has the same path as the Rust source file containing the bridge, "
|
|
"except with a .rs.h file extension."
|
|
msgstr ""
|
|
"CXX 코드 생성기는 `extern \"Rust\"` 섹션을 사용하여 상응하는 C++ 선언이 포함"
|
|
"된 C++ 헤더 파일을 생성합니다. 생성된 헤더는 파일 확장자가 .rs.h인 경우를 제"
|
|
"외하고 브리지가 포함된 Rust 소스 파일과 동일한 경로를 갖습니다."
|
|
|
|
#: src/android/interoperability/cpp/generated-cpp.md
|
|
msgid "Results in (roughly) the following C++:"
|
|
msgstr "그 결과는 대략 다음과 같은 C++입니다."
|
|
|
|
#: src/android/interoperability/cpp/cpp-bridge.md
|
|
msgid "C++ Bridge Declarations"
|
|
msgstr "C++ 브리지 선언"
|
|
|
|
#: src/android/interoperability/cpp/cpp-bridge.md
|
|
msgid "Results in (roughly) the following Rust:"
|
|
msgstr "결과는 대략 다음과 같은 Rust입니다."
|
|
|
|
#: src/android/interoperability/cpp/cpp-bridge.md
|
|
msgid "\"org$blobstore$cxxbridge1$new_blobstore_client\""
|
|
msgstr "\"org$blobstore$cxxbridge1$new_blobstore_client\""
|
|
|
|
#: src/android/interoperability/cpp/cpp-bridge.md
|
|
msgid "\"org$blobstore$cxxbridge1$BlobstoreClient$put\""
|
|
msgstr "\"org$blobstore$cxxbridge1$BlobstoreClient$put\""
|
|
|
|
#: src/android/interoperability/cpp/cpp-bridge.md
|
|
msgid ""
|
|
"The programmer does not need to promise that the signatures they have typed "
|
|
"in are accurate. CXX performs static assertions that the signatures exactly "
|
|
"correspond with what is declared in C++."
|
|
msgstr ""
|
|
"프로그래머는 자신이 입력한 시그니쳐가 정확하다고 보장할 필요가 없습니다. CXX"
|
|
"는 시그니쳐가C++에서 선언된 것과 정확히 일치하는지를 체크하기 위해 정적으로 "
|
|
"assertion을 실행합니다."
|
|
|
|
#: src/android/interoperability/cpp/cpp-bridge.md
|
|
msgid ""
|
|
"`unsafe extern` blocks allow you to declare C++ functions that are safe to "
|
|
"call from Rust."
|
|
msgstr ""
|
|
"`unsafe extern` 블록을 사용하면 Rust에서 안전하게 호출할 수 있는 C++ 함수를 "
|
|
"선언할 수 있습니다."
|
|
|
|
#: src/android/interoperability/cpp/shared-types.md
|
|
msgid "// A=1, J=11, Q=12, K=13\n"
|
|
msgstr "// A=1, J=11, Q=12, K=13\n"
|
|
|
|
#: src/android/interoperability/cpp/shared-types.md
|
|
msgid "Only C-like (unit) enums are supported."
|
|
msgstr "C와 같은 (단위) enum만 지원됩니다."
|
|
|
|
#: src/android/interoperability/cpp/shared-types.md
|
|
msgid ""
|
|
"A limited number of traits are supported for `#[derive()]` on shared types. "
|
|
"Corresponding functionality is also generated for the C++ code, e.g. if you "
|
|
"derive `Hash` also generates an implementation of `std::hash` for the "
|
|
"corresponding C++ type."
|
|
msgstr ""
|
|
"공유 타입의 `#[derive()]`에는 제한된 수의 트레잇이 지원됩니다. C++ 코드에 대"
|
|
"해서도 상응하는 기능이 생성됩니다. 예를 들어 `Hash`를 파생하면 해당 C++ 타입"
|
|
"에 대한 `std::hash` 구현도 생성됩니다."
|
|
|
|
#: src/android/interoperability/cpp/shared-enums.md
|
|
msgid "Generated Rust:"
|
|
msgstr "생성된 러스트:"
|
|
|
|
#: src/android/interoperability/cpp/shared-enums.md
|
|
#, fuzzy
|
|
msgid "Generated C++:"
|
|
msgstr "생성된 C++:"
|
|
|
|
#: src/android/interoperability/cpp/shared-enums.md
|
|
msgid ""
|
|
"On the Rust side, the code generated for shared enums is actually a struct "
|
|
"wrapping a numeric value. This is because it is not UB in C++ for an enum "
|
|
"class to hold a value different from all of the listed variants, and our "
|
|
"Rust representation needs to have the same behavior."
|
|
msgstr ""
|
|
"Rust 측에서, 공유된 enum에 관해 생성된 코드는 실제로 숫자 값을 래핑하는 구조"
|
|
"체입니다. 이는 enum 클래스가 나열된 모든 변형과 다른 값을 보유하는 것이 C++에"
|
|
"서 UB가 아니고 Rust 표현도 동일한 동작을 가져야 하기 때문입니다."
|
|
|
|
#: src/android/interoperability/cpp/rust-result.md
|
|
msgid "\"fallible1 requires depth > 0\""
|
|
msgstr "\"fallible1에 깊이 > 0 필요\""
|
|
|
|
#: src/android/interoperability/cpp/rust-result.md
|
|
msgid "\"Success!\""
|
|
msgstr "\"완료!\""
|
|
|
|
#: src/android/interoperability/cpp/rust-result.md
|
|
msgid ""
|
|
"Rust functions that return `Result` are translated to exceptions on the C++ "
|
|
"side."
|
|
msgstr "`Result`를 반환하는 Rust 함수는 C++ 측에서 예외로 변환됩니다."
|
|
|
|
#: src/android/interoperability/cpp/rust-result.md
|
|
msgid ""
|
|
"The exception thrown will always be of type `rust::Error`, which primarily "
|
|
"exposes a way to get the error message string. The error message will come "
|
|
"from the error type's `Display` impl."
|
|
msgstr ""
|
|
"발생하는 예외는 항상 `rust::Error` 타입이며 주로 오류 메시지 문자열을 가져오"
|
|
"는 방법을 노출합니다. 오류 메시지는 오류 타입의 `Display` impl에서 가져옵니"
|
|
"다."
|
|
|
|
#: src/android/interoperability/cpp/rust-result.md
|
|
msgid ""
|
|
"A panic unwinding from Rust to C++ will always cause the process to "
|
|
"immediately terminate."
|
|
msgstr "Rust에서 C++로 패닉이 해제되면 프로세스가 즉시 종료됩니다."
|
|
|
|
#: src/android/interoperability/cpp/cpp-exception.md
|
|
msgid "\"example/include/example.h\""
|
|
msgstr "\"example/include/example.h\""
|
|
|
|
#: src/android/interoperability/cpp/cpp-exception.md
|
|
msgid "\"Error: {}\""
|
|
msgstr "\"오류: {}\""
|
|
|
|
#: src/android/interoperability/cpp/cpp-exception.md
|
|
msgid ""
|
|
"C++ functions declared to return a `Result` will catch any thrown exception "
|
|
"on the C++ side and return it as an `Err` value to the calling Rust function."
|
|
msgstr ""
|
|
"`Result`를 반환하도록 선언된 C++ 함수는 C++ 측에서 발생한 예외를 포착하고 이"
|
|
"를 호출 Rust 함수에 `Err` 값으로 반환합니다."
|
|
|
|
#: src/android/interoperability/cpp/cpp-exception.md
|
|
msgid ""
|
|
"If an exception is thrown from an extern \"C++\" function that is not "
|
|
"declared by the CXX bridge to return `Result`, the program calls C++'s `std::"
|
|
"terminate`. The behavior is equivalent to the same exception being thrown "
|
|
"through a `noexcept` C++ function."
|
|
msgstr ""
|
|
"`Result`를 반환하도록 CXX 브리지에서 선언하지 않은 extern 'C++' 함수에서 예외"
|
|
"가 발생하면 프로그램은 C++의 `std::terminate`를 호출합니다. 이 동작은 "
|
|
"`noexcept` C++ 함수를 통해 발생하는 동일한 예외와 같습니다."
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "C++ Type"
|
|
msgstr "C++ 예제"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`rust::String`"
|
|
msgstr "`std::string`"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
msgid "`&str`"
|
|
msgstr "`&str`"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`rust::Str`"
|
|
msgstr "`rust::Box<T>`"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`CxxString`"
|
|
msgstr "String"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`std::string`"
|
|
msgstr "`std::string`"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
msgid "`&[T]`/`&mut [T]`"
|
|
msgstr "`&[T]`/`&mut [T]`"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`rust::Slice`"
|
|
msgstr "`rust_ffi`"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`rust::Box<T>`"
|
|
msgstr "`rust::Box<T>`"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
msgid "`UniquePtr<T>`"
|
|
msgstr "`UniquePtr<T>`"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`std::unique_ptr<T>`"
|
|
msgstr "`std::unique_ptr<T>`"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`rust::Vec<T>`"
|
|
msgstr "`rust::Box<T>`"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`CxxVector<T>`"
|
|
msgstr "`Cell<T>`"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
#, fuzzy
|
|
msgid "`std::vector<T>`"
|
|
msgstr "`std::unique_ptr<T>`"
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
msgid ""
|
|
"These types can be used in the fields of shared structs and the arguments "
|
|
"and returns of extern functions."
|
|
msgstr ""
|
|
"이러한 타입은 공유 구조체의 필드와 extern 함수의 인수 및 반환에서 사용할 수 "
|
|
"있습니다."
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
msgid ""
|
|
"Note that Rust's `String` does not map directly to `std::string`. There are "
|
|
"a few reasons for this:"
|
|
msgstr ""
|
|
"Rust의 `String`은 `std::string`에 직접 매핑되지 않습니다. 여기에는 다음과 같"
|
|
"은 몇 가지 이유가 있습니다."
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
msgid ""
|
|
"`std::string` does not uphold the UTF-8 invariant that `String` requires."
|
|
msgstr "`std::string`은 `String`에 필요한 UTF-8 불변값을 유지하지 않습니다."
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
msgid ""
|
|
"The two types have different layouts in memory and so can't be passed "
|
|
"directly between languages."
|
|
msgstr ""
|
|
"두 타입은 메모리에 서로 다른 레이아웃을 가지고 있으므로 언어 간에 직접 전달"
|
|
"될 수 없습니다."
|
|
|
|
#: src/android/interoperability/cpp/type-mapping.md
|
|
msgid ""
|
|
"`std::string` requires move constructors that don't match Rust's move "
|
|
"semantics, so a `std::string` can't be passed by value to Rust."
|
|
msgstr ""
|
|
"`std::string`에는 Rust의 이동 의미 체계와 일치하지 않는 이동 생성자가 필요하"
|
|
"므로 `std::string`을 값으로 Rust에 전달할 수 없습니다."
|
|
|
|
#: src/android/interoperability/cpp/android-build-cpp.md
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
#: src/android/interoperability/cpp/android-build-rust.md
|
|
#, fuzzy
|
|
msgid "Building in Android"
|
|
msgstr "Android에서 빌드"
|
|
|
|
#: src/android/interoperability/cpp/android-build-cpp.md
|
|
msgid ""
|
|
"Create a `cc_library_static` to build the C++ library, including the CXX "
|
|
"generated header and source file."
|
|
msgstr ""
|
|
"`cc_library_static`을 만들어 CXX에서 생성된 헤더와 소스 파일을 비롯하여 C++ "
|
|
"라이브러리를 빌드합니다."
|
|
|
|
#: src/android/interoperability/cpp/android-build-cpp.md
|
|
#: src/android/interoperability/cpp/android-build-rust.md
|
|
msgid "\"libcxx_test_cpp\""
|
|
msgstr "\"libcxx_test_cpp\""
|
|
|
|
#: src/android/interoperability/cpp/android-build-cpp.md
|
|
msgid "\"cxx_test.cpp\""
|
|
msgstr "\"cxx_test.cpp\""
|
|
|
|
#: src/android/interoperability/cpp/android-build-cpp.md
|
|
msgid "\"cxx-bridge-header\""
|
|
msgstr "\"cxx-bridge-header\""
|
|
|
|
#: src/android/interoperability/cpp/android-build-cpp.md
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
msgid "\"libcxx_test_bridge_header\""
|
|
msgstr "\"libcxx_test_bridge_header\""
|
|
|
|
#: src/android/interoperability/cpp/android-build-cpp.md
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
msgid "\"libcxx_test_bridge_code\""
|
|
msgstr "\"libcxx_test_bridge_code\""
|
|
|
|
#: src/android/interoperability/cpp/android-build-cpp.md
|
|
msgid ""
|
|
"Point out that `libcxx_test_bridge_header` and `libcxx_test_bridge_code` are "
|
|
"the dependencies for the CXX-generated C++ bindings. We'll show how these "
|
|
"are setup on the next slide."
|
|
msgstr ""
|
|
"`libcxx_test_bridge_header` 및 `libcxx_test_bridge_code`가 CXX에서 생성된 C+"
|
|
"+ 바인딩의 종속 항목이라는 점을 지적합니다. 다음 슬라이드에서 설정 방법을 알"
|
|
"아봅니다."
|
|
|
|
#: src/android/interoperability/cpp/android-build-cpp.md
|
|
msgid ""
|
|
"Note that you also need to depend on the `cxx-bridge-header` library in "
|
|
"order to pull in common CXX definitions."
|
|
msgstr ""
|
|
"일반적인 CXX 정의를 가져오려면 `cxx-bridge-header` 라이브러리도 사용해야 합니"
|
|
"다."
|
|
|
|
#: src/android/interoperability/cpp/android-build-cpp.md
|
|
msgid ""
|
|
"Full docs for using CXX in Android can be found in [the Android docs]"
|
|
"(https://source.android.com/docs/setup/build/rust/building-rust-modules/"
|
|
"android-rust-patterns#rust-cpp-interop-using-cxx). You may want to share "
|
|
"that link with the class so that students know where they can find these "
|
|
"instructions again in the future."
|
|
msgstr ""
|
|
"Android에서 CXX를 사용하는 방법에 관한 전체 문서는 [Android 문서](https://"
|
|
"source.android.com/docs/setup/build/rust/building-rust-modules/android-rust-"
|
|
"patterns#rust-cpp-interop-using-cxx)에서 확인할 수 있습니다. 학생들이 나중에 "
|
|
"이 안내를 어디에서 다시 찾을 수 있는지 알 수 있도록 이 링크를 수업에 공유하"
|
|
"는 것이 좋습니다."
|
|
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
msgid ""
|
|
"Create two genrules: One to generate the CXX header, and one to generate the "
|
|
"CXX source file. These are then used as inputs to the `cc_library_static`."
|
|
msgstr ""
|
|
"두 개의 genrule을 만듭니다. 하나는 CXX 헤더를 생성하고 다른 하나는 CXX 소스 "
|
|
"파일을 생성합니다. 그런 다음 `cc_library_static`에 대한 입력으로 사용됩니다."
|
|
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
msgid ""
|
|
"// Generate a C++ header containing the C++ bindings\n"
|
|
"// to the Rust exported functions in lib.rs.\n"
|
|
msgstr ""
|
|
"// lib.rs의 Rust 내보내기 함수에 대한\n"
|
|
"// C++ 바인딩이 포함된 C++ 헤더를 생성합니다.\n"
|
|
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
msgid "\"cxxbridge\""
|
|
msgstr "\"cxxbridge\""
|
|
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
msgid "\"$(location cxxbridge) $(in) --header > $(out)\""
|
|
msgstr "\"$(location cxxbridge) $(in) --header > $(out)\""
|
|
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
#: src/android/interoperability/cpp/android-build-rust.md
|
|
#, fuzzy
|
|
msgid "\"lib.rs\""
|
|
msgstr "\"lib.rs\""
|
|
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
#, fuzzy
|
|
msgid "\"lib.rs.h\""
|
|
msgstr "\"lib.rs.h\""
|
|
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
msgid "// Generate the C++ code that Rust calls into.\n"
|
|
msgstr "// Rust가 호출하는 C++ 코드를 생성합니다.\n"
|
|
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
msgid "\"$(location cxxbridge) $(in) > $(out)\""
|
|
msgstr "\"$(location cxxbridge) $(in) > $(out)\""
|
|
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
#, fuzzy
|
|
msgid "\"lib.rs.cc\""
|
|
msgstr "\"lib.rs.cc\""
|
|
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
msgid ""
|
|
"The `cxxbridge` tool is a standalone tool that generates the C++ side of the "
|
|
"bridge module. It is included in Android and available as a Soong tool."
|
|
msgstr ""
|
|
"`cxxbridge` 도구는 C++ 측의 브리지 모듈을 생성하는 독립형 도구입니다. 이 도구"
|
|
"는 Android에 포함되어 있으며 Soong 도구로 사용할 수 있습니다."
|
|
|
|
#: src/android/interoperability/cpp/android-cpp-genrules.md
|
|
msgid ""
|
|
"By convention, if your Rust source file is `lib.rs` your header file will be "
|
|
"named `lib.rs.h` and your source file will be named `lib.rs.cc`. This naming "
|
|
"convention isn't enforced, though."
|
|
msgstr ""
|
|
"일반적으로 Rust 소스 파일이 `lib.rs`인 경우 헤더 파일의 이름은 `lib.rs.h`이"
|
|
"고 소스 파일의 이름은 `lib.rs.cc`가 됩니다. 그러나 이 이름 지정 규칙은 강제되"
|
|
"지 않습니다."
|
|
|
|
#: src/android/interoperability/cpp/android-build-rust.md
|
|
msgid ""
|
|
"Create a `rust_binary` that depends on `libcxx` and your `cc_library_static`."
|
|
msgstr "`libcxx` 및 `cc_library_static`에 종속되는 `rust_binary`를 생성합니다."
|
|
|
|
#: src/android/interoperability/cpp/android-build-rust.md
|
|
msgid "\"cxx_test\""
|
|
msgstr "\"cxx_test\""
|
|
|
|
#: src/android/interoperability/cpp/android-build-rust.md
|
|
msgid "\"libcxx\""
|
|
msgstr "\"libcxx\""
|
|
|
|
#: src/android/interoperability/java.md
|
|
msgid "Interoperability with Java"
|
|
msgstr "Java와의 상호운용성"
|
|
|
|
#: src/android/interoperability/java.md
|
|
msgid ""
|
|
"Java can load shared objects via [Java Native Interface (JNI)](https://en."
|
|
"wikipedia.org/wiki/Java_Native_Interface). The [`jni` 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
|
|
msgid "First, we create a Rust function to export to Java:"
|
|
msgstr "먼저, 자바로 내보낼 러스트 함수를 생성합니다:"
|
|
|
|
#: src/android/interoperability/java.md
|
|
#, fuzzy
|
|
msgid "_interoperability/java/src/lib.rs_:"
|
|
msgstr "_interoperability/bindgen/main.rs_:"
|
|
|
|
#: src/android/interoperability/java.md
|
|
msgid "//! Rust <-> Java FFI demo.\n"
|
|
msgstr "//! Rust <-> Java FFI 데모입니다.\n"
|
|
|
|
#: src/android/interoperability/java.md
|
|
#, fuzzy
|
|
msgid "/// HelloWorld::hello method implementation.\n"
|
|
msgstr "/// HelloWorld::hello 메서드 구현입니다.\n"
|
|
|
|
#: src/android/interoperability/java.md
|
|
#, fuzzy
|
|
msgid "\"system\""
|
|
msgstr "\"시스템\""
|
|
|
|
#: src/android/interoperability/java.md
|
|
#, fuzzy
|
|
msgid "\"Hello, {input}!\""
|
|
msgstr "\"{input}님, 안녕하세요!\""
|
|
|
|
#: src/android/interoperability/java.md
|
|
#, fuzzy
|
|
msgid "_interoperability/java/Android.bp_:"
|
|
msgstr "_interoperability/bindgen/Android.bp_:"
|
|
|
|
#: src/android/interoperability/java.md
|
|
msgid "\"libhello_jni\""
|
|
msgstr "\"libhello_jni\""
|
|
|
|
#: src/android/interoperability/java.md
|
|
#, fuzzy
|
|
msgid "\"hello_jni\""
|
|
msgstr "\"hello_jni\""
|
|
|
|
#: src/android/interoperability/java.md
|
|
msgid "\"libjni\""
|
|
msgstr "\"libjni\""
|
|
|
|
#: src/android/interoperability/java.md
|
|
#, fuzzy
|
|
msgid "We then call this function from Java:"
|
|
msgstr "자바에서 이 함수를 호출 할 수 있습니다:"
|
|
|
|
#: src/android/interoperability/java.md
|
|
#, fuzzy
|
|
msgid "_interoperability/java/HelloWorld.java_:"
|
|
msgstr "_interoperability/bindgen/libbirthday.h_:"
|
|
|
|
#: src/android/interoperability/java.md
|
|
#, fuzzy
|
|
msgid "\"helloworld_jni\""
|
|
msgstr "\"helloworld_jni\""
|
|
|
|
#: src/android/interoperability/java.md
|
|
#, fuzzy
|
|
msgid "\"HelloWorld.java\""
|
|
msgstr "\"helloworld_jni\""
|
|
|
|
#: src/android/interoperability/java.md
|
|
#, fuzzy
|
|
msgid "\"HelloWorld\""
|
|
msgstr "\"helloworld_jni\""
|
|
|
|
#: src/android/interoperability/java.md
|
|
msgid "Finally, you can build, sync, and run the binary:"
|
|
msgstr "마지막으로 바이너리를 빌드, 싱크, 실행합니다:"
|
|
|
|
#: src/exercises/android/morning.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"This is a group exercise: We will look at one of the projects you work with "
|
|
"and try to integrate some Rust into it. Some suggestions:"
|
|
msgstr ""
|
|
"마지막 연습문제는 여러분이 작업하고 있는 프로젝트 중 하나를 FFI로 러스트와 연"
|
|
"계 해보는 것입니다. 몇 가지 예시입니다:"
|
|
|
|
#: src/exercises/android/morning.md
|
|
msgid "Call your AIDL service with a client written in Rust."
|
|
msgstr "당신의 AIDL서비스를 러스트 클라이언트에서 호출해봅니다."
|
|
|
|
#: src/exercises/android/morning.md
|
|
msgid "Move a function from your project to Rust and call it."
|
|
msgstr "당신의 프로젝트의 함수를 러스트로 옮기고 호출해봅니다."
|
|
|
|
#: src/exercises/android/morning.md
|
|
msgid ""
|
|
"No solution is provided here since this is open-ended: it relies on someone "
|
|
"in the class having a piece of code which you can turn in to Rust on the fly."
|
|
msgstr ""
|
|
"이 연습문제는 열려있기 때문에 해답이 제공되지 않습니다. 클래스에서 제출된 코"
|
|
"드에 의존합니다."
|
|
|
|
#: src/chromium.md
|
|
#, fuzzy
|
|
msgid "Welcome to Rust in Chromium"
|
|
msgstr "1일차 개요"
|
|
|
|
#: src/chromium.md
|
|
msgid ""
|
|
"Rust is supported for third-party libraries in Chromium, with first-party "
|
|
"glue code to connect between Rust and existing Chromium C++ code."
|
|
msgstr ""
|
|
"Rust는 Chromium의 서드 파티 라이브러리에 대해 지원되며, Rust와 기존 Chromium "
|
|
"C++ 코드 간에 연결하는 퍼스트 파티 글루 코드를 포함합니다."
|
|
|
|
#: src/chromium.md
|
|
msgid ""
|
|
"Today, we'll call into Rust to do something silly with strings. If you've "
|
|
"got a corner of the code where you're displaying a UTF8 string to the user, "
|
|
"feel free to follow this recipe in your part of the codebase instead of the "
|
|
"exact part we talk about."
|
|
msgstr ""
|
|
"오늘은 Rust를 호출하여 문자열로 우스꽝스러운 작업을 해 보겠습니다. 사용자에"
|
|
"게 UTF8 문자열을 표시하는 코드 부분이 있는 경우, 언급되는 정확한 부분 대신 코"
|
|
"드베이스에서 이 레시피를 따르시면 됩니다."
|
|
|
|
#: src/chromium/setup.md
|
|
msgid ""
|
|
"Make sure you can build and run Chromium. Any platform and set of build "
|
|
"flags is OK, so long as your code is relatively recent (commit position "
|
|
"1223636 onwards, corresponding to November 2023):"
|
|
msgstr ""
|
|
"Chromium을 빌드하고 실행할 수 있는지 확인합니다. 코드가 비교적 최신이라면(커"
|
|
"밋 위치 1223636 이후, 2023년 11월에 해당) 어떤 플랫폼이나 빌드 플래그 집합도 "
|
|
"괜찮습니다."
|
|
|
|
#: src/chromium/setup.md
|
|
msgid ""
|
|
"(A component, debug build is recommended for quickest iteration time. This "
|
|
"is the default!)"
|
|
msgstr ""
|
|
"개발 속도를 빠르게 하고 싶다면 디버그 빌드를 사용하는 것이 좋습니다. 이게 기"
|
|
"본값입니다."
|
|
|
|
#: src/chromium/setup.md
|
|
msgid ""
|
|
"See [How to build Chromium](https://www.chromium.org/developers/how-tos/get-"
|
|
"the-code/) if you aren't already at that point. Be warned: setting up to "
|
|
"build Chromium takes time."
|
|
msgstr ""
|
|
"아직 빌드하지 않았다면 [Chromium 빌드 방법](https://www.chromium.org/"
|
|
"developers/how-tos/get-the-code/)을 참고하세요. 주의: Chromium 빌드 환경 셋업"
|
|
"은 시간이 걸립니다."
|
|
|
|
#: src/chromium/setup.md
|
|
msgid "It's also recommended that you have Visual Studio code installed."
|
|
msgstr "또한 Visual Studio Code가 설치되어 있는 것이 좋습니다."
|
|
|
|
#: src/chromium/setup.md
|
|
#, fuzzy
|
|
msgid "About the exercises"
|
|
msgstr "연습문제 정보"
|
|
|
|
#: src/chromium/setup.md
|
|
msgid ""
|
|
"This part of the course has a series of exercises which build on each other. "
|
|
"We'll be doing them spread throughout the course instead of just at the end. "
|
|
"If you don't have time to complete a certain part, don't worry: you can "
|
|
"catch up in the next slot."
|
|
msgstr ""
|
|
"과정의 이 부분에는 서로 연계되는 일련의 연습문제가 있습니다. 마지막에 한꺼번"
|
|
"에 하지 않고 과정 전반에 연습문제가 흩어져 있습니다. 특정 부분을 완료할 시간"
|
|
"이 없더라도 걱정하지 마세요. 다음번에 따라잡을 수 있습니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"The Rust community typically uses `cargo` and libraries from [crates.io]"
|
|
"(https://crates.io/). Chromium is built using `gn` and `ninja` and a curated "
|
|
"set of dependencies."
|
|
msgstr ""
|
|
"Rust 커뮤니티는 일반적으로 [crates.io](https://crates.io/)의 `cargo` 및 라이"
|
|
"브러리를 사용합니다. Chromium은 세심하게 선별된 의존성들과 함께 `gn`, `ninja`"
|
|
"을 이용하여 빌드됩니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid "When writing code in Rust, your choices are:"
|
|
msgstr "Rust로 코드를 작성할 때 선택할 수 있는 옵션은 다음과 같습니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Use `gn` and `ninja` with the help of the templates from `//build/rust/*."
|
|
"gni` (e.g. `rust_static_library` that we'll meet later). This uses "
|
|
"Chromium's audited toolchain and crates."
|
|
msgstr ""
|
|
"`//build/rust/*.gni`의 템플릿(예: 나중에 다룰 `rust_static_library`)을 통해 "
|
|
"`gn` 및 `ninja`를 사용합니다. 이는 Chromium의 감사 도구 모음 및 크레이트를 사"
|
|
"용합니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Use `cargo`, but [restrict yourself to Chromium's audited toolchain and "
|
|
"crates](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/"
|
|
"docs/rust.md#Using-cargo)"
|
|
msgstr ""
|
|
"`cargo`를 사용하되 [Chromium의 감사 도구 모음 및 크레이트로 제한]합니다"
|
|
"(https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/rust."
|
|
"md#Using-cargo)."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Use `cargo`, trusting a [toolchain](https://rustup.rs/) and/or [crates "
|
|
"downloaded from the internet](https://crates.io/)"
|
|
msgstr ""
|
|
"`cargo`를 사용하여 [도구 모음](https://rustup.rs/) 또는 [인터넷에서 다운로드"
|
|
"한 크레이트](https://crates.io/)를 신뢰합니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"From here on we'll be focusing on `gn` and `ninja`, because this is how Rust "
|
|
"code can be built into the Chromium browser. At the same time, Cargo is an "
|
|
"important part of the Rust ecosystem and you should keep it in your toolbox."
|
|
msgstr ""
|
|
"여기서부터는 `gn`과 `ninja`에 집중할 겁니다. 그 도구들을 써야만 Chromium 브라"
|
|
"우저에 Rust 코드를빌드해서 넣을 수 있기 때문입니다. 이와 동시에, Cargo는 "
|
|
"Rust 생태계에서 중요한 부분이므로 Cargo에도 익숙해야 합니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
#, fuzzy
|
|
msgid "Mini exercise"
|
|
msgstr "연습문제"
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid "Split into small groups and:"
|
|
msgstr "소규모 그룹으로 나눈 다음:"
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Brainstorm scenarios where `cargo` may offer an advantage and assess the "
|
|
"risk profile of these scenarios."
|
|
msgstr ""
|
|
"'cargo'가 유리할 수 있는 시나리오를 브레인스토밍하고 이러한 시나리오의 위험 "
|
|
"프로필을 평가합니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Discuss which tools, libraries, and groups of people need to be trusted when "
|
|
"using `gn` and `ninja`, offline `cargo`, etc."
|
|
msgstr ""
|
|
"`gn` 및 `ninja`, 오프라인 `cargo` 등을 사용할 때 신뢰해야 하는 도구, 라이브러"
|
|
"리, 사용자 그룹을 논의합니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Ask students to avoid peeking at the speaker notes before completing the "
|
|
"exercise. Assuming folks taking the course are physically together, ask them "
|
|
"to discuss in small groups of 3-4 people."
|
|
msgstr ""
|
|
"학생들에게 연습문제를 완료하기 전에 발표자 노트를 엿보지 말라고 합니다. 과정"
|
|
"을 수강하는 학생들이 실제로 함께 있다고 가정하고 3~4명으로 구성된 소그룹으로 "
|
|
"토론하도록 합니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Notes/hints related to the first part of the exercise (\"scenarios where "
|
|
"Cargo may offer an advantage\"):"
|
|
msgstr ""
|
|
"연습문제의 첫 부분과 관련된 참고사항/힌트('Cargo가 이점을 제공할 수 있는 시나"
|
|
"리오'):"
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"It's fantastic that when writing a tool, or prototyping a part of Chromium, "
|
|
"one has access to the rich ecosystem of crates.io libraries. There is a "
|
|
"crate for almost anything and they are usually quite pleasant to use. "
|
|
"(`clap` for command-line parsing, `serde` for serializing/deserializing to/"
|
|
"from various formats, `itertools` for working with iterators, etc.)."
|
|
msgstr ""
|
|
"도구를 작성하거나 Chromium 일부의 프로토타입을 제작할 때 crates.io 라이브러리"
|
|
"의 풍부한 생태계에 액세스할 수 있다는 것은 멋진 일입니다. 거의 모든 것을 위"
|
|
"해 크레이트가 있으며 일반적으로 사용하기 매우 좋습니다. 명령줄 파싱을 위한 "
|
|
"`clap`, 다양한 형식 간 직렬화/역직렬화를 위한 `serde`, 반복자를 사용하는 경우"
|
|
"의 `itertools` 등이 있습니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"`cargo` makes it easy to try a library (just add a single line to `Cargo."
|
|
"toml` and start writing code)"
|
|
msgstr ""
|
|
"`cargo`를 사용하면 라이브러리를 쉽게 사용해 볼 수 있습니다. `Cargo.toml`에 "
|
|
"한 줄을 추가하고 코드 작성을 시작하면 됩니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"It may be worth comparing how CPAN helped make `perl` a popular choice. Or "
|
|
"comparing with `python` + `pip`."
|
|
msgstr ""
|
|
"`perl`이 인기를 얻게 된 데 CPAN이 어떤 도움이 되었는지 비교해 보는 것도 좋습"
|
|
"니다. `python` + `pip`와 비교해도 됩니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Development experience is made really nice not only by core Rust tools (e.g. "
|
|
"using `rustup` to switch to a different `rustc` version when testing a crate "
|
|
"that needs to work on nightly, current stable, and older stable) but also by "
|
|
"an ecosystem of third-party tools (e.g. Mozilla provides `cargo vet` for "
|
|
"streamlining and sharing security audits; `criterion` crate gives a "
|
|
"streamlined way to run benchmarks)."
|
|
msgstr ""
|
|
"핵심 Rust 도구(예: 나이틀리, 최신 안정화 버전, 이전 안정화 버전에서 작동해야 "
|
|
"하는 크레이트를 테스트할 때 `rustup`을 사용하여 다른 `rustc` 버전으로 전환)뿐"
|
|
"만 아니라 서드 파티 도구의 생태계(예: Mozilla는 보안 감사 간소화 및 공유를 위"
|
|
"해 `cargo vet` 제공, `criterion` 크레이트는 간소화된 벤치마크 실행 방법을 제"
|
|
"공함)를 통해서도 개발 환경이 개선됩니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"`cargo` makes it easy to add a tool via `cargo install --locked cargo-vet`."
|
|
msgstr ""
|
|
"`cargo`를 사용하면 `cargo install --locked cargo-vet`를 통해 도구를 쉽게 추가"
|
|
"할 수 있습니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid "It may be worth comparing with Chrome Extensions or VScode extensions."
|
|
msgstr ""
|
|
"Chrome 확장 프로그램 또는 VScode 확장 프로그램과 비교해 보는 것이 좋습니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Broad, generic examples of projects where `cargo` may be the right choice:"
|
|
msgstr "`cargo`가 적합할 수 있는 프로젝트의 광범위하고 일반적인 예:"
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Perhaps surprisingly, Rust is becoming increasingly popular in the industry "
|
|
"for writing command line tools. The breadth and ergonomics of libraries is "
|
|
"comparable to Python, while being more robust (thanks to the rich "
|
|
"typesystem) and running faster (as a compiled, rather than interpreted "
|
|
"language)."
|
|
msgstr ""
|
|
"놀랍게도 업계에서 Rust가 명령줄 도구 작성으로 점점 인기를 얻고 있습니다. 라"
|
|
"이브러리의 다양함과 사용편의성은 Python과 유사하지만 풍부한 타입 시스템 덕분"
|
|
"에 더 안전하고 더 빠르게 실행됩니다(인터프리트 언어가 아닌 컴파일된 언어로)."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Participating in the Rust ecosystem requires using standard Rust tools like "
|
|
"Cargo. Libraries that want to get external contributions, and want to be "
|
|
"used outside of Chromium (e.g. in Bazel or Android/Soong build environments) "
|
|
"should probably use Cargo."
|
|
msgstr ""
|
|
"Rust 생태계에 참여하려면 Cargo와 같은 표준 Rust 도구를 사용해야 합니다. 외부 "
|
|
"기여를 원하고 Chromium 외부(예: Bazel 또는 Android/Soong 빌드 환경)에서 사용"
|
|
"하고자 하는 라이브러리는 Cargo를 사용해야 할 수 있습니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid "Examples of Chromium-related projects that are `cargo`\\-based:"
|
|
msgstr "`cargo`\\ 기반 Chromium 관련 프로젝트의 예는 다음과 같습니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"`serde_json_lenient` (experimented with in other parts of Google which "
|
|
"resulted in PRs with performance improvements)"
|
|
msgstr ""
|
|
"`serde_json_lenient`(Google의 다른 부분에서 실험하여 성능이 개선된 PR이 나옴)"
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid "Fontations libraries like `font-types`"
|
|
msgstr "`font-types`와 같은 글꼴 라이브러리"
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"`gnrt` tool (we will meet it later in the course) which depends on `clap` "
|
|
"for command-line parsing and on `toml` for configuration files."
|
|
msgstr ""
|
|
"`gnrt` 도구(과정 후반부에서 설명)는 명령줄 파싱의 경우 `clap`, 구성 파일의 경"
|
|
"우 `toml`에 종속됩니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Disclaimer: a unique reason for using `cargo` was unavailability of `gn` "
|
|
"when building and bootstrapping Rust standard library when building Rust "
|
|
"toolchain."
|
|
msgstr ""
|
|
"주의: 여기서 `cargo`를 사용하는 유일한 이유는 Rust 도구 모음을 빌드할 때 "
|
|
"Rust 표준 라이브러리를 빌드하고 부트스트랩하는 경우 `gn`을 사용할 수 없기 때"
|
|
"문입니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"`run_gnrt.py` uses Chromium's copy of `cargo` and `rustc`. `gnrt` depends on "
|
|
"third-party libraries downloaded from the internet, but `run_gnrt.py` asks "
|
|
"`cargo` that only `--locked` content is allowed via `Cargo.lock`.)"
|
|
msgstr ""
|
|
"`run_gnrt.py`는 Chromium의 `cargo` 및 `rustc` 사본을 사용합니다. `gnrt`는 인"
|
|
"터넷에서 다운로드한 서드 파티 라이브러리에 종속되며 `run_gnrt.py`는 `cargo`"
|
|
"에 `Cargo.lock`을 통해 `--locked` 콘텐츠만 허용된다고 합니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Students may identify the following items as being implicitly or explicitly "
|
|
"trusted:"
|
|
msgstr ""
|
|
"학생은 다음 항목을 암시적 또는 명시적으로 신뢰할 수 있는 것으로 식별할 수 있"
|
|
"습니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"`rustc` (the Rust compiler) which in turn depends on the LLVM libraries, the "
|
|
"Clang compiler, the `rustc` sources (fetched from GitHub, reviewed by Rust "
|
|
"compiler team), binary Rust compiler downloaded for bootstrapping"
|
|
msgstr ""
|
|
"`rustc`(Rust 컴파일러)는 차례로 LLVM 라이브러리, Clang 컴파일러, `rustc` 소스"
|
|
"(GitHub에서 가져옴, Rust 컴파일러팀에서 검토), 부트스트랩을 위해 다운로드한 "
|
|
"바이너리 Rust 컴파일러에 종속됩니다."
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"`rustup` (it may be worth pointing out that `rustup` is developed under the "
|
|
"umbrella of the https://github.com/rust-lang/ organization - same as `rustc`)"
|
|
msgstr ""
|
|
"`rustup`(`rustup`은 https://github.com/rust-lang/ 조직 산하에서 개발되었으며 "
|
|
"`rustc`와 동일함)"
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid "`cargo`, `rustfmt`, etc."
|
|
msgstr "`cargo`, `rustfmt` 등"
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Various internal infrastructure (bots that build `rustc`, system for "
|
|
"distributing the prebuilt toolchain to Chromium engineers, etc.)"
|
|
msgstr ""
|
|
"다양한 내부 인프라('rustc'를 빌드하는 봇, 사전 빌드된 도구 모음을 Chromium 엔"
|
|
"지니어에게 배포하기 위한 시스템 등)"
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid "Cargo tools like `cargo audit`, `cargo vet`, etc."
|
|
msgstr "`cargo audit`, `cargo vet` 등과 같은 Cargo 도구"
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid ""
|
|
"Rust libraries vendored into `//third_party/rust` (audited by "
|
|
"security@chromium.org)"
|
|
msgstr ""
|
|
"`//third_party/rust`에 공급되는 Rust 라이브러리(security@chromium.org에서 감"
|
|
"사)"
|
|
|
|
#: src/chromium/cargo.md
|
|
msgid "Other Rust libraries (some niche, some quite popular and commonly used)"
|
|
msgstr ""
|
|
"기타 Rust 라이브러리(일부는 틈새시장용, 일부는 매우 인기 있으며 흔히 사용됨)"
|
|
|
|
#: src/chromium/policy.md
|
|
msgid "Chromium Rust policy"
|
|
msgstr "Chromium Rust 정책"
|
|
|
|
#: src/chromium/policy.md
|
|
msgid ""
|
|
"Chromium does not yet allow first-party Rust except in rare cases as "
|
|
"approved by Chromium's [Area Tech Leads](https://source.chromium.org/"
|
|
"chromium/chromium/src/+/main:ATL_OWNERS)."
|
|
msgstr ""
|
|
"Chromium에서는 아직 퍼스트 파티 Rust를 허용하지 않습니다. 단, Chromium의 "
|
|
"[Area Tech Leads](https://source.chromium.org/chromium/chromium/src/+/main:"
|
|
"ATL_OWNERS)에서 승인한 드문 경우는 예외입니다."
|
|
|
|
#: src/chromium/policy.md
|
|
msgid ""
|
|
"Chromium's policy on third party libraries is outlined [here](https://"
|
|
"chromium.googlesource.com/chromium/src/+/main/docs/adding_to_third_party."
|
|
"md#rust) - Rust is allowed for third party libraries under various "
|
|
"circumstances, including if they're the best option for performance or for "
|
|
"security."
|
|
msgstr ""
|
|
"서드 파티 라이브러리에 관한 Chromium의 정책은 [여기](https://chromium."
|
|
"googlesource.com/chromium/src/+/main/docs/adding_to_third_party.md#rust)에 설"
|
|
"명되어 있습니다. Rust는 성능이나 보안을 위해 최상의 옵션인 경우 등 다양한 상"
|
|
"황에서 서드 파티 라이브러리에 허용됩니다."
|
|
|
|
#: src/chromium/policy.md
|
|
msgid ""
|
|
"Very few Rust libraries directly expose a C/C++ API, so that means that "
|
|
"nearly all such libraries will require a small amount of first-party glue "
|
|
"code."
|
|
msgstr ""
|
|
"C/C++ API를 직접 노출하는 Rust 라이브러리는 극소수이므로 이러한 거의 모든 라"
|
|
"이브러리에는 소량의 퍼스트 파티 글루 코드가 필요합니다."
|
|
|
|
#: src/chromium/policy.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"```bob\n"
|
|
"\"C++\" Rust\n"
|
|
".- - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - - - - "
|
|
"-.\n"
|
|
": : : :\n"
|
|
": Existing Chromium : : Chromium Rust Existing "
|
|
"Rust :\n"
|
|
": \"C++\" : : \"wrapper\" "
|
|
"crate :\n"
|
|
": +---------------+ : : +----------------+ +-------------"
|
|
"+ :\n"
|
|
": | | : : | | | "
|
|
"| :\n"
|
|
": | o-----+-+-----------+-+-> o-+----------+--> "
|
|
"| :\n"
|
|
": | | : Language : | | Crate | "
|
|
"| :\n"
|
|
": +---------------+ : boundary : +----------------+ API +-------------"
|
|
"+ :\n"
|
|
": : : :\n"
|
|
"`- - - - - - - - - -' `- - - - - - - - - - - - - - - - - - - - - - "
|
|
"-'\n"
|
|
"```"
|
|
msgstr ""
|
|
"```bob\n"
|
|
" 스택 힙\n"
|
|
".- - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - - - - "
|
|
"-.\n"
|
|
": : : :\n"
|
|
": "
|
|
"list : : :\n"
|
|
": +----+----+ : : +----+----+ +----+------"
|
|
"+ :\n"
|
|
": | 1 | o--+-----------+-----+--->| 2 | o--+--->| // | null "
|
|
"| :\n"
|
|
": +----+----+ : : +----+----+ +----+------"
|
|
"+ :\n"
|
|
": : : :\n"
|
|
": : : :\n"
|
|
"`- - - - - - - - - - - - -' '- - - - - - - - - - - - - - - - - - - - - - "
|
|
"-'\n"
|
|
"```"
|
|
|
|
#: src/chromium/policy.md
|
|
msgid ""
|
|
"First-party Rust glue code for a particular third-party crate should "
|
|
"normally be kept in `third_party/rust/<crate>/<version>/wrapper`."
|
|
msgstr ""
|
|
"특정 서드 파티 크레이트의 퍼스트 파티 Rust 글루 코드는 일반적으로 "
|
|
"`third_party/rust/<crate>/<version>/wrapper`에 보관해야 합니다."
|
|
|
|
#: src/chromium/policy.md
|
|
msgid "Because of this, today's course will be heavily focused on:"
|
|
msgstr "따라서 오늘 과정에서는 다음과 같은 내용을 중점적으로 다룹니다."
|
|
|
|
#: src/chromium/policy.md
|
|
msgid "Bringing in third-party Rust libraries (\"crates\")"
|
|
msgstr "서드 파티 Rust 라이브러리('crates') 가져오기"
|
|
|
|
#: src/chromium/policy.md
|
|
msgid "Writing glue code to be able to use those crates from Chromium C++."
|
|
msgstr ""
|
|
"Chromium C++에서 이러한 크레이트를 사용할 수 있도록 글루 코드를 작성합니다."
|
|
|
|
#: src/chromium/policy.md
|
|
msgid "If this policy changes over time, the course will evolve to keep up."
|
|
msgstr "시간이 지나면서 이 정책이 변경되면 교육 과정도 이에 맞게 변경됩니다."
|
|
|
|
#: src/chromium/build-rules.md
|
|
msgid "Build rules"
|
|
msgstr "빌드 규칙"
|
|
|
|
#: src/chromium/build-rules.md
|
|
msgid ""
|
|
"Rust code is usually built using `cargo`. Chromium builds with `gn` and "
|
|
"`ninja` for efficiency --- its static rules allow maximum parallelism. Rust "
|
|
"is no exception."
|
|
msgstr ""
|
|
"Rust 코드는 일반적으로 `cargo`를 사용하여 빌드됩니다. Chromium은 효율성을 위"
|
|
"해 `gn` 및 `ninja`로 빌드됩니다. 정적 규칙은 최대 동시 로드를 허용합니다. "
|
|
"Rust도 예외는 아닙니다."
|
|
|
|
#: src/chromium/build-rules.md
|
|
msgid "Adding Rust code to Chromium"
|
|
msgstr "Chromium에 Rust 코드 추가"
|
|
|
|
#: src/chromium/build-rules.md
|
|
msgid ""
|
|
"In some existing Chromium `BUILD.gn` file, declare a `rust_static_library`:"
|
|
msgstr ""
|
|
"일부 기존 Chromium `BUILD.gn` 파일에서 `rust_static_library`를 선언합니다."
|
|
|
|
#: src/chromium/build-rules.md
|
|
msgid ""
|
|
"```gn\n"
|
|
"import(\"//build/rust/rust_static_library.gni\")\n"
|
|
"\n"
|
|
"rust_static_library(\"my_rust_lib\") {\n"
|
|
" crate_root = \"lib.rs\"\n"
|
|
" sources = [ \"lib.rs\" ]\n"
|
|
"}\n"
|
|
"```"
|
|
msgstr ""
|
|
"```gn\n"
|
|
"import(\"//build/rust/rust_static_library.gni\")\n"
|
|
"\n"
|
|
"rust_static_library(\"my_rust_lib\") {\n"
|
|
" crate_root = \"lib.rs\"\n"
|
|
" sources = [ \"lib.rs\" ]\n"
|
|
"}\n"
|
|
"```"
|
|
|
|
#: src/chromium/build-rules.md
|
|
msgid ""
|
|
"You can also add `deps` on other Rust targets. Later we'll use this to "
|
|
"depend upon third party code."
|
|
msgstr ""
|
|
"다른 Rust 타겟에도 `deps`를 추가할 수 있습니다. 나중에 서드 파티 코드에 의존"
|
|
"하기 위해 이를 사용합니다."
|
|
|
|
#: src/chromium/build-rules.md
|
|
msgid ""
|
|
"You must specify _both_ the crate root, _and_ a full list of sources. The "
|
|
"`crate_root` is the file given to the Rust compiler representing the root "
|
|
"file of the compilation unit --- typically `lib.rs`. `sources` is a complete "
|
|
"list of all source files which `ninja` needs in order to determine when "
|
|
"rebuilds are necessary."
|
|
msgstr ""
|
|
"크레이트 루트 _및_ 소스 전체 목록 _둘 다_를 지정해야 합니다. `crate_root`는 "
|
|
"컴파일 단위의 루트 파일(일반적으로 `lib.rs`)을 나타내는 Rust 컴파일러에 제공"
|
|
"되는 파일입니다. `sources`는 재빌드가 필요한 시점을 결정하기 위해 `ninja`에 "
|
|
"필요한 모든 소스 파일의 전체 목록입니다."
|
|
|
|
#: src/chromium/build-rules.md
|
|
msgid ""
|
|
"(There's no such thing as a Rust `source_set`, because in Rust, an entire "
|
|
"crate is a compilation unit. A `static_library` is the smallest unit.)"
|
|
msgstr ""
|
|
"(Rust에서는 크레이트 전체가 컴파일 단위이므로 Rust `source_set`와 같은 것은 "
|
|
"없습니다. `static_library`가 최소 단위입니다.)"
|
|
|
|
#: src/chromium/build-rules.md
|
|
msgid ""
|
|
"Students might be wondering why we need a gn template, rather than using "
|
|
"[gn's built-in support for Rust static libraries](https://gn.googlesource."
|
|
"com/gn/+/main/docs/reference.md#func_static_library). The answer is that "
|
|
"this template provides support for CXX interop, Rust features, and unit "
|
|
"tests, some of which we'll use later."
|
|
msgstr ""
|
|
"학생들은 [gn의 내장 Rust 정적 라이브러리 지원](https://gn.googlesource.com/"
|
|
"gn/+/main/docs/reference.md#func_static_library)을 사용하는 대신 gn 템플릿이 "
|
|
"필요한 이유를 궁금해할 수 있습니다. 대답은 이 템플릿이 CXX 상호 운용성, Rust "
|
|
"기능, 단위 테스트를 지원한다는 것입니다. 이 중 일부는 나중에 사용하게 됩니다."
|
|
|
|
#: src/chromium/build-rules/unsafe.md
|
|
msgid "Including `unsafe` Rust Code"
|
|
msgstr "`unsafe` Rust 코드 포함"
|
|
|
|
#: src/chromium/build-rules/unsafe.md
|
|
msgid ""
|
|
"Unsafe Rust code is forbidden in `rust_static_library` by default --- it "
|
|
"won't compile. If you need unsafe Rust code, add `allow_unsafe = true` to "
|
|
"the gn target. (Later in the course we'll see circumstances where this is "
|
|
"necessary.)"
|
|
msgstr ""
|
|
"`rust_static_library`에는 안전하지 않은 Rust 코드가 기본적으로 금지되어 있으"
|
|
"므로 컴파일되지 않습니다. 안전하지 않은 Rust 코드가 필요하면 gn 타겟에 "
|
|
"`allow_unsafe = true`를 추가하세요. (이 과정의 후반부에 이것이 필요한 상황을 "
|
|
"살펴봅니다.)"
|
|
|
|
#: src/chromium/build-rules/unsafe.md
|
|
msgid ""
|
|
"```gn\n"
|
|
"import(\"//build/rust/rust_static_library.gni\")\n"
|
|
"\n"
|
|
"rust_static_library(\"my_rust_lib\") {\n"
|
|
" crate_root = \"lib.rs\"\n"
|
|
" sources = [\n"
|
|
" \"lib.rs\",\n"
|
|
" \"hippopotamus.rs\"\n"
|
|
" ]\n"
|
|
" allow_unsafe = true\n"
|
|
"}\n"
|
|
"```"
|
|
msgstr ""
|
|
"```gn\n"
|
|
"import(\"//build/rust/rust_static_library.gni\")\n"
|
|
"\n"
|
|
"rust_static_library(\"my_rust_lib\") {\n"
|
|
" crate_root = \"lib.rs\"\n"
|
|
" sources = [\n"
|
|
" \"lib.rs\",\n"
|
|
" \"hippopotamus.rs\"\n"
|
|
" ]\n"
|
|
" allow_unsafe = true\n"
|
|
"}\n"
|
|
"```"
|
|
|
|
#: src/chromium/build-rules/depending.md
|
|
msgid "Simply add the above target to the `deps` of some Chromium C++ target."
|
|
msgstr "위의 타겟을 일부 Chromium C++ 타겟의 `deps`에 추가하기만 하면 됩니다."
|
|
|
|
#: src/chromium/build-rules/depending.md
|
|
msgid ""
|
|
"```gn\n"
|
|
"import(\"//build/rust/rust_static_library.gni\")\n"
|
|
"\n"
|
|
"rust_static_library(\"my_rust_lib\") {\n"
|
|
" crate_root = \"lib.rs\"\n"
|
|
" sources = [ \"lib.rs\" ]\n"
|
|
"}\n"
|
|
"\n"
|
|
"# or source_set, static_library etc.\n"
|
|
"component(\"preexisting_cpp\") {\n"
|
|
" deps = [ \":my_rust_lib\" ]\n"
|
|
"}\n"
|
|
"```"
|
|
msgstr ""
|
|
"```gn\n"
|
|
"import(\"//build/rust/rust_static_library.gni\")\n"
|
|
"\n"
|
|
"rust_static_library(\"my_rust_lib\") {\n"
|
|
" crate_root = \"lib.rs\"\n"
|
|
" sources = [ \"lib.rs\" ]\n"
|
|
"}\n"
|
|
"\n"
|
|
"# or source_set, static_library etc.\n"
|
|
"component(\"preexisting_cpp\") {\n"
|
|
" deps = [ \":my_rust_lib\" ]\n"
|
|
"}\n"
|
|
"```"
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid ""
|
|
"Types are elided in Rust code, which makes a good IDE even more useful than "
|
|
"for C++. Visual Studio code works well for Rust in Chromium. To use it,"
|
|
msgstr ""
|
|
"Rust 코드에서는 타입이 생략되므로 우수한 IDE가 C++보다 훨씬 더 유용해집니다. "
|
|
"Visual Studio Code는 Chromium의 Rust에서 잘 작동합니다. 사용하려면 다음을 실"
|
|
"행합니다."
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid ""
|
|
"Ensure your VSCode has the `rust-analyzer` extension, not earlier forms of "
|
|
"Rust support"
|
|
msgstr ""
|
|
"VSCode에 이전 형태의 Rust 지원이 아닌 `rust-analyzer` 확장 프로그램이 있는지 "
|
|
"확인하세요."
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid ""
|
|
"`gn gen out/Debug --export-rust-project` (or equivalent for your output "
|
|
"directory)"
|
|
msgstr "`gn gen out/Debug --export-rust-project`(또는 출력 디렉터리에 상응)"
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid "`ln -s out/Debug/rust-project.json rust-project.json`"
|
|
msgstr "`ln -s out/Debug/rust-project.json rust-project.json`"
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid ""
|
|
"A demo of some of the code annotation and exploration features of rust-"
|
|
"analyzer might be beneficial if the audience are naturally skeptical of IDEs."
|
|
msgstr ""
|
|
"누군가가 IDE에 대해 회의적인 경우 rust-analyzer의 코드 주석 및 탐색 기능 중 "
|
|
"일부를 시연해 보면 생각을 바꾸는데 유용할 수 있습니다."
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid ""
|
|
"The following steps may help with the demo (but feel free to instead use a "
|
|
"piece of Chromium-related Rust that you are most familiar with):"
|
|
msgstr ""
|
|
"다음 단계는 데모에 도움이 될 수 있습니다. 하지만 가장 익숙한 Chromium 관련 "
|
|
"Rust를 대신 사용해도 됩니다."
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid "Open `components/qr_code_generator/qr_code_generator_ffi_glue.rs`"
|
|
msgstr "`components/qr_code_generator/qr_code_generator_ffi_glue.rs`를 엽니다."
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid ""
|
|
"Place the cursor over the `QrCode::new` call (around line 26) in "
|
|
"\\`qr_code_generator_ffi_glue.rs"
|
|
msgstr ""
|
|
"커서를 `qr_code_generator_ffi_glue.rs의 \\`QrCode::new` 호출(26번 줄 부근) 위"
|
|
"로 이동합니다."
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid ""
|
|
"Demo **show documentation** (typical bindings: vscode = ctrl k i; vim/CoC = "
|
|
"K)."
|
|
msgstr "데모 **문서 표시**(일반적인 바인딩: vscode = ctrl k i; vim/CoC = K)"
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid ""
|
|
"Demo **go to definition** (typical bindings: vscode = F12; vim/CoC = g d). "
|
|
"(This will take you to `//third_party/rust/.../qr_code-.../src/lib.rs`.)"
|
|
msgstr ""
|
|
"데모 **정의로 이동**(일반적인 바인딩: vscode = F12; vim/CoC = g d) 그러면 "
|
|
"`//third_party/rust/.../qr_code-.../src/lib.rs`로 이동합니다."
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid ""
|
|
"Demo **outline** and navigate to the `QrCode::with_bits` method (around line "
|
|
"164; the outline is in the file explorer pane in vscode; typical vim/CoC "
|
|
"bindings = space o)"
|
|
msgstr ""
|
|
"**개요** 데모를 실행하고 `QrCode::with_bits` 메서드(164번 줄 근처, 개요는 "
|
|
"vscode의 파일 탐색기 창에 있음, 일반적인 vim/CoC 바인딩 = space o)로 이동합니"
|
|
"다."
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid ""
|
|
"Demo **type annotations** (there are quote a few nice examples in the "
|
|
"`QrCode::with_bits` method)"
|
|
msgstr ""
|
|
"데모 **유형 주석**(`QrCode::with_bits` 메서드에 몇 가지 좋은 예가 있음)"
|
|
|
|
#: src/chromium/build-rules/vscode.md
|
|
msgid ""
|
|
"It may be worth pointing out that `gn gen ... --export-rust-project` will "
|
|
"need to be rerun after editing `BUILD.gn` files (which we will do a few "
|
|
"times throughout the exercises in this session)."
|
|
msgstr ""
|
|
"`BUILD.gn` 파일을 수정한 후 `gn gen ... --export-rust-project`를 다시 실행해"
|
|
"야 한다는 점은 주목할 필요가 있습니다. 이 작업은 이 세션의 연습 전반에 걸쳐 "
|
|
"몇 번 반복하게 됩니다."
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid "Build rules exercise"
|
|
msgstr "빌드 규칙"
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"In your Chromium build, add a new Rust target to `//ui/base/BUILD.gn` "
|
|
"containing:"
|
|
msgstr ""
|
|
"Chromium 빌드에서 다음을 포함하는 `//ui/base/BUILD.gn`에 새 Rust 타겟을 추가"
|
|
"합니다."
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"**Important**: note that `no_mangle` here is considered a type of unsafety "
|
|
"by the Rust compiler, so you'll need to allow unsafe code in your `gn` "
|
|
"target."
|
|
msgstr ""
|
|
"**중요**: 여기서 `no_mangle`은 Rust 컴파일러에 의해 안전하지 않은 유형으로 간"
|
|
"주되므로 `gn` 타겟에서 안전하지 않은 코드를 허용해야 합니다."
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"Add this new Rust target as a dependency of `//ui/base:base`. Declare this "
|
|
"function at the top of `ui/base/resource/resource_bundle.cc` (later, we'll "
|
|
"see how this can be automated by bindings generation tools):"
|
|
msgstr ""
|
|
"이 새로운 Rust 타겟을 `//ui/base:base`의 종속 항목으로 추가합니다. 이 함수를 "
|
|
"`ui/base/resource/resource_bundle.cc`의 맨 위에서 선언합니다. 나중에 바인딩 "
|
|
"생성 도구로 자동화하는 방법을 살펴봅니다."
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"Call this function from somewhere in `ui/base/resource/resource_bundle.cc` - "
|
|
"we suggest the top of `ResourceBundle::MaybeMangleLocalizedString`. Build "
|
|
"and run Chromium, and ensure that \"Hello from Rust!\" is printed lots of "
|
|
"times."
|
|
msgstr ""
|
|
"`ui/base/resource/resource_bundle.cc`의 어딘가에서 이 함수를 호출합니다. "
|
|
"`ResourceBundle::MaybeMangleLocalizedString`의 상단이 좋습니다. Chromium을 빌"
|
|
"드하고 실행하여 'Hello from Rust!'가 여러 번 출력되는지 확인합니다."
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"If you use VSCode, now set up Rust to work well in VSCode. It will be useful "
|
|
"in subsequent exercises. If you've succeeded, you will be able to use right-"
|
|
"click \"Go to definition\" on `println!`."
|
|
msgstr ""
|
|
"VSCode를 사용하는 경우 이제 VSCode에서 잘 작동하도록 Rust를 설정합니다. 이후 "
|
|
"연습에서 유용합니다. 성공하면 `println!`에서 '정의로 이동'을 마우스 오른쪽 버"
|
|
"튼으로 클릭할 수 있습니다."
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "Where to find help"
|
|
msgstr "도움을 받을 수 있는 곳"
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"The options available to the [`rust_static_library` gn template](https://"
|
|
"source.chromium.org/chromium/chromium/src/+/main:build/rust/"
|
|
"rust_static_library.gni;l=16)"
|
|
msgstr ""
|
|
"[`rust_static_library` gn 템플릿](https://source.chromium.org/chromium/"
|
|
"chromium/src/+/main:build/rust/rust_static_library.gni;l=16)에서 사용 가능한 "
|
|
"옵션"
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"Information about [`#[no_mangle]`](https://doc.rust-lang.org/beta/reference/"
|
|
"abi.html#the-no_mangle-attribute)"
|
|
msgstr ""
|
|
"[`#[no_mangle]`](https://doc.rust-lang.org/beta/reference/abi.html#the-"
|
|
"no_mangle-attribute)에 관한 정보"
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"Information about [`extern \"C\"`](https://doc.rust-lang.org/std/keyword."
|
|
"extern.html)"
|
|
msgstr ""
|
|
"[`extern \"C\"`](https://doc.rust-lang.org/std/keyword.extern.html)에 관한 정"
|
|
"보"
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"Information about gn's [`--export-rust-project`](https://gn.googlesource.com/"
|
|
"gn/+/main/docs/reference.md#compilation-database) switch"
|
|
msgstr ""
|
|
"gn의 [`--export-rust-project`](https://gn.googlesource.com/gn/+/main/docs/"
|
|
"reference.md#compilation-database) 전환 정보"
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"[How to install rust-analyzer in VSCode](https://code.visualstudio.com/docs/"
|
|
"languages/rust)"
|
|
msgstr ""
|
|
"[VSCode에서 rust-analyzer를 설치하는 방법](https://code.visualstudio.com/"
|
|
"docs/languages/rust)"
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"This example is unusual because it boils down to the lowest-common-"
|
|
"denominator interop language, C. Both C++ and Rust can natively declare and "
|
|
"call C ABI functions. Later in the course, we'll connect C++ directly to "
|
|
"Rust."
|
|
msgstr ""
|
|
"이 예는 최소 공통분모 상호 운용성 언어인 C로 귀결되기 때문에 일반적이지 않습"
|
|
"니다. C++와 Rust 모두 기본적으로 C ABI 함수를 선언하고 호출할 수 있습니다. "
|
|
"이 과정의 후반부에서 C++를 Rust에 직접 연결합니다."
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"`allow_unsafe = true` is required here because `#[no_mangle]` might allow "
|
|
"Rust to generate two functions with the same name, and Rust can no longer "
|
|
"guarantee that the right one is called."
|
|
msgstr ""
|
|
"여기서 `allow_unsafe = true`가 필요한 이유는 `#[no_mangle]`이 Rust가 이름이 "
|
|
"같은 함수 두 개를 생성할 수 있도록 할 수 있고 Rust는 더 이상 올바른 함수가 호"
|
|
"출된다고 보장할 수 없기 때문입니다."
|
|
|
|
#: src/exercises/chromium/build-rules.md
|
|
msgid ""
|
|
"If you need a pure Rust executable, you can also do that using the "
|
|
"`rust_executable` gn template."
|
|
msgstr ""
|
|
"순수한 Rust 실행 파일이 필요하면 `rust_executable` gn 템플릿을 사용하면 됩니"
|
|
"다."
|
|
|
|
#: src/chromium/testing.md
|
|
msgid ""
|
|
"Rust community typically authors unit tests in a module placed in the same "
|
|
"source file as the code being tested. This was covered [earlier](../testing."
|
|
"md) in the course and looks like this:"
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing.md
|
|
msgid ""
|
|
"In Chromium we place unit tests in a separate source file and we continue to "
|
|
"follow this practice for Rust --- this makes tests consistently discoverable "
|
|
"and helps to avoid rebuilding `.rs` files a second time (in the `test` "
|
|
"configuration)."
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing.md
|
|
msgid ""
|
|
"This results in the following options for testing Rust code in Chromium:"
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing.md
|
|
msgid ""
|
|
"Native Rust tests (i.e. `#[test]`). Discouraged outside of `//third_party/"
|
|
"rust`."
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing.md
|
|
msgid ""
|
|
"`gtest` tests authored in C++ and exercising Rust via FFI calls. Sufficient "
|
|
"when Rust code is just a thin FFI layer and the existing unit tests provide "
|
|
"sufficient coverage for the feature."
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing.md
|
|
msgid ""
|
|
"`gtest` tests authored in Rust and using the crate under test through its "
|
|
"public API (using `pub mod for_testing { ... }` if needed). This is the "
|
|
"subject of the next few slides."
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing.md
|
|
msgid ""
|
|
"Mention that native Rust tests of third-party crates should eventually be "
|
|
"exercised by Chromium bots. (Such testing is needed rarely --- only after "
|
|
"adding or updating third-party crates.)"
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing.md
|
|
msgid ""
|
|
"Some examples may help illustrate when C++ `gtest` vs Rust `gtest` should be "
|
|
"used:"
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing.md
|
|
msgid ""
|
|
"QR has very little functionality in the first-party Rust layer (it's just a "
|
|
"thin FFI glue) and therefore uses the existing C++ unit tests for testing "
|
|
"both the C++ and the Rust implementation (parameterizing the tests so they "
|
|
"enable or disable Rust using a `ScopedFeatureList`)."
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing.md
|
|
msgid ""
|
|
"Hypothetical/WIP PNG integration may need to implement memory-safe "
|
|
"implementation of pixel transformations that are provided by `libpng` but "
|
|
"missing in the `png` crate - e.g. RGBA => BGRA, or gamma correction. Such "
|
|
"functionality may benefit from separate tests authored in Rust."
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing/rust-gtest-interop.md
|
|
msgid ""
|
|
"The [`rust_gtest_interop`](https://chromium.googlesource.com/chromium/src/+/"
|
|
"main/testing/rust_gtest_interop/README.md) library provides a way to:"
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing/rust-gtest-interop.md
|
|
msgid ""
|
|
"Use a Rust function as a `gtest` testcase (using the `#[gtest(...)]` "
|
|
"attribute)"
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing/rust-gtest-interop.md
|
|
msgid ""
|
|
"Use `expect_eq!` and similar macros (similar to `assert_eq!` but not "
|
|
"panicking and not terminating the test when the assertion fails)."
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing/rust-gtest-interop.md
|
|
#, fuzzy
|
|
msgid "Example:"
|
|
msgstr "예제"
|
|
|
|
#: src/chromium/testing/build-gn.md
|
|
msgid ""
|
|
"The simplest way to build Rust `gtest` tests is to add them to an existing "
|
|
"test binary that already contains tests authored in C++. For example:"
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing/build-gn.md
|
|
msgid ""
|
|
"```gn\n"
|
|
"test(\"ui_base_unittests\") {\n"
|
|
" ...\n"
|
|
" sources += [ \"my_rust_lib_unittest.rs\" ]\n"
|
|
" deps += [ \":my_rust_lib\" ]\n"
|
|
"}\n"
|
|
"```"
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing/build-gn.md
|
|
msgid ""
|
|
"Authoring Rust tests in a separate `static_library` also works, but requires "
|
|
"manually declaring the dependency on the support libraries:"
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing/build-gn.md
|
|
msgid ""
|
|
"```gn\n"
|
|
"rust_static_library(\"my_rust_lib_unittests\") {\n"
|
|
" testonly = true\n"
|
|
" is_gtest_unittests = true\n"
|
|
" crate_root = \"my_rust_lib_unittest.rs\"\n"
|
|
" sources = [ \"my_rust_lib_unittest.rs\" ]\n"
|
|
" deps = [\n"
|
|
" \":my_rust_lib\",\n"
|
|
" \"//testing/rust_gtest_interop\",\n"
|
|
" ]\n"
|
|
"}\n"
|
|
"\n"
|
|
"test(\"ui_base_unittests\") {\n"
|
|
" ...\n"
|
|
" deps += [ \":my_rust_lib_unittests\" ]\n"
|
|
"}\n"
|
|
"```"
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing/chromium-import-macro.md
|
|
msgid ""
|
|
"After adding `:my_rust_lib` to GN `deps`, we still need to learn how to "
|
|
"import and use `my_rust_lib` from `my_rust_lib_unittest.rs`. We haven't "
|
|
"provided an explicit `crate_name` for `my_rust_lib` so its crate name is "
|
|
"computed based on the full target path and name. Fortunately we can avoid "
|
|
"working with such an unwieldy name by using the `chromium::import!` macro "
|
|
"from the automatically-imported `chromium` crate:"
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing/chromium-import-macro.md
|
|
#, fuzzy
|
|
msgid "\"//ui/base:my_rust_lib\""
|
|
msgstr "'ui/base/my_rust_file.rs.h'"
|
|
|
|
#: src/chromium/testing/chromium-import-macro.md
|
|
msgid "Under the covers the macro expands to something similar to:"
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing/chromium-import-macro.md
|
|
msgid ""
|
|
"More information can be found in [the doc comment](https://source.chromium."
|
|
"org/chromium/chromium/src/+/main:build/rust/chromium_prelude/"
|
|
"chromium_prelude.rs?q=f:chromium_prelude.rs%20pub.use.*%5Cbimport%5Cb;%20-f:"
|
|
"third_party&ss=chromium%2Fchromium%2Fsrc) of the `chromium::import` macro."
|
|
msgstr ""
|
|
|
|
#: src/chromium/testing/chromium-import-macro.md
|
|
msgid ""
|
|
"`rust_static_library` supports specifying an explicit name via `crate_name` "
|
|
"property, but doing this is discouraged. And it is discouraged because the "
|
|
"crate name has to be globally unique. crates.io guarantees uniqueness of its "
|
|
"crate names so `cargo_crate` GN targets (generated by the `gnrt` tool "
|
|
"covered in a later section) use short crate names."
|
|
msgstr ""
|
|
|
|
#: src/exercises/chromium/testing.md
|
|
#, fuzzy
|
|
msgid "Testing exercise"
|
|
msgstr "Rust on Exercism"
|
|
|
|
#: src/exercises/chromium/testing.md
|
|
msgid "Time for another exercise!"
|
|
msgstr "새로운 연습문제를 풀어봅시다!"
|
|
|
|
#: src/exercises/chromium/testing.md
|
|
msgid "In your Chromium build:"
|
|
msgstr ""
|
|
|
|
#: src/exercises/chromium/testing.md
|
|
msgid ""
|
|
"Add a testable function next to `hello_from_rust`. Some suggestions: adding "
|
|
"two integers received as arguments, computing the nth Fibonacci number, "
|
|
"summing integers in a slice, etc."
|
|
msgstr ""
|
|
|
|
#: src/exercises/chromium/testing.md
|
|
msgid "Add a separate `..._unittest.rs` file with a test for the new function."
|
|
msgstr ""
|
|
|
|
#: src/exercises/chromium/testing.md
|
|
msgid "Add the new tests to `BUILD.gn`."
|
|
msgstr ""
|
|
|
|
#: src/exercises/chromium/testing.md
|
|
msgid "Build the tests, run them, and verify that the new test works."
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"The Rust community offers multiple options for C++/Rust interop, with new "
|
|
"tools being developed all the time. At the moment, Chromium uses a tool "
|
|
"called CXX."
|
|
msgstr ""
|
|
"Rust 커뮤니티는 C++/Rust 상호 운용성을 위한 여러 옵션을 제공하며, 새로운 도구"
|
|
"가 계속 개발되고 있습니다. 현재 Chromium은 CXX라는 도구를 사용합니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"You describe your whole language boundary in an interface definition "
|
|
"language (which looks a lot like Rust) and then CXX tools generate "
|
|
"declarations for functions and types in both Rust and C++."
|
|
msgstr ""
|
|
"인터페이스 정의 언어(Rust와 매우 유사함)에서 전체 언어 경계를 설명하면 CXX 도"
|
|
"구가 Rust 및 C++ 모두에서 함수와 유형에 관한 선언을 생성합니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"See the [CXX tutorial](https://cxx.rs/tutorial.html) for a full example of "
|
|
"using this."
|
|
msgstr ""
|
|
"사용하는 방법에 대해서는[CXX 튜토리얼](https://cxx.rs/tutorial.html) 를 참조"
|
|
"합니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"Talk through the diagram. Explain that behind the scenes, this is doing just "
|
|
"the same as you previously did. Point out that automating the process has "
|
|
"the following benefits:"
|
|
msgstr ""
|
|
"다이어그램을 통해 설명합니다. 내부적으로는 이전과 동일한 작업을 실행한다고 설"
|
|
"명합니다. 프로세스를 자동화하면 다음과 같은 이점이 있습니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"The tool guarantees that the C++ and Rust sides match (e.g. you get compile "
|
|
"errors if the `#[cxx::bridge]` doesn't match the actual C++ or Rust "
|
|
"definitions, but with out-of-sync manual bindings you'd get Undefined "
|
|
"Behavior)"
|
|
msgstr ""
|
|
"이 도구는 C++와 Rust 측의 일치를 보장합니다. 예를 들어 `#[cxx::bridge]`가 실"
|
|
"제 C++ 또는 Rust 정의와 일치하지 않는 경우 컴파일 오류가 발생하지만 동기화되"
|
|
"지 않은 수동 바인딩을 사용하면 정의되지 않은 동작이 발생합니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"The tool automates generation of FFI thunks (small, C-ABI-compatible, free "
|
|
"functions) for non-C features (e.g. enabling FFI calls into Rust or C++ "
|
|
"methods; manual bindings would require authoring such top-level, free "
|
|
"functions manually)"
|
|
msgstr ""
|
|
"이 도구는 비 C 기능의 FFI thunk(소형, C-ABI 호환, 무료 함수) 생성을 자동화합"
|
|
"니다(예: Rust 또는 C++ 메서드에 대한 FFI 호출 사용 설정, 수동 바인딩의 경우 "
|
|
"이러한 최상위 무료 함수를 수동으로 작성해야 함)."
|
|
|
|
#: src/chromium/interoperability-with-cpp.md
|
|
msgid "The tool and the library can handle a set of core types - for example:"
|
|
msgstr ""
|
|
"도구와 라이브러리는 핵심 유형 집합을 처리할 수 있습니다. 예를 들면 다음과 같"
|
|
"습니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"`&[T]` can be passed across the FFI boundary, even though it doesn't "
|
|
"guarantee any particular ABI or memory layout. With manual bindings `std::"
|
|
"span<T>` / `&[T]` have to be manually destructured and rebuilt out of a "
|
|
"pointer and length - this is error-prone given that each language represents "
|
|
"empty slices slightly differently)"
|
|
msgstr ""
|
|
"`&[T]`는 특정 ABI나 메모리 레이아웃을 보장하지 않더라도 FFI 경계를 넘어 전달"
|
|
"될 수 있습니다. 수동 바인딩을 사용하면 `std::span<T>` / `&[T]`는 수동으로 디"
|
|
"스트럭처링해야 하고 포인터와 길이로 다시 빌드해야 합니다. 이는 각 언어가 빈 "
|
|
"슬라이스를 약간 다르게 표현하는 점을 고려할 때 오류가 발생하기 쉽습니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"Smart pointers like `std::unique_ptr<T>`, `std::shared_ptr<T>`, and/or `Box` "
|
|
"are natively supported. With manual bindings, one would have to pass C-ABI-"
|
|
"compatible raw pointers, which would increase lifetime and memory-safety "
|
|
"risks."
|
|
msgstr ""
|
|
"`std::unique_ptr<T>`, `std::shared_ptr<T>`, `Box` 등의 스마트 포인터가 기본적"
|
|
"으로 지원됩니다. 수동 바인딩을 사용하면 C-ABI 호환 원시 포인터를 전달해야 하"
|
|
"므로 전체 기간 및 메모리 안전 위험이 증가합니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"`rust::String` and `CxxString` types understand and maintain differences in "
|
|
"string representation across the languages (e.g. `rust::String::lossy` can "
|
|
"build a Rust string from non-UTF8 input and `rust::String::c_str` can NUL-"
|
|
"terminate a string)."
|
|
msgstr ""
|
|
"`rust::String` 및 `CxxString` 유형은 언어 간 문자열 표현의 차이를 이해하고 유"
|
|
"지합니다. 예를 들어 `rust::String::lossy`는 UTF8이 아닌 입력에서 Rust 문자열"
|
|
"을 빌드할 수 있고 `rust::String::c_str`은 문자열을 NUL 종료할 수 있습니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/example-bindings.md
|
|
msgid ""
|
|
"CXX requires that the whole C++/Rust boundary is declared in `cxx::bridge` "
|
|
"modules inside `.rs` source code."
|
|
msgstr ""
|
|
"CXX에서는 전체 C++/Rust 경계가 `.rs` 소스 코드 내의 `cxx::bridge` "
|
|
"'modules'에 선언되어야 합니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/example-bindings.md
|
|
msgid "\"example/include/blobstore.h\""
|
|
msgstr "\"example/include/blobstore.h\""
|
|
|
|
#: src/chromium/interoperability-with-cpp/example-bindings.md
|
|
msgid "// Definitions of Rust types and functions go here\n"
|
|
msgstr "// Rust 유형 및 함수의 정의는 여기를 참고하세요.\n"
|
|
|
|
#: src/chromium/interoperability-with-cpp/example-bindings.md
|
|
msgid "Point out:"
|
|
msgstr "참고:"
|
|
|
|
#: src/chromium/interoperability-with-cpp/example-bindings.md
|
|
msgid ""
|
|
"Although this looks like a regular Rust `mod`, the `#[cxx::bridge]` "
|
|
"procedural macro does complex things to it. The generated code is quite a "
|
|
"bit more sophisticated - though this does still result in a `mod` called "
|
|
"`ffi` in your code."
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/example-bindings.md
|
|
msgid "Native support for C++'s `std::unique_ptr` in Rust"
|
|
msgstr "Rust에서 C++'의 `std::unique_ptr` 기본 지원"
|
|
|
|
#: src/chromium/interoperability-with-cpp/example-bindings.md
|
|
#, fuzzy
|
|
msgid "Native support for Rust slices in C++"
|
|
msgstr "Rust에서 C++'의 `std::unique_ptr` 기본 지원"
|
|
|
|
#: src/chromium/interoperability-with-cpp/example-bindings.md
|
|
msgid "Calls from C++ to Rust, and Rust types (in the top part)"
|
|
msgstr "C++에서 Rust 호출 및 Rust 유형(상단)"
|
|
|
|
#: src/chromium/interoperability-with-cpp/example-bindings.md
|
|
msgid "Calls from Rust to C++, and C++ types (in the bottom part)"
|
|
msgstr "Rust에서 C++ 호출 및 C++ 유형(하단)"
|
|
|
|
#: src/chromium/interoperability-with-cpp/example-bindings.md
|
|
msgid ""
|
|
"**Common misconception**: It _looks_ like a C++ header is being parsed by "
|
|
"Rust, but this is misleading. This header is never interpreted by Rust, but "
|
|
"simply `#include`d in the generated C++ code for the benefit of C++ "
|
|
"compilers."
|
|
msgstr ""
|
|
"**일반적인 오해**: C++ 헤더가 Rust에서 파싱되는 _것처럼 보이지만_ 오해의 소지"
|
|
"가 있습니다. 이 헤더는 Rust에서 해석되지 않으며 C++ 컴파일러의 이점을 위해 생"
|
|
"성된 C++ 코드에 단순히 `#include`됩니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/limitations-of-cxx.md
|
|
msgid ""
|
|
"By far the most useful page when using CXX is the [type reference](https://"
|
|
"cxx.rs/bindings.html)."
|
|
msgstr ""
|
|
"CXX를 사용할 때 단연 가장 유용한 페이지는 [유형 참조](https://cxx.rs/"
|
|
"bindings.html)입니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/limitations-of-cxx.md
|
|
msgid "CXX fundamentally suits cases where:"
|
|
msgstr "CXX는 기본적으로 다음과 같은 사례에 적합합니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/limitations-of-cxx.md
|
|
msgid ""
|
|
"Your Rust-C++ interface is sufficiently simple that you can declare all of "
|
|
"it."
|
|
msgstr "Rust-C++ 인터페이스는 매우 단순하여 모두 선언할 수 있습니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/limitations-of-cxx.md
|
|
msgid ""
|
|
"You're using only the types natively supported by CXX already, for example "
|
|
"`std::unique_ptr`, `std::string`, `&[u8]` etc."
|
|
msgstr ""
|
|
"이미 CXX에서 기본적으로 지원하는 유형만 사용하고 있습니다(예: `std::"
|
|
"unique_ptr`, `std::string`, `&[u8]` 등)."
|
|
|
|
#: src/chromium/interoperability-with-cpp/limitations-of-cxx.md
|
|
msgid ""
|
|
"It has many limitations --- for example lack of support for Rust's `Option` "
|
|
"type."
|
|
msgstr ""
|
|
"많은 제한이 있습니다. 예를 들어 Rust의 `Option` 유형은 지원되지 않습니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/limitations-of-cxx.md
|
|
msgid ""
|
|
"These limitations constrain us to using Rust in Chromium only for well "
|
|
"isolated \"leaf nodes\" rather than for arbitrary Rust-C++ interop. When "
|
|
"considering a use-case for Rust in Chromium, a good starting point is to "
|
|
"draft the CXX bindings for the language boundary to see if it appears simple "
|
|
"enough."
|
|
msgstr ""
|
|
"이러한 제한사항으로 인해 임의의 Rust-C++ 상호 운용성이 아닌 잘 격리된 '리프 "
|
|
"노드'의 경우에만 Chromium에서 Rust를 사용할 수 있습니다. Chromium에서 Rust 사"
|
|
"용 사례를 고려할 때 좋은 출발점은 언어 경계의 CXX 바인딩 초안을 작성하여 충분"
|
|
"히 단순하게 표시되는지 확인하는 것입니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/limitations-of-cxx.md
|
|
msgid ""
|
|
"You should also discuss some of the other sticky points with CXX, for "
|
|
"example:"
|
|
msgstr "CXX의 다른 어려운 문제도 논의해야 합니다. 예를 들면 다음과 같습니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/limitations-of-cxx.md
|
|
msgid ""
|
|
"Its error handling is based around C++ exceptions (given on the next slide)"
|
|
msgstr "오류 처리는 C++ 예외를 기반으로 합니다(다음 슬라이드에 나와 있음)."
|
|
|
|
#: src/chromium/interoperability-with-cpp/limitations-of-cxx.md
|
|
msgid "Function pointers are awkward to use."
|
|
msgstr "함수 포인터는 사용하기 어색합니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"CXX's [support for `Result<T,E>`](https://cxx.rs/binding/result.html) relies "
|
|
"on C++ exceptions, so we can't use that in Chromium. Alternatives:"
|
|
msgstr ""
|
|
"CXX의 `Result<T,E>` 지원은 C++ 예외를 사용하므로 Chromium에서 사용할 수 없습"
|
|
"니다. 대안:"
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling.md
|
|
msgid "The `T` part of `Result<T, E>` can be:"
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling.md
|
|
msgid ""
|
|
"Returned via out parameters (e.g. via `&mut T`). This requires that `T` can "
|
|
"be passed across the FFI boundary - for example `T` has to be:"
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling.md
|
|
msgid "A primitive type (like `u32` or `usize`)"
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling.md
|
|
msgid ""
|
|
"A type natively supported by `cxx` (like `UniquePtr<T>`) that has a suitable "
|
|
"default value to use in a failure case (_unlike_ `Box<T>`)."
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling.md
|
|
msgid ""
|
|
"Retained on the Rust side, and exposed via reference. This may be needed "
|
|
"when `T` is a Rust type, which cannot be passed across the FFI boundary, and "
|
|
"cannot be stored in `UniquePtr<T>`."
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling.md
|
|
msgid "The `E` part of `Result<T, E>` can be:"
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling.md
|
|
msgid ""
|
|
"Returned as a boolean (e.g. `true` representing success, and `false` "
|
|
"representing failure)"
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling.md
|
|
msgid ""
|
|
"Preserving error details is in theory possible, but so far hasn't been "
|
|
"needed in practice."
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-qr.md
|
|
#, fuzzy
|
|
msgid "CXX Error Handling: QR Example"
|
|
msgstr "오류처리"
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-qr.md
|
|
msgid ""
|
|
"The QR code generator is [an example](https://source.chromium.org/chromium/"
|
|
"chromium/src/+/main:components/qr_code_generator/qr_code_generator_ffi_glue."
|
|
"rs;l=13-18;drc=7bf1b75b910ca430501b9c6a74c1d18a0223ecca) where a boolean is "
|
|
"used to communicate success vs failure, and where the successful result can "
|
|
"be passed across the FFI boundary:"
|
|
msgstr ""
|
|
"[QR 코드 생성기](https://source.chromium.org/chromium/chromium/src/+/main:"
|
|
"components/qr_code_generator/qr_code_generator_ffi_glue.rs;l=10)에서와 같이 "
|
|
"간단한 부울로 성공을 나타낼 수 있는 경우: 성공을 나타내는 부울을 반환하고 "
|
|
"out 매개변수를 사용하여 결과를 기록합니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-qr.md
|
|
msgid "\"qr_code_generator\""
|
|
msgstr "\"qr_code_generator\""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-qr.md
|
|
msgid ""
|
|
"Students may be curious about the semantics of the `out_qr_size` output. "
|
|
"This is not the size of the vector, but the size of the QR code (and "
|
|
"admittedly it is a bit redundant - this is the square root of the size of "
|
|
"the vector)."
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-qr.md
|
|
msgid ""
|
|
"It may be worth pointing out the importance of initializing `out_qr_size` "
|
|
"before calling into the Rust function. Creation of a Rust reference that "
|
|
"points to uninitialized memory results in Undefined Behavior (unlike in C++, "
|
|
"when only the act of dereferencing such memory results in UB)."
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-qr.md
|
|
msgid ""
|
|
"If students ask about `Pin`, then explain why CXX needs it for mutable "
|
|
"references to C++ data: the answer is that C++ data can’t be moved around "
|
|
"like Rust data, because it may contain self-referential pointers."
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-png.md
|
|
#, fuzzy
|
|
msgid "CXX Error Handling: PNG Example"
|
|
msgstr "오류처리"
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-png.md
|
|
msgid ""
|
|
"A prototype of a PNG decoder illustrates what can be done when the "
|
|
"successful result cannot be passed across the FFI boundary:"
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-png.md
|
|
msgid "\"gfx::rust_bindings\""
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-png.md
|
|
msgid ""
|
|
"/// This returns an FFI-friendly equivalent of `Result<PngReader<'a>,\n"
|
|
" /// ()>`.\n"
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-png.md
|
|
msgid "/// C++ bindings for the `crate::png::ResultOfPngReader` type.\n"
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-png.md
|
|
msgid "/// C++ bindings for the `crate::png::PngReader` type.\n"
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-png.md
|
|
msgid ""
|
|
"`PngReader` and `ResultOfPngReader` are Rust types --- objects of these "
|
|
"types cannot cross the FFI boundary without indirection of a `Box<T>`. We "
|
|
"can't have an `out_parameter: &mut PngReader`, because CXX doesn't allow C++ "
|
|
"to store Rust objects by value."
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/error-handling-png.md
|
|
msgid ""
|
|
"This example illustrates that even though CXX doesn't support arbitrary "
|
|
"generics nor templates, we can still pass them across the FFI boundary by "
|
|
"manually specializing / monomorphizing them into a non-generic type. In the "
|
|
"example `ResultOfPngReader` is a non-generic type that forwards into "
|
|
"appropriate methods of `Result<T, E>` (e.g. into `is_err`, `unwrap`, and/or "
|
|
"`as_mut`)."
|
|
msgstr ""
|
|
|
|
#: src/chromium/interoperability-with-cpp/using-cxx-in-chromium.md
|
|
msgid "Using cxx in Chromium"
|
|
msgstr "Chromium에서 cxx 사용"
|
|
|
|
#: src/chromium/interoperability-with-cpp/using-cxx-in-chromium.md
|
|
msgid ""
|
|
"In Chromium, we define an independent `#[cxx::bridge] mod` for each leaf-"
|
|
"node where we want to use Rust. You'd typically have one for each "
|
|
"`rust_static_library`. Just add"
|
|
msgstr ""
|
|
"Chromium에서는 Rust를 사용하려는 리프 노드마다 독립적인 `#[cxx::bridge] mod`"
|
|
"를 정의합니다. 일반적으로 `rust_static_library`마다 하나씩 있습니다. 추가하기"
|
|
"만 하면 됩니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/using-cxx-in-chromium.md
|
|
msgid ""
|
|
"```gn\n"
|
|
"cxx_bindings = [ \"my_rust_file.rs\" ]\n"
|
|
" # list of files containing #[cxx::bridge], not all source files\n"
|
|
"allow_unsafe = true\n"
|
|
"```"
|
|
msgstr ""
|
|
"```gn\n"
|
|
"cxx_bindings = [ \"my_rust_file.rs\" ]\n"
|
|
" # 모든 소스 파일이 아닌 #[cxx::bridge]가 포함된 파일 목록\n"
|
|
"allow_unsafe = true\n"
|
|
"```"
|
|
|
|
#: src/chromium/interoperability-with-cpp/using-cxx-in-chromium.md
|
|
msgid ""
|
|
"to your existing `rust_static_library` target alongside `crate_root` and "
|
|
"`sources`."
|
|
msgstr ""
|
|
"`crate_root` 및 `sources`와 함께 기존 `rust_static_library` 타겟에 추가합니"
|
|
"다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/using-cxx-in-chromium.md
|
|
msgid "C++ headers will be generated at a sensible location, so you can just"
|
|
msgstr "C++ 헤더는 적절한 위치에 생성됩니다. 따라서"
|
|
|
|
#: src/chromium/interoperability-with-cpp/using-cxx-in-chromium.md
|
|
msgid "\"ui/base/my_rust_file.rs.h\""
|
|
msgstr "'ui/base/my_rust_file.rs.h'"
|
|
|
|
#: src/chromium/interoperability-with-cpp/using-cxx-in-chromium.md
|
|
msgid ""
|
|
"You will find some utility functions in `//base` to convert to/from Chromium "
|
|
"C++ types to CXX Rust types --- for example [`SpanToRustSlice`](https://"
|
|
"source.chromium.org/chromium/chromium/src/+/main:base/containers/span_rust.h;"
|
|
"l=21)."
|
|
msgstr ""
|
|
"`//base`에서 Chromium C++ 유형으로 변환하는 또는 Chromium C++ 유형에서 CXX "
|
|
"Rust 유형으로 변환하는 유틸리티 함수를 확인할 수 있습니다. 예: "
|
|
"[`SpanToRustSlice`](https://source.chromium.org/chromium/chromium/src/+/main:"
|
|
"base/containers/span_rust.h;l=21)"
|
|
|
|
#: src/chromium/interoperability-with-cpp/using-cxx-in-chromium.md
|
|
msgid "Students may ask --- why do we still need `allow_unsafe = true`?"
|
|
msgstr "`allow_unsafe = true`가 계속 필요한 이유가 궁금할 수 있습니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/using-cxx-in-chromium.md
|
|
msgid ""
|
|
"The broad answer is that no C/C++ code is \"safe\" by the normal Rust "
|
|
"standards. Calling back and forth to C/C++ from Rust may do arbitrary things "
|
|
"to memory, and compromise the safety of Rust's own data layouts. Presence of "
|
|
"_too many_ `unsafe` keywords in C/C++ interop can harm the signal-to-noise "
|
|
"ratio of such a keyword, and is [controversial](https://steveklabnik.com/"
|
|
"writing/the-cxx-debate), but strictly, bringing any foreign code into a Rust "
|
|
"binary can cause unexpected behavior from Rust's perspective."
|
|
msgstr ""
|
|
"광범위한 의미의 답변은 일반적인 Rust 표준에서는 C/C++ 코드가 '안전하지' 않다"
|
|
"는 것입니다. Rust에서 C/C++를 여기저기 호출하면 메모리에 임의적인 작업을 할 "
|
|
"수 있으며 Rust 자체 데이터 레이아웃의 안전성이 손상될 수 있습니다. C/C++ 상"
|
|
"호 운용성에 `unsafe` 키워드가 _너무 많으면_ 이러한 키워드의 신호대 잡음비에 "
|
|
"해를 끼칠 수 있으며 [논란의 소지가 있습니다](https://steveklabnik.com/"
|
|
"writing/the-cxx-debate). 그러나 엄격하게는 외부 코드를 Rust 바이너리로 가져오"
|
|
"면 Rust의 관점에서 예기치 않은 동작이 발생할 수 있습니다."
|
|
|
|
#: src/chromium/interoperability-with-cpp/using-cxx-in-chromium.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The narrow answer lies in the diagram at the top of [this page](../"
|
|
"interoperability-with-cpp.md) --- behind the scenes, CXX generates Rust "
|
|
"`unsafe` and `extern \"C\"` functions just like we did manually in the "
|
|
"previous section."
|
|
msgstr ""
|
|
"좁은 의미의 답변은 이 페이지 상단의 다이어그램에 있습니다. 내부적으로 CXX는 "
|
|
"이전 섹션에서 수동으로 했던 것처럼 Rust `unsafe` 및 `extern \"C\"` 함수를 생"
|
|
"성합니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
#, fuzzy
|
|
msgid "Exercise: Interoperability with C++"
|
|
msgstr "C와의 상호운용성"
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "Part one"
|
|
msgstr "1부"
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"In the Rust file you previously created, add a `#[cxx::bridge]` which "
|
|
"specifies a single function, to be called from C++, called "
|
|
"`hello_from_rust`, taking no parameters and returning no value."
|
|
msgstr ""
|
|
"이전에 만든 Rust 파일에서, C++에서 호출할 `hello_from_rust`라는 단일 함수를 "
|
|
"지정하는 `#[cxx::bridge]`를 추가합니다. 이 함수는 매개변수를 사용하지 않고 값"
|
|
"을 반환하지 않습니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"Modify your previous `hello_from_rust` function to remove `extern \"C\"` and "
|
|
"`#[no_mangle]`. This is now just a standard Rust function."
|
|
msgstr ""
|
|
"이전의 `hello_from_rust` 함수를 수정하여 `extern \"C\"` 및 `#[no_mangle]`을 "
|
|
"삭제합니다. 이 함수는 이제 표준 Rust 함수입니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "Modify your `gn` target to build these bindings."
|
|
msgstr "`gn` 타겟을 수정하여 이러한 바인딩을 빌드합니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"In your C++ code, remove the forward-declaration of `hello_from_rust`. "
|
|
"Instead, include the generated header file."
|
|
msgstr ""
|
|
"C++ 코드에서 `hello_from_rust`의 정방향 선언을 삭제합니다. 대신 생성된 헤더 "
|
|
"파일을 포함합니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "Build and run!"
|
|
msgstr "빌드 및 실행"
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "Part two"
|
|
msgstr "2부"
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"It's a good idea to play with CXX a little. It helps you think about how "
|
|
"flexible Rust in Chromium actually is."
|
|
msgstr ""
|
|
"CXX를 사용해 보는 것도 좋은 방법입니다. Chromium의 Rust가 실제로 얼마나 유연"
|
|
"한지 생각해 보는 데 도움이 됩니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
#, fuzzy
|
|
msgid "Some things to try:"
|
|
msgstr "참고사항:"
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "Call back into C++ from Rust. You will need:"
|
|
msgstr "Rust에서 C++로 다시 호출 필요한 사항은 다음과 같습니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"An additional header file which you can `include!` from your `cxx::bridge`. "
|
|
"You'll need to declare your C++ function in that new header file."
|
|
msgstr ""
|
|
"`cxx::bridge`에서 `include!`할 수 있는 추가 헤더 파일입니다. 새 헤더 파일에"
|
|
"서 C++ 함수를 선언해야 합니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"An `unsafe` block to call such a function, or alternatively specify the "
|
|
"`unsafe` keyword in your `#[cxx::bridge]` [as described here](https://cxx.rs/"
|
|
"extern-c++.html#functions-and-member-functions)."
|
|
msgstr ""
|
|
"이러한 함수를 호출하거나 [여기에 설명된 대로](https://cxx.rs/extern-c++."
|
|
"html#functions-and-member-functions) `#[cxx::bridge]`에서 `unsafe` 키워드를 "
|
|
"지정하는 `unsafe` 블록입니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"You may also need to `#include \"third_party/rust/cxx/v1/crate/include/cxx."
|
|
"h\"`"
|
|
msgstr ""
|
|
"`#include \"third_party/rust/cxx/v1/crate/include/cxx.h\"`가 필요할 수도 있습"
|
|
"니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "Pass a C++ string from C++ into Rust."
|
|
msgstr "C++에서 Rust로 C++ 문자열을 전달합니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "Pass a reference to a C++ object into Rust."
|
|
msgstr "C++ 객체 참조를 Rust로 전달합니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"Intentionally get the Rust function signatures mismatched from the `#[cxx::"
|
|
"bridge]`, and get used to the errors you see."
|
|
msgstr ""
|
|
"의도적으로 `#[cxx::bridge]`에서 일치하지 않는 Rust 함수 서명을 가져와서 표시"
|
|
"되는 오류에 익숙해집니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"Intentionally get the C++ function signatures mismatched from the `#[cxx::"
|
|
"bridge]`, and get used to the errors you see."
|
|
msgstr ""
|
|
"의도적으로 `#[cxx::bridge]`에서 일치하지 않는 C++ 함수 서명을 가져와서 표시되"
|
|
"는 오류에 익숙해집니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"Pass a `std::unique_ptr` of some type from C++ into Rust, so that Rust can "
|
|
"own some C++ object."
|
|
msgstr ""
|
|
"Rust가 C++ 객체를 소유할 수 있도록 C++에서 일부 유형의 `std::unique_ptr`을 "
|
|
"Rust로 전달합니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"Create a Rust object and pass it into C++, so that C++ owns it. (Hint: you "
|
|
"need a `Box`)."
|
|
msgstr ""
|
|
"Rust 객체를 만들어 C++로 전달하여 C++에서 소유하도록 합니다. 힌트: `Box` 필요"
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "Declare some methods on a C++ type. Call them from Rust."
|
|
msgstr "C++ 유형에 일부 메서드를 선언합니다. Rust에서 이를 호출하세요."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "Declare some methods on a Rust type. Call them from C++."
|
|
msgstr "Rust 유형에 일부 메서드를 선언합니다. C++에서 이를 호출하세요."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "Part three"
|
|
msgstr "3부"
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"Now you understand the strengths and limitations of CXX interop, think of a "
|
|
"couple of use-cases for Rust in Chromium where the interface would be "
|
|
"sufficiently simple. Sketch how you might define that interface."
|
|
msgstr ""
|
|
"지금까지 CXX 상호 운용성의 강점과 한계를 이해했으니, 인터페이스가 충분히 간단"
|
|
"한 Chromium의 Rust 사용 사례를 생각해 보세요. 해당 인터페이스를 정의하는 방법"
|
|
"을 스케치합니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "The [`cxx` binding reference](https://cxx.rs/bindings.html)"
|
|
msgstr "[`cxx` 바인딩 참조](https://cxx.rs/bindings.html)"
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"The [`rust_static_library` gn template](https://source.chromium.org/chromium/"
|
|
"chromium/src/+/main:build/rust/rust_static_library.gni;l=16)"
|
|
msgstr ""
|
|
"[`rust_static_library` gn 템플릿](https://source.chromium.org/chromium/"
|
|
"chromium/src/+/main:build/rust/rust_static_library.gni;l=16)"
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid "Some of the questions you may encounter:"
|
|
msgstr "다음과 같은 문제가 있을 수 있습니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"I'm seeing a problem initializing a variable of type X with type Y, where X "
|
|
"and Y are both function types. This is because your C++ function doesn't "
|
|
"quite match the declaration in your `cxx::bridge`."
|
|
msgstr ""
|
|
"유형 Y로 유형 X의 변수를 초기화하는 데 문제가 있습니다. 여기서 X와 Y는 모두 "
|
|
"함수 유형입니다. 이는 C++ 함수가 `cxx::bridge`의 선언과 일치하지 않기 때문입"
|
|
"니다."
|
|
|
|
#: src/exercises/chromium/interoperability-with-cpp.md
|
|
msgid ""
|
|
"I seem to be able to freely convert C++ references into Rust references. "
|
|
"Doesn't that risk UB? For CXX's _opaque_ types, no, because they are zero-"
|
|
"sized. For CXX trivial types yes, it's _possible_ to cause UB, although "
|
|
"CXX's design makes it quite difficult to craft such an example."
|
|
msgstr ""
|
|
"C++ 참조를 Rust 참조로 자유롭게 변환할 수 있는 것 같습니다. 이렇게 하면 UB가 "
|
|
"발생하지 않을까요? CXX의 _불투명_ 유형의 경우 발생하지 않습니다. 크기가 0이"
|
|
"기 때문입니다. CXX 사소한 유형의 경우 UB를 유발하는 것이 _가능_하지만 CXX의 "
|
|
"설계상 이러한 예를 만들기가 상당히 어렵습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid ""
|
|
"Rust libraries are called \"crates\" and are found at [crates.io](https://"
|
|
"crates.io). It's _very easy_ for Rust crates to depend upon one another. So "
|
|
"they do!"
|
|
msgstr ""
|
|
"Rust 라이브러리는 '크레이트'라고 하며 [crates.io](https://crates.io)에서 찾"
|
|
"을 수 있습니다. Rust 크레이트가 서로 종속되는 것은 _아주 쉽습니다_. 따라서 서"
|
|
"로 종속됩니다."
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
#, fuzzy
|
|
msgid "C++ library"
|
|
msgstr "라이브러리"
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
#, fuzzy
|
|
msgid "Rust crate"
|
|
msgstr "러스트 생태계"
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
#, fuzzy
|
|
msgid "Build system"
|
|
msgstr "러스트 생태계"
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "Lots"
|
|
msgstr "1억+"
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "Consistent: `Cargo.toml`"
|
|
msgstr "일관성: `Cargo.toml`"
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "Typical library size"
|
|
msgstr "일반적인 라이브러리 크기"
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "Large-ish"
|
|
msgstr "큰 편"
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "Small"
|
|
msgstr "작게"
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "Transitive dependencies"
|
|
msgstr "모든 종속성들"
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "Few"
|
|
msgstr "적음"
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "For a Chromium engineer, this has pros and cons:"
|
|
msgstr "Chromium 엔지니어에게는 다음과 같은 장단점이 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid ""
|
|
"All crates use a common build system so we can automate their inclusion into "
|
|
"Chromium..."
|
|
msgstr ""
|
|
"모든 크레이트는 공통 빌드 시스템을 사용하므로 Chromium에 자동으로 포함할 수 "
|
|
"있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid ""
|
|
"... but, crates typically have transitive dependencies, so you will likely "
|
|
"have to bring in multiple libraries."
|
|
msgstr ""
|
|
"그러나 크레이트에는 일반적으로 전이 종속 항목이 있으므로 여러 라이브러리를 가"
|
|
"져와야 할 수 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "We'll discuss:"
|
|
msgstr "다룰 내용은 다음과 같습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "How to put a crate in the Chromium source code tree"
|
|
msgstr "Chromium 소스 코드 트리에 크레이트를 추가하는 방법"
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "How to make `gn` build rules for it"
|
|
msgstr "이를 위해 `gn` 빌드 규칙을 만드는 방법"
|
|
|
|
#: src/chromium/adding-third-party-crates.md
|
|
msgid "How to audit its source code for sufficient safety."
|
|
msgstr "충분한 안전성을 위해 소스 코드를 감사하는 방법"
|
|
|
|
#: src/chromium/adding-third-party-crates/configuring-cargo-toml.md
|
|
msgid "Configuring the `Cargo.toml` file to add crates"
|
|
msgstr "크레이트를 추가하도록 `Cargo.toml` 파일 구성"
|
|
|
|
#: src/chromium/adding-third-party-crates/configuring-cargo-toml.md
|
|
msgid ""
|
|
"Chromium has a single set of centrally-managed direct crate dependencies. "
|
|
"These are managed through a single [`Cargo.toml`](https://source.chromium."
|
|
"org/chromium/chromium/src/+/main:third_party/rust/chromium_crates_io/Cargo."
|
|
"toml):"
|
|
msgstr ""
|
|
"Chromium에는 중앙에서 관리되는 직접 크레이트 종속 항목의 단일 세트가 있습니"
|
|
"다. 이는 단일 [`Cargo.toml`](https://source.chromium.org/chromium/chromium/"
|
|
"src/+/main:third_party/rust/chromium_crates_io/Cargo.toml)을 통해 관리됩니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/configuring-cargo-toml.md
|
|
msgid ""
|
|
"```toml\n"
|
|
"[dependencies]\n"
|
|
"bitflags = \"1\"\n"
|
|
"cfg-if = \"1\"\n"
|
|
"cxx = \"1\"\n"
|
|
"# lots more...\n"
|
|
"```"
|
|
msgstr ""
|
|
"```toml\n"
|
|
"[dependencies]\n"
|
|
"bitflags = \"1\"\n"
|
|
"cfg-if = \"1\"\n"
|
|
"cxx = \"1\"\n"
|
|
"# lots more...\n"
|
|
"```"
|
|
|
|
#: src/chromium/adding-third-party-crates/configuring-cargo-toml.md
|
|
msgid ""
|
|
"As with any other `Cargo.toml`, you can specify [more details about the "
|
|
"dependencies](https://doc.rust-lang.org/cargo/reference/specifying-"
|
|
"dependencies.html) --- most commonly, you'll want to specify the `features` "
|
|
"that you wish to enable in the crate."
|
|
msgstr ""
|
|
"다른 `Cargo.toml`과 마찬가지로 [종속 항목에 관한 자세한 내용](https://doc."
|
|
"rust-lang.org/cargo/reference/specifying-dependencies.html)을 지정할 수 있습"
|
|
"니다. 가장 흔하게는 크레이트에서 사용 설정하려는 `features`를 지정하는 것이 "
|
|
"좋습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/configuring-cargo-toml.md
|
|
msgid ""
|
|
"When adding a crate to Chromium, you'll often need to provide some extra "
|
|
"information in an additional file, `gnrt_config.toml`, which we'll meet next."
|
|
msgstr ""
|
|
"Chromium에 크레이트를 추가할 때는 다음 단계에서 다룰 추가 파일 `gnrt_config."
|
|
"toml`에 몇 가지 정보를 추가로 제공해야 하는 경우가 많습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/configuring-gnrt-config-toml.md
|
|
msgid ""
|
|
"Alongside `Cargo.toml` is [`gnrt_config.toml`](https://source.chromium.org/"
|
|
"chromium/chromium/src/+/main:third_party/rust/chromium_crates_io/gnrt_config."
|
|
"toml). This contains Chromium-specific extensions to crate handling."
|
|
msgstr ""
|
|
"`Cargo.toml`과 함께 [`gnrt_config.toml`](https://source.chromium.org/"
|
|
"chromium/chromium/src/+/main:third_party/rust/chromium_crates_io/gnrt_config."
|
|
"toml)이 있습니다. 여기에는 크레이트 처리를 위한 Chromium 전용 확장 프로그램"
|
|
"이 포함되어 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/configuring-gnrt-config-toml.md
|
|
msgid ""
|
|
"If you add a new crate, you should specify at least the `group`. This is one "
|
|
"of:"
|
|
msgstr ""
|
|
"새 크레이트를 추가하는 경우 적어도 `group`을 지정해야 합니다. 다음 중 하나입"
|
|
"니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/configuring-gnrt-config-toml.md
|
|
#: src/chromium/adding-third-party-crates/depending-on-a-crate.md
|
|
msgid "For instance,"
|
|
msgstr "예를 들면 다음과 같습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/configuring-gnrt-config-toml.md
|
|
msgid ""
|
|
"Depending on the crate source code layout, you may also need to use this "
|
|
"file to specify where its `LICENSE` file(s) can be found."
|
|
msgstr ""
|
|
"크레이트 소스 코드 레이아웃에 따라 이 파일을 사용하여 `LICENSE` 파일을 찾을 "
|
|
"수 있는 위치를 지정해야 할 수도 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/configuring-gnrt-config-toml.md
|
|
msgid ""
|
|
"Later, we'll see some other things you will need to configure in this file "
|
|
"to resolve problems."
|
|
msgstr ""
|
|
"나중에 문제를 해결하기 위해 이 파일에서 구성해야 하는 몇 가지 사항을 살펴봅니"
|
|
"다."
|
|
|
|
#: src/chromium/adding-third-party-crates/downloading-crates.md
|
|
msgid ""
|
|
"A tool called `gnrt` knows how to download crates and how to generate `BUILD."
|
|
"gn` rules."
|
|
msgstr ""
|
|
"`gnrt`라는 도구는 크레이트를 다운로드하는 방법과 `BUILD.gn` 규칙을 생성하는 "
|
|
"방법을 알고 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/downloading-crates.md
|
|
msgid "To start, download the crate you want like this:"
|
|
msgstr "시작하려면 다음과 같이 원하는 크레이트를 다운로드합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/downloading-crates.md
|
|
msgid ""
|
|
"Although the `gnrt` tool is part of the Chromium source code, by running "
|
|
"this command you will be downloading and running its dependencies from "
|
|
"`crates.io`. See [the earlier section](../cargo.md) discussing this security "
|
|
"decision."
|
|
msgstr ""
|
|
"`gnrt` 도구는 Chromium 소스 코드의 일부이지만 이 명령어를 실행하면 `crates."
|
|
"io`에서 종속 항목을 다운로드하고 실행하게 됩니다. 이 보안 관련 결정에 관해서"
|
|
"는 [이전 섹션](../cargo.md)을 참고하세요."
|
|
|
|
#: src/chromium/adding-third-party-crates/downloading-crates.md
|
|
msgid "This `vendor` command may download:"
|
|
msgstr "이 `vendor` 명령어는 다음을 다운로드할 수 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/downloading-crates.md
|
|
#, fuzzy
|
|
msgid "Your crate"
|
|
msgstr "유용한 크레이트"
|
|
|
|
#: src/chromium/adding-third-party-crates/downloading-crates.md
|
|
msgid "Direct and transitive dependencies"
|
|
msgstr "직접 및 임시 종속 항목"
|
|
|
|
#: src/chromium/adding-third-party-crates/downloading-crates.md
|
|
msgid ""
|
|
"New versions of other crates, as required by `cargo` to resolve the complete "
|
|
"set of crates required by Chromium."
|
|
msgstr ""
|
|
"Chromium에서 필요한 전체 크레이트 세트를 해결하기 위해 `cargo`에서 요구하는 "
|
|
"다른 크레이트의 새 버전입니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/downloading-crates.md
|
|
msgid ""
|
|
"Chromium maintains patches for some crates, kept in `//third_party/rust/"
|
|
"chromium_crates_io/patches`. These will be reapplied automatically, but if "
|
|
"patching fails you may need to take manual action."
|
|
msgstr ""
|
|
"Chromium은 `//third_party/rust/chromium_crates_io/patches`에 보관되는 일부 크"
|
|
"레이트의 패치를 유지관리합니다. 이는 자동으로 다시 적용되지만 패치에 실패하"
|
|
"면 직접 조치를 취해야 할 수도 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/generating-gn-build-rules.md
|
|
msgid ""
|
|
"Once you've downloaded the crate, generate the `BUILD.gn` files like this:"
|
|
msgstr "크레이트를 다운로드한 후에는 다음과 같이 `BUILD.gn` 파일을 생성합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/generating-gn-build-rules.md
|
|
msgid "Now run `git status`. You should find:"
|
|
msgstr "이제 `git status`를 실행합니다. 다음을 확인할 수 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/generating-gn-build-rules.md
|
|
msgid ""
|
|
"At least one new crate source code in `third_party/rust/chromium_crates_io/"
|
|
"vendor`"
|
|
msgstr ""
|
|
"`third_party/rust/chromium_crates_io/vendor`에 하나 이상의 새 크레이트 소스 "
|
|
"코드가 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/generating-gn-build-rules.md
|
|
msgid ""
|
|
"At least one new `BUILD.gn` in `third_party/rust/<crate name>/v<major semver "
|
|
"version>`"
|
|
msgstr ""
|
|
"`third_party/rust/<crate name>/v<major semver version>`에 새 `BUILD.gn`이 하"
|
|
"나 이상 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/generating-gn-build-rules.md
|
|
msgid "An appropriate `README.chromium`"
|
|
msgstr "적절한 `README.chromium`"
|
|
|
|
#: src/chromium/adding-third-party-crates/generating-gn-build-rules.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The \"major semver version\" is a [Rust \"semver\" version number](https://"
|
|
"doc.rust-lang.org/cargo/reference/semver.html)."
|
|
msgstr ""
|
|
"자세한 사항은 [공식문서](https://doc.rust-lang.org/reference/type-layout."
|
|
"html)를 확인하세요."
|
|
|
|
#: src/chromium/adding-third-party-crates/generating-gn-build-rules.md
|
|
msgid ""
|
|
"Take a close look, especially at the things generated in `third_party/rust`."
|
|
msgstr "특히 `third_party/rust`에서 생성된 항목을 자세히 살펴보세요."
|
|
|
|
#: src/chromium/adding-third-party-crates/generating-gn-build-rules.md
|
|
msgid ""
|
|
"Talk a little about semver --- and specifically the way that in Chromium "
|
|
"it's to allow multiple incompatible versions of a crate, which is "
|
|
"discouraged but sometimes necessary in the Cargo ecosystem."
|
|
msgstr ""
|
|
"semver에 관해 좀 더 이야기합니다. 특히 Chromium에서는 호환되지 않는 크레이트 "
|
|
"버전을 여러 개 허용하는 방식이 있는데 이는 권장되지 않지만 Cargo 생태계에서"
|
|
"는 때때로 필요합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid ""
|
|
"If your build fails, it may be because of a `build.rs`: programs which do "
|
|
"arbitrary things at build time. This is fundamentally at odds with the "
|
|
"design of `gn` and `ninja` which aim for static, deterministic, build rules "
|
|
"to maximize parallelism and repeatability of builds."
|
|
msgstr ""
|
|
"빌드가 실패하는 경우, 이는 빌드 시간에 임의의 작업을 실행하는 프로그램인 "
|
|
"`build.rs` 때문일 수 있습니다. 이는 빌드의 병렬성과 재현성을 최대화하기 위해 "
|
|
"정적인 빌드 규칙을 목표로 하는 `gn` 및 `ninja`의 설계와 근본적으로 상충됩니"
|
|
"다."
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid ""
|
|
"Some `build.rs` actions are automatically supported; others require action:"
|
|
msgstr "일부 `build.rs` 작업은 자동으로 지원됩니다. 그 외는 조치가 필요합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid "build script effect"
|
|
msgstr "빌드 스크립트 효과"
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid "Supported by our gn templates"
|
|
msgstr "Google의 gn 템플릿에서 지원"
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid "Work required by you"
|
|
msgstr "필요한 작업"
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid "Checking rustc version to configure features on and off"
|
|
msgstr "기능을 사용 및 사용 중지로 구성하기 위해 rustc 버전 확인"
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid "None"
|
|
msgstr "없음"
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid "Checking platform or CPU to configure features on and off"
|
|
msgstr "기능을 사용 및 사용 중지로 구성하기 위해 플랫폼 또는 CPU 확인"
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
#, fuzzy
|
|
msgid "Generating code"
|
|
msgstr "`gn` 빌드 규칙 생성"
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid "Yes - specify in `gnrt_config.toml`"
|
|
msgstr "예 - `gnrt_config.toml`에 지정"
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid "Building C/C++"
|
|
msgstr "C/C++ 빌드"
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid "Patch around it"
|
|
msgstr "주변에 패치를 적용합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid "Arbitrary other actions"
|
|
msgstr "임의의 기타 작업"
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems.md
|
|
msgid ""
|
|
"Fortunately, most crates don't contain a build script, and fortunately, most "
|
|
"build scripts only do the top two actions."
|
|
msgstr ""
|
|
"다행히 대부분의 크레이트에는 빌드 스크립트가 포함되어 있지 않으며, 다행히 대"
|
|
"부분의 빌드 스크립트는 상위 두 가지 작업만 실행합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-generate-code.md
|
|
msgid ""
|
|
"If `ninja` complains about missing files, check the `build.rs` to see if it "
|
|
"writes source code files."
|
|
msgstr ""
|
|
"`ninja`가 파일 누락에 관한 불만을 제기하는 경우 `build.rs`에서 소스 코드 파일"
|
|
"을 작성하는지 확인합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-generate-code.md
|
|
msgid ""
|
|
"If so, modify [`gnrt_config.toml`](../configuring-gnrt-config-toml.md) to "
|
|
"add `build-script-outputs` to the crate. If this is a transitive dependency, "
|
|
"that is, one on which Chromium code should not directly depend, also add "
|
|
"`allow-first-party-usage=false`. There are several examples already in that "
|
|
"file:"
|
|
msgstr ""
|
|
"그렇다면 [`gnrt_config.toml`](../configuring-gnrt-config-toml.md)을 수정하여 "
|
|
"`build-script-outputs`를 크레이트에 추가합니다. 이것이 전이 종속 항목, 즉 "
|
|
"Chromium 코드가 직접 종속되면 안 되는 종속 항목인 경우 `allow-first-party-"
|
|
"usage=false`도 추가합니다. 이 파일에는 이미 다음과 같은 몇 가지 예가 있습니"
|
|
"다."
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-generate-code.md
|
|
msgid ""
|
|
"```toml\n"
|
|
"[crate.unicode-linebreak]\n"
|
|
"allow-first-party-usage = false\n"
|
|
"build-script-outputs = [\"tables.rs\"]\n"
|
|
"```"
|
|
msgstr ""
|
|
"```toml\n"
|
|
"[crate.unicode-linebreak]\n"
|
|
"allow-first-party-usage = false\n"
|
|
"build-script-outputs = [ \"tables.rs\" ]\n"
|
|
"```"
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-generate-code.md
|
|
msgid ""
|
|
"Now rerun [`gnrt.py -- gen`](../generating-gn-build-rules.md) to regenerate "
|
|
"`BUILD.gn` files to inform ninja that this particular output file is input "
|
|
"to subsequent build steps."
|
|
msgstr ""
|
|
"이제 [`gnrt.py -- gen`](../generating-gn-build-rules.md)을 다시 실행하여 "
|
|
"`BUILD.gn` 파일을 다시 생성하고 이 특정 출력 파일이 후속 빌드 단계의 입력이라"
|
|
"고 ninja에 알립니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-take-arbitrary-actions.md
|
|
msgid ""
|
|
"Some crates use the [`cc`](https://crates.io/crates/cc) crate to build and "
|
|
"link C/C++ libraries. Other crates parse C/C++ using [`bindgen`](https://"
|
|
"crates.io/crates/bindgen) within their build scripts. These actions can't be "
|
|
"supported in a Chromium context --- our gn, ninja and LLVM build system is "
|
|
"very specific in expressing relationships between build actions."
|
|
msgstr ""
|
|
"일부 크레이트는 [`cc`](https://crates.io/crates/cc) 크레이트를 사용하여 C/C+"
|
|
"+ 라이브러리를 빌드하고 연결합니다. 다른 크레이트는 빌드 스크립트 내에서 "
|
|
"[`bindgen`](https://crates.io/crates/bindgen)을 사용하여 C/C++를 파싱합니다. "
|
|
"이러한 작업은 Chromium 컨텍스트에서는 지원되지 않습니다. --- Google의 gn, "
|
|
"ninja, LLVM 빌드 시스템은 빌드 작업 간의 관계를 매우 구체적으로 표현합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-take-arbitrary-actions.md
|
|
msgid "So, your options are:"
|
|
msgstr "옵션은 다음과 같습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-take-arbitrary-actions.md
|
|
msgid "Avoid these crates"
|
|
msgstr "이 크레이트는 피하세요."
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-take-arbitrary-actions.md
|
|
msgid "Apply a patch to the crate."
|
|
msgstr "크레이트에 패치를 적용합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-take-arbitrary-actions.md
|
|
msgid ""
|
|
"Patches should be kept in `third_party/rust/chromium_crates_io/patches/"
|
|
"<crate>` - see for example the [patches against the `cxx` crate](https://"
|
|
"source.chromium.org/chromium/chromium/src/+/main:third_party/rust/"
|
|
"chromium_crates_io/patches/cxx/) - and will be applied automatically by "
|
|
"`gnrt` each time it upgrades the crate."
|
|
msgstr ""
|
|
"패치는 `third_party/rust/chromium_crates_io/patches/<crate>`에 보관해야 합니"
|
|
"다. 예는 [`cxx` 크레이트에 대한 패치](https://source.chromium.org/chromium/"
|
|
"chromium/src/+/main:third_party/rust/chromium_crates_io/patches/cxx/)를 참고"
|
|
"하세요. 그리고 크레이트를 업그레이드할 때마다 `gnrt`에 의해 자동으로 적용됩니"
|
|
"다."
|
|
|
|
#: src/chromium/adding-third-party-crates/depending-on-a-crate.md
|
|
msgid ""
|
|
"Once you've added a third-party crate and generated build rules, depending "
|
|
"on a crate is simple. Find your `rust_static_library` target, and add a "
|
|
"`dep` on the `:lib` target within your crate."
|
|
msgstr ""
|
|
"서드 파티 크레이트를 추가하고 빌드 규칙을 생성하고 나면 크레이트에 따른 작업"
|
|
"은 간단합니다. `rust_static_library` 타겟을 찾고 크레이트 내의 `:lib` 타겟에 "
|
|
"`dep`를 추가합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/depending-on-a-crate.md
|
|
#, fuzzy
|
|
msgid "Specifically,"
|
|
msgstr "OS가 정의함"
|
|
|
|
#: src/chromium/adding-third-party-crates/depending-on-a-crate.md
|
|
msgid ""
|
|
"```bob\n"
|
|
" +------------+ +----------------------+\n"
|
|
"\"//third_party/rust\" | crate name | \"/v\" | major semver version | \":"
|
|
"lib\"\n"
|
|
" +------------+ +----------------------+\n"
|
|
"```"
|
|
msgstr ""
|
|
"```bob\n"
|
|
" +------------+ +----------------------+\n"
|
|
"\"//서드 파티/rust\" | 크레이트 이름 | \"/v\" | 메이저 semver 버전 | \"/:"
|
|
"lib\"\n"
|
|
" +------------+ +----------------------+\n"
|
|
"```"
|
|
|
|
#: src/chromium/adding-third-party-crates/depending-on-a-crate.md
|
|
msgid ""
|
|
"```gn\n"
|
|
"rust_static_library(\"my_rust_lib\") {\n"
|
|
" crate_root = \"lib.rs\"\n"
|
|
" sources = [ \"lib.rs\" ]\n"
|
|
" deps = [ \"//third_party/rust/example_rust_crate/v1:lib\" ]\n"
|
|
"}\n"
|
|
"```"
|
|
msgstr ""
|
|
"```gn\n"
|
|
"rust_static_library(\"my_rust_lib\") {\n"
|
|
" crate_root = \"lib.rs\"\n"
|
|
" sources = [ \"lib.rs\" ]\n"
|
|
" deps = [ \"//third_party/rust/example_rust_crate/v1:lib\" ]\n"
|
|
"}\n"
|
|
"```"
|
|
|
|
#: src/chromium/adding-third-party-crates/reviews-and-audits.md
|
|
msgid "Auditing Third Party Crates"
|
|
msgstr "서드 파티 크레이트 감사"
|
|
|
|
#: src/chromium/adding-third-party-crates/reviews-and-audits.md
|
|
msgid ""
|
|
"Adding new libraries is subject to Chromium's standard [policies](https://"
|
|
"chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/rust."
|
|
"md#Third_party-review), but of course also subject to security review. As "
|
|
"you may be bringing in not just a single crate but also transitive "
|
|
"dependencies, there may be a lot of code to review. On the other hand, safe "
|
|
"Rust code can have limited negative side effects. How should you review it?"
|
|
msgstr ""
|
|
"새 라이브러리 추가에는 Chromium의 표준 [정책](https://chromium.googlesource."
|
|
"com/chromium/src/+/refs/heads/main/docs/rust.md#Third_party-review)이 적용되"
|
|
"지만 또한 보안 검토도 적용됩니다. 단일 크레이트뿐만 아니라 전이 종속 항목도 "
|
|
"가져올 수 있으므로 검토할 코드가 많을 수 있습니다. 반면에 안전한 Rust 코드에"
|
|
"서는 부정적인 부작용이 제한될 수 있습니다. 어떻게 검토해야 할까요?"
|
|
|
|
#: src/chromium/adding-third-party-crates/reviews-and-audits.md
|
|
msgid ""
|
|
"Over time Chromium aims to move to a process based around [cargo vet]"
|
|
"(https://mozilla.github.io/cargo-vet/)."
|
|
msgstr ""
|
|
"Chromium은 시간이 지남에 따라 [cargo vet](https://mozilla.github.io/cargo-"
|
|
"vet/)를 기반으로 한 프로세스로 전환하는 것을 목표로 합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/reviews-and-audits.md
|
|
msgid ""
|
|
"Meanwhile, for each new crate addition, we are checking for the following:"
|
|
msgstr "한편 새로운 크레이트가 추가될 때마다 다음 사항을 확인하고 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/reviews-and-audits.md
|
|
msgid ""
|
|
"Understand why each crate is used. What's the relationship between crates? "
|
|
"If the build system for each crate contains a `build.rs` or procedural "
|
|
"macros, work out what they're for. Are they compatible with the way Chromium "
|
|
"is normally built?"
|
|
msgstr ""
|
|
"각 크레이트가 사용되는 이유를 이해합니다. 크레이트 간 관계는 어떠한가요? 각 "
|
|
"크레이트의 빌드 시스템에 `build.rs` 또는 절차 매크로가 포함된 경우 그 용도를 "
|
|
"파악해야 합니다. Chromium이 일반적으로 빌드되는 방식과 호환되나요?"
|
|
|
|
#: src/chromium/adding-third-party-crates/reviews-and-audits.md
|
|
msgid "Check each crate seems to be reasonably well maintained"
|
|
msgstr "각 크레이트가 적절히 잘 유지관리되는지 확인합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/reviews-and-audits.md
|
|
msgid ""
|
|
"Use `cd third-party/rust/chromium_crates_io; cargo audit` to check for known "
|
|
"vulnerabilities (first you'll need to `cargo install cargo-audit`, which "
|
|
"ironically involves downloading lots of dependencies from the internet[2](../"
|
|
"cargo.md))"
|
|
msgstr ""
|
|
"`cd third-party/rust/chromium_crates_io; cargo audit`을 사용하여 알려진 취약"
|
|
"점을 확인합니다. 먼저 `cargo install cargo-audit`을 실행해야 합니다. 여기에"
|
|
"는 인터넷[2](../cargo.md)에서 여러 종속 항목을 다운로드하는 작업이 포함되어 "
|
|
"있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/reviews-and-audits.md
|
|
msgid ""
|
|
"Ensure any `unsafe` code is good enough for the [Rule of Two](https://"
|
|
"chromium.googlesource.com/chromium/src/+/main/docs/security/rule-of-2."
|
|
"md#unsafe-code-in-safe-languages)"
|
|
msgstr ""
|
|
"`unsafe` 코드가 [2의 법칙](https://chromium.googlesource.com/chromium/src/+/"
|
|
"main/docs/security/rule-of-2.md#unsafe-code-in-safe-languages)에 적합한지 확"
|
|
"인합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/reviews-and-audits.md
|
|
msgid "Check for any use of `fs` or `net` APIs"
|
|
msgstr "`fs` 또는 `net` API의 사용 확인"
|
|
|
|
#: src/chromium/adding-third-party-crates/reviews-and-audits.md
|
|
msgid ""
|
|
"Read all the code at a sufficient level to look for anything out of place "
|
|
"that might have been maliciously inserted. (You can't realistically aim for "
|
|
"100% perfection here: there's often just too much code.)"
|
|
msgstr ""
|
|
"악의적으로 삽입되었을 수 있는 잘못된 코드를 찾을 수 있는 충분한 수준으로 모"
|
|
"든 코드를 읽습니다. 현실적으로 100% 완벽을 추구할 수는 없습니다. 코드가 너무 "
|
|
"많을 때가 많습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/reviews-and-audits.md
|
|
msgid ""
|
|
"These are just guidelines --- work with reviewers from `security@chromium."
|
|
"org` to work out the right way to become confident of the crate."
|
|
msgstr ""
|
|
"이 내용은 가이드라인에 불과합니다. `security@chromium.org`의 검토자와 협력하"
|
|
"여 크레이트에 관한 확신을 가질 수 있는 올바른 방법을 찾아보세요."
|
|
|
|
#: src/chromium/adding-third-party-crates/checking-in.md
|
|
msgid "Checking Crates into Chromium Source Code"
|
|
msgstr "Chromium 소스 코드로 크레이트 확인"
|
|
|
|
#: src/chromium/adding-third-party-crates/checking-in.md
|
|
msgid "`git status` should reveal:"
|
|
msgstr "`git status`는 다음을 표시해야 합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/checking-in.md
|
|
msgid "Crate code in `//third_party/rust/chromium_crates_io`"
|
|
msgstr "`//third_party/rust/chromium_crates_io`의 크레이트 코드"
|
|
|
|
#: src/chromium/adding-third-party-crates/checking-in.md
|
|
msgid ""
|
|
"Metadata (`BUILD.gn` and `README.chromium`) in `//third_party/rust/<crate>/"
|
|
"<version>`"
|
|
msgstr ""
|
|
"`//third_party/rust/<crate>/<version>`의 메타데이터(`BUILD.gn` 및 `README."
|
|
"chromium`)"
|
|
|
|
#: src/chromium/adding-third-party-crates/checking-in.md
|
|
msgid "Please also add an `OWNERS` file in the latter location."
|
|
msgstr "후자의 위치에 `OWNERS` 파일도 추가하세요."
|
|
|
|
#: src/chromium/adding-third-party-crates/checking-in.md
|
|
msgid ""
|
|
"You should land all this, along with your `Cargo.toml` and `gnrt_config."
|
|
"toml` changes, into the Chromium repo."
|
|
msgstr ""
|
|
"이 모든 것을 `Cargo.toml` 및 `gnrt_config.toml` 변경사항과 함께 Chromium 저장"
|
|
"소에 배치해야 합니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/checking-in.md
|
|
msgid ""
|
|
"**Important**: you need to use `git add -f` because otherwise `.gitignore` "
|
|
"files may result in some files being skipped."
|
|
msgstr ""
|
|
"**중요**: `git add -f`를 사용해야 합니다. 그러지 않으면 `.gitignore` 파일로 "
|
|
"인해 일부 파일을 건너뛸 수 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/checking-in.md
|
|
msgid ""
|
|
"As you do so, you might find presubmit checks fail because of non-inclusive "
|
|
"language. This is because Rust crate data tends to include names of git "
|
|
"branches, and many projects still use non-inclusive terminology there. So "
|
|
"you may need to run:"
|
|
msgstr ""
|
|
"이렇게 하면 포용적이지 않은 언어로 인해 사전 제출 검사가 실패할 수도 있습니"
|
|
"다. 이는 Rust 크레이트 데이터에는 git 브랜치 이름이 포함되는 경향이 있고, 많"
|
|
"은 프로젝트에서는 여전히 포용적이지 않은 용어를 거기서 사용하기 때문입니다. "
|
|
"따라서 다음을 실행해야 할 수 있습니다."
|
|
|
|
#: src/chromium/adding-third-party-crates/keeping-up-to-date.md
|
|
msgid ""
|
|
"As the OWNER of any third party Chromium dependency, you are [expected to "
|
|
"keep it up to date with any security fixes](https://chromium.googlesource."
|
|
"com/chromium/src/+/main/docs/adding_to_third_party.md#add-owners). It is "
|
|
"hoped that we will soon automate this for Rust crates, but for now, it's "
|
|
"still your responsibility just as it is for any other third party dependency."
|
|
msgstr ""
|
|
"서드 파티 Chromium 종속 항목의 OWNER이므로 [모든 보안 수정사항을 통해 최신 상"
|
|
"태로 유지해야 합니다](https://chromium.googlesource.com/chromium/src/+/main/"
|
|
"docs/adding_to_third_party.md#add-owners). 곧 Rust 크레이트의 경우 이 작업을 "
|
|
"자동화할 수 있기를 바라지만, 당분간은 다른 서드 파티 종속 항목과 마찬가지로 "
|
|
"개발자의 책임입니다."
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid ""
|
|
"Add [uwuify](https://crates.io/crates/uwuify) to Chromium, turning off the "
|
|
"crate's [default features](https://doc.rust-lang.org/cargo/reference/"
|
|
"features.html#the-default-feature). Assume that the crate will be used in "
|
|
"shipping Chromium, but won't be used to handle untrustworthy input."
|
|
msgstr ""
|
|
"Chromium에 [uwuify](https://crates.io/crates/uwuify)를 추가하여 크레이트의 "
|
|
"[기본 기능](https://doc.rust-lang.org/cargo/reference/features.html#the-"
|
|
"default-feature)을 사용 중지합니다. 크레이트가 Chromium 배송에 사용되지만 신"
|
|
"뢰할 수 없는 입력을 처리하는 데는 사용되지 않는다고 가정합니다."
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid ""
|
|
"(In the next exercise we'll use uwuify from Chromium, but feel free to skip "
|
|
"ahead and do that now if you like. Or, you could create a new "
|
|
"[`rust_executable` target](https://source.chromium.org/chromium/chromium/src/"
|
|
"+/main:build/rust/rust_executable.gni) which uses `uwuify`)."
|
|
msgstr ""
|
|
"다음 연습에서는 Chromium의 uwuify를 사용합니다. 원한다면 건너뛰고 지금 해 봐"
|
|
"도 됩니다. 또는 `uwuify`를 사용하는 새로운 [`rust_executable` 타겟](https://"
|
|
"source.chromium.org/chromium/chromium/src/+/main:build/rust/rust_executable."
|
|
"gni)을 만들 수 있습니다."
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid "Students will need to download lots of transitive dependencies."
|
|
msgstr "직접 및 임시 종속 항목"
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid "The total crates needed are:"
|
|
msgstr ""
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid "`instant`,"
|
|
msgstr "`instant`,"
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid "`lock_api`,"
|
|
msgstr "`lock_api`,"
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid "`parking_lot`,"
|
|
msgstr "`parking_lot`,"
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid "`parking_lot_core`,"
|
|
msgstr "`parking_lot_core`,"
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid "`redox_syscall`,"
|
|
msgstr "`redox_syscall`,"
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid "`scopeguard`,"
|
|
msgstr "`scopeguard`,"
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid "`smallvec`, and"
|
|
msgstr "`smallvec`, and"
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid "`uwuify`."
|
|
msgstr "`uwuify`."
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"If students are downloading even more than that, they probably forgot to "
|
|
"turn off the default features."
|
|
msgstr ""
|
|
"필요한 총 크레이트는 uwuify, smallvec, scopeguard, parking_lot, "
|
|
"parking_lot_core, lock_api, instant입니다. 이보다 더 많이 다운로드하는 경우 "
|
|
"기본 기능을 사용 중지하는 것을 잊었을 수 있습니다."
|
|
|
|
#: src/exercises/chromium/third-party.md
|
|
msgid ""
|
|
"Thanks to [Daniel Liu](https://github.com/Daniel-Liu-c0deb0t) for this crate!"
|
|
msgstr ""
|
|
"이 크레이트를 제공해 주신 [다니엘 리우](https://github.com/Daniel-Liu-"
|
|
"c0deb0t)에게 감사드립니다. "
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
#, fuzzy
|
|
msgid "Bringing It Together --- Exercise"
|
|
msgstr "총정리 - 연습문제"
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"In this exercise, you're going to add a whole new Chromium feature, bringing "
|
|
"together everything you already learned."
|
|
msgstr ""
|
|
"이 연습에서는 이미 학습한 모든 내용을 종합하는 완전히 새로운 Chromium 기능을 "
|
|
"추가합니다."
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
#, fuzzy
|
|
msgid "The Brief from Product Management"
|
|
msgstr "제품 관리 브리핑"
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"A community of pixies has been discovered living in a remote rainforest. "
|
|
"It's important that we get Chromium for Pixies delivered to them as soon as "
|
|
"possible."
|
|
msgstr ""
|
|
"외딴 열대 우림에 사는 pixie 커뮤니티가 발견되었습니다. Pixie용 Chromium을 최"
|
|
"대한 빨리 배송하는 것이 중요합니다."
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"The requirement is to translate all Chromium's UI strings into Pixie "
|
|
"language."
|
|
msgstr "Chromium의 모든 UI 문자열을 Pixie 언어로 번역해야 합니다."
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"There's not time to wait for proper translations, but fortunately pixie "
|
|
"language is very close to English, and it turns out there's a Rust crate "
|
|
"which does the translation."
|
|
msgstr ""
|
|
"제대로 번역될 때까지 기다릴 시간은 없지만, 다행히 pixie 언어는 영어와 매우 유"
|
|
"사한 데다 번역을 하는 Rust 크레이트가 있습니다."
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"In fact, you already [imported that crate in the previous exercise](https://"
|
|
"crates.io/crates/uwuify)."
|
|
msgstr ""
|
|
"사실 [이전 연습에서 이 크레이트를 이미 가져왔습니다](https://crates.io/"
|
|
"crates/uwuify)."
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"(Obviously, real translations of Chrome require incredible care and "
|
|
"diligence. Don't ship this!)"
|
|
msgstr ""
|
|
"물론 Chrome의 실제 번역 작업을 위해서는 상당한 주의와 노력이 필요합니다. 배송"
|
|
"하지 마세요."
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid "Steps"
|
|
msgstr "걸음수"
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"Modify `ResourceBundle::MaybeMangleLocalizedString` so that it uwuifies all "
|
|
"strings before display. In this special build of Chromium, it should always "
|
|
"do this irrespective of the setting of `mangle_localized_strings_`."
|
|
msgstr ""
|
|
"표시하기 전에 모든 문자열을 uwuify하도록 `ResourceBundle::"
|
|
"MaybeMangleLocalizedString`을 수정합니다. 이 특수 Chromium 빌드에서는 "
|
|
"`mangle_localized_strings_`의 설정과 관계없이 항상 이 작업을 실행해야 합니다."
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"If you've done everything right across all these exercises, congratulations, "
|
|
"you should have created Chrome for pixies!"
|
|
msgstr ""
|
|
"이 모든 연습에서 모든 작업을 제대로 완료했다면 축하합니다. pixie용 Chrome을 "
|
|
"만드셨을 것입니다."
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"UTF16 vs UTF8. Students should be aware that Rust strings are always UTF8, "
|
|
"and will probably decide that it's better to do the conversion on the C++ "
|
|
"side using `base::UTF16ToUTF8` and back again."
|
|
msgstr ""
|
|
"UTF16과 UTF8. 학생들은 Rust 문자열이 항상 UTF8이라는 점을 알고 있어야 하며, "
|
|
"`base::UTF16ToUTF8`을 사용하여 C++ 측에서 변환을 실행하고 다시 그 반대로 변환"
|
|
"하는 것이 더 낫다고 결정할 수 있습니다."
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"If students decide to do the conversion on the Rust side, they'll need to "
|
|
"consider [`String::from_utf16`](https://doc.rust-lang.org/std/string/struct."
|
|
"String.html#method.from_utf16), consider error handling, and consider which "
|
|
"[CXX supported types can transfer a lot of u16s](https://cxx.rs/binding/"
|
|
"slice.html)."
|
|
msgstr ""
|
|
"Rust 측에서 변환하기로 결정한 학생들은 [`String::from_utf16`](https://doc."
|
|
"rust-lang.org/std/string/struct.String.html#method.from_utf16)을 고려하고 오"
|
|
"류 처리를 고려하고 [많은 u16을 전송할 수 있는 CXX 지원 유형](https://cxx.rs/"
|
|
"binding/slice.html)을 고려해야 합니다."
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"Students may design the C++/Rust boundary in several different ways, e.g. "
|
|
"taking and returning strings by value, or taking a mutable reference to a "
|
|
"string. If a mutable reference is used, CXX will likely tell the student "
|
|
"that they need to use [`Pin`](https://doc.rust-lang.org/std/pin/). You may "
|
|
"need to explain what `Pin` does, and then explain why CXX needs it for "
|
|
"mutable references to C++ data: the answer is that C++ data can't be moved "
|
|
"around like Rust data, because it may contain self-referential pointers."
|
|
msgstr ""
|
|
"학생들은 여러 가지 방법으로 C++/Rust 경계를 설계할 수 있습니다. 예를 들어 값"
|
|
"으로 문자열을 가져와 반환하거나 문자열에 대한 변경 가능한 참조를 사용할 수 있"
|
|
"습니다. 변경 가능한 참조를 사용하면 CXX에서 학생에게[`Pin`](https://doc.rust-"
|
|
"lang.org/std/pin/)을 사용해야 한다고 알릴 가능성이 높습니다. `Pin`의 역할을 "
|
|
"설명하고 이것이 C++ 데이터에 대한 변경 가능한 참조를 위해 CXX에 필요한 이유"
|
|
"를 설명해야 할 수도 있습니다. 대답은 C++ 데이터는 Rust 데이터처럼 이동할 수 "
|
|
"없다는 것입니다. 자체 참조 포인터가 포함되어 있을 수 있기 때문입니다."
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"The C++ target containing `ResourceBundle::MaybeMangleLocalizedString` will "
|
|
"need to depend on a `rust_static_library` target. The student probably "
|
|
"already did this."
|
|
msgstr ""
|
|
"`ResourceBundle::MaybeMangleLocalizedString`이 포함된 C++ 타겟은 "
|
|
"`rust_static_library` 타겟에 종속되어야 합니다. 학생은 이미 이를 실행했을 것"
|
|
"입니다."
|
|
|
|
#: src/exercises/chromium/bringing-it-together.md
|
|
msgid ""
|
|
"The `rust_static_library` target will need to depend on `//third_party/rust/"
|
|
"uwuify/v0_2:lib`."
|
|
msgstr ""
|
|
"`rust_static_library` 타겟은 `//third_party/rust/uwuify/v0_2:lib`에 종속되어"
|
|
"야 합니다."
|
|
|
|
#: src/exercises/chromium/solutions.md
|
|
msgid ""
|
|
"Solutions to the Chromium exercises can be found in [this series of CLs]"
|
|
"(https://chromium-review.googlesource.com/c/chromium/src/+/5096560)."
|
|
msgstr ""
|
|
|
|
#: src/bare-metal.md
|
|
#, fuzzy
|
|
msgid "Welcome to Bare Metal Rust"
|
|
msgstr "Welcome to Comprehensive Rust 🦀"
|
|
|
|
#: src/bare-metal.md
|
|
msgid ""
|
|
"This is a standalone one-day course about bare-metal Rust, aimed at people "
|
|
"who are familiar with the basics of Rust (perhaps from completing the "
|
|
"Comprehensive Rust course), and ideally also have some experience with bare-"
|
|
"metal programming in some other language such as C."
|
|
msgstr ""
|
|
"이 과정은 Rust에 대해 어느정도 경험이 있고 (아마도 Comprehensive Rust 과정을 "
|
|
"통해) C와 같은 다른 언어로 bare-metal 프로그래밍을 해 본 사용자를 대상으로 하"
|
|
"는 bare-metal Rust에 관한 독립적인 1일 과정입니다."
|
|
|
|
#: src/bare-metal.md
|
|
msgid ""
|
|
"Today we will talk about 'bare-metal' Rust: running Rust code without an OS "
|
|
"underneath us. This will be divided into several parts:"
|
|
msgstr ""
|
|
"오늘은 OS를 사용하지 않고 Rust 코드를 실행하는 'bare-metal' Rust에 관해 알아"
|
|
"봅니다. 본 강의의 구성은 다음과 같습니다."
|
|
|
|
#: src/bare-metal.md
|
|
msgid "What is `no_std` Rust?"
|
|
msgstr "`no_std` Rust란 무엇인가요?"
|
|
|
|
#: src/bare-metal.md
|
|
msgid "Writing firmware for microcontrollers."
|
|
msgstr "마이크로컨트롤러용 펌웨어 작성"
|
|
|
|
#: src/bare-metal.md
|
|
msgid "Writing bootloader / kernel code for application processors."
|
|
msgstr "애플리케이션 프로세서를 위한 부트로더 / 커널 코드 작성"
|
|
|
|
#: src/bare-metal.md
|
|
msgid "Some useful crates for bare-metal Rust development."
|
|
msgstr "bare-metal Rust 개발을 위한 유용한 크레이트"
|
|
|
|
#: src/bare-metal.md
|
|
msgid ""
|
|
"For the microcontroller part of the course we will use the [BBC micro:bit]"
|
|
"(https://microbit.org/) v2 as an example. It's a [development board](https://"
|
|
"tech.microbit.org/hardware/) based on the Nordic nRF51822 microcontroller "
|
|
"with some LEDs and buttons, an I2C-connected accelerometer and compass, and "
|
|
"an on-board SWD debugger."
|
|
msgstr ""
|
|
"이 강의에서는 [BBC micro:bit](https://microbit.org/) v2마이크로컨트롤러를 사"
|
|
"용합니다. 이 마이크로컨트롤러는 Nordic nRF51822 마이크로컨트롤러에 기반한 [개"
|
|
"발 보드](https://tech.microbit.org/hardware/)로써, LED와 버튼, I2C 연결 가속"
|
|
"도계 및 나침반, 온보드 SWD 디버거를 포함하고 있습니다."
|
|
|
|
#: src/bare-metal.md
|
|
msgid ""
|
|
"To get started, install some tools we'll need later. On gLinux or Debian:"
|
|
msgstr ""
|
|
"시작하기전에, 앞으로 사용할 도구를 설치해야 합니다. gLinux 또는 Debian를 사용"
|
|
"하고 있다면 아래와 같이 하세요."
|
|
|
|
#: src/bare-metal.md
|
|
msgid ""
|
|
"And give users in the `plugdev` group access to the micro:bit programmer:"
|
|
msgstr ""
|
|
"`plugdev` 그룹의 사용자에게 micro:bit 프로그래머 장치에 대한 액세스 권한을 부"
|
|
"여합니다."
|
|
|
|
#: src/bare-metal.md src/bare-metal/microcontrollers/debugging.md
|
|
msgid "On MacOS:"
|
|
msgstr "MacOS에서:"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`core`"
|
|
msgstr "`core`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`std`"
|
|
msgstr "`std`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "Slices, `&str`, `CStr`"
|
|
msgstr "Slices, `&str`, `CStr`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`NonZeroU8`..."
|
|
msgstr "`NonZeroU8`..."
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`Option`, `Result`"
|
|
msgstr "`Option`, `Result`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`Display`, `Debug`, `write!`..."
|
|
msgstr "`Display`, `Debug`, `write!`..."
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`panic!`, `assert_eq!`..."
|
|
msgstr "`panic!`, `assert_eq!`..."
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`NonNull` and all the usual pointer-related functions"
|
|
msgstr "`NonNull` 및 모든 일반적인 포인터 관련 함수"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`Future` and `async`/`await`"
|
|
msgstr "`Future` and `async`/`await`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`fence`, `AtomicBool`, `AtomicPtr`, `AtomicU32`..."
|
|
msgstr "`fence`, `AtomicBool`, `AtomicPtr`, `AtomicU32`..."
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`Duration`"
|
|
msgstr "`Duration`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`Box`, `Cow`, `Arc`, `Rc`"
|
|
msgstr "`Box`, `Cow`, `Arc`, `Rc`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`Vec`, `BinaryHeap`, `BtreeMap`, `LinkedList`, `VecDeque`"
|
|
msgstr "`Vec`, `BinaryHeap`, `BtreeMap`, `LinkedList`, `VecDeque`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`String`, `CString`, `format!`"
|
|
msgstr "`String`, `CString`, `format!`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`Error`"
|
|
msgstr "`Error`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`Mutex`, `Condvar`, `Barrier`, `Once`, `RwLock`, `mpsc`"
|
|
msgstr "`Mutex`, `Condvar`, `Barrier`, `Once`, `RwLock`, `mpsc`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`File` and the rest of `fs`"
|
|
msgstr "`File` 및 나머지 `fs`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`println!`, `Read`, `Write`, `Stdin`, `Stdout` and the rest of `io`"
|
|
msgstr "`println!`, `Read`, `Write`, `Stdin`, `Stdout` 및 나머지 `io`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`Path`, `OsString`"
|
|
msgstr "`Path`, `OsString`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`net`"
|
|
msgstr "`net`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`Command`, `Child`, `ExitCode`"
|
|
msgstr "`Command`, `Child`, `ExitCode`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`spawn`, `sleep` and the rest of `thread`"
|
|
msgstr "`spawn`, `sleep` 및 나머지 `thread`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`SystemTime`, `Instant`"
|
|
msgstr "`SystemTime`, `Instant`"
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`HashMap` depends on RNG."
|
|
msgstr "`HashMap`은 RNG에 의존합니다."
|
|
|
|
#: src/bare-metal/no_std.md
|
|
msgid "`std` re-exports the contents of both `core` and `alloc`."
|
|
msgstr "`std`는 `core` 및 `alloc`를 포함합니다."
|
|
|
|
#: src/bare-metal/minimal.md
|
|
msgid "A minimal `no_std` program"
|
|
msgstr "최소한의 `no_std` 프로그램"
|
|
|
|
#: src/bare-metal/minimal.md
|
|
msgid "This will compile to an empty binary."
|
|
msgstr "이 코드는 빈 바이너리로 컴파일됩니다."
|
|
|
|
#: src/bare-metal/minimal.md
|
|
msgid "`std` provides a panic handler; without it we must provide our own."
|
|
msgstr ""
|
|
"`std`는 패닉 핸들러를 제공하지만, 우리는 자체적으로 핸들러를 만들어야합니다."
|
|
|
|
#: src/bare-metal/minimal.md
|
|
msgid "It can also be provided by another crate, such as `panic-halt`."
|
|
msgstr "패닉 핸들러는 `panic-halt`와 같은 크레이트를 통해서 만들수도 있습니다."
|
|
|
|
#: src/bare-metal/minimal.md
|
|
msgid ""
|
|
"Depending on the target, you may need to compile with `panic = \"abort\"` to "
|
|
"avoid an error about `eh_personality`."
|
|
msgstr ""
|
|
"타겟에 따라 `panic = \"abort\"`로 컴파일해야 할 수 있습니다. 이는 "
|
|
"`eh_personality`에 관한 오류를 방지하기 위함입니다."
|
|
|
|
#: src/bare-metal/minimal.md
|
|
msgid ""
|
|
"Note that there is no `main` or any other entry point; it's up to you to "
|
|
"define your own entry point. This will typically involve a linker script and "
|
|
"some assembly code to set things up ready for Rust code to run."
|
|
msgstr ""
|
|
"`main` 과 같은 프로그램 진입점이 없습니다. 개발자가 자체적으로 진입점을 정의"
|
|
"해야 합니다. 진입점을 정의하는 작업은, 일반적으로 링커 스크립트와 어셈블리 코"
|
|
"드를 필요로 합니다."
|
|
|
|
#: src/bare-metal/alloc.md
|
|
msgid ""
|
|
"To use `alloc` you must implement a [global (heap) allocator](https://doc."
|
|
"rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html)."
|
|
msgstr ""
|
|
"`alloc`을 사용하려면 [전역 (힙) 할당자](https://doc.rust-lang.org/stable/std/"
|
|
"alloc/trait.GlobalAlloc.html)를 구현해야 합니다."
|
|
|
|
#: src/bare-metal/alloc.md
|
|
msgid ""
|
|
"// Safe because `HEAP` is only used here and `entry` is only called once.\n"
|
|
msgstr ""
|
|
"// `HEAP`이 여기서만 사용되고 `entry`가 한 번만 호출되므로 안전합니다.\n"
|
|
|
|
#: src/bare-metal/alloc.md
|
|
msgid "// Give the allocator some memory to allocate.\n"
|
|
msgstr "// 할당자에게 할당할 메모리를 제공합니다.\n"
|
|
|
|
#: src/bare-metal/alloc.md
|
|
msgid "// Now we can do things that require heap allocation.\n"
|
|
msgstr "// 이제 힙 할당이 필요한 작업을 할 수 있습니다.\n"
|
|
|
|
#: src/bare-metal/alloc.md
|
|
#, fuzzy
|
|
msgid "\"A string\""
|
|
msgstr "String"
|
|
|
|
#: src/bare-metal/alloc.md
|
|
msgid ""
|
|
"`buddy_system_allocator` is a third-party crate implementing a basic buddy "
|
|
"system allocator. Other crates are available, or you can write your own or "
|
|
"hook into your existing allocator."
|
|
msgstr ""
|
|
"`buddy_system_allocator`는 간단한 버디 시스템 할당자를 구현하는 서드 파티 크"
|
|
"레이트입니다. 이 외에도, 다른 크레이트를 사용하거나, 직접 할당자를 만들거나, "
|
|
"이미 존재하는 다른 할당자에 후킹할 수 있습니다."
|
|
|
|
#: src/bare-metal/alloc.md
|
|
msgid ""
|
|
"The const parameter of `LockedHeap` is the max order of the allocator; i.e. "
|
|
"in this case it can allocate regions of up to 2\\*\\*32 bytes."
|
|
msgstr ""
|
|
"`LockHeap` 타입의 const 매개변수는 할당자의 최대 크기를 2진수로 표현했을 때"
|
|
"의 자릿수입니다. 즉, 이 경우처럼 32인 경우 최대 2\\*\\*32바이트 크기의 영역"
|
|
"을 다룰 수 있습니다."
|
|
|
|
#: src/bare-metal/alloc.md
|
|
msgid ""
|
|
"If any crate in your dependency tree depends on `alloc` then you must have "
|
|
"exactly one global allocator defined in your binary. Usually this is done in "
|
|
"the top-level binary crate."
|
|
msgstr ""
|
|
"한 바이너리에서 `alloc`에 의존하는 크레이트가 하나라도 있다면 바이너리 전체에"
|
|
"서 전역 할당자가 반드시 하나 존재해야 합니다. 일반적으로 전역 할당자를 선언하"
|
|
"는 작업은 최상위 바이너리 크레이트에서 이루어집니다."
|
|
|
|
#: src/bare-metal/alloc.md
|
|
msgid ""
|
|
"`extern crate panic_halt as _` is necessary to ensure that the `panic_halt` "
|
|
"crate is linked in so we get its panic handler."
|
|
msgstr ""
|
|
"`panic_halt` 크레이트가 연결되어 패닉 핸들러를 가져오도록 하려면 `extern "
|
|
"crate panic_halt as _`가 필요합니다."
|
|
|
|
#: src/bare-metal/alloc.md
|
|
msgid "This example will build but not run, as it doesn't have an entry point."
|
|
msgstr ""
|
|
"이 예시 코드는 빌드는 되지만, 진입점이 없기 때문에 실행되지는 않습니다."
|
|
|
|
#: src/bare-metal/microcontrollers.md
|
|
msgid ""
|
|
"The `cortex_m_rt` crate provides (among other things) a reset handler for "
|
|
"Cortex M microcontrollers."
|
|
msgstr ""
|
|
"`cortex_m_rt` 크레이트는 Cortex M 마이크로컨트롤러를 초기화 하는 핸들러를 제"
|
|
"공합니다."
|
|
|
|
#: src/bare-metal/microcontrollers.md
|
|
msgid ""
|
|
"Next we'll look at how to access peripherals, with increasing levels of "
|
|
"abstraction."
|
|
msgstr ""
|
|
"이제, 주변장치에 액세스하는 방법을 알아보겠습니다. 가장 기계에 가까운 낮은 단"
|
|
"계에서 시작해서 점점 추상화 수준을 올리겠습니다."
|
|
|
|
#: src/bare-metal/microcontrollers.md
|
|
msgid ""
|
|
"The `cortex_m_rt::entry` macro requires that the function have type `fn() -"
|
|
"> !`, because returning to the reset handler doesn't make sense."
|
|
msgstr ""
|
|
"`cortex_m_rt::entry` 매크로는 진입점으로 사용되는 함수가`fn() -> !` 타입(즉, "
|
|
"리턴하지 않는)임을 요구합니다. 만약, 리턴하게 되면, 프로그램 수행 후 리셋 핸"
|
|
"들러로 돌아가게 되는 것인데 이는 말이 되지 않기 때문입니다."
|
|
|
|
#: src/bare-metal/microcontrollers.md
|
|
msgid "Run the example with `cargo embed --bin minimal`"
|
|
msgstr "`cargo embed --bin minimal`을 사용하여 예시를 실행합니다."
|
|
|
|
#: src/bare-metal/microcontrollers/mmio.md
|
|
msgid ""
|
|
"Most microcontrollers access peripherals via memory-mapped IO. Let's try "
|
|
"turning on an LED on our micro:bit:"
|
|
msgstr ""
|
|
"대부분의 마이크로컨트롤러는 메모리 매핑 IO를 통해 주변기기에 액세스합니다. "
|
|
"micro:bit에서 LED를 켜보겠습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/mmio.md
|
|
msgid "/// GPIO port 0 peripheral address\n"
|
|
msgstr "/// GPIO 포트 0 주변기기 주소\n"
|
|
|
|
#: src/bare-metal/microcontrollers/mmio.md
|
|
msgid "// GPIO peripheral offsets\n"
|
|
msgstr "// GPIO 주변기기 오프셋\n"
|
|
|
|
#: src/bare-metal/microcontrollers/mmio.md
|
|
msgid "// PIN_CNF fields\n"
|
|
msgstr "// PIN_CNF 필드\n"
|
|
|
|
#: src/bare-metal/microcontrollers/mmio.md
|
|
#: src/bare-metal/microcontrollers/pacs.md
|
|
#: src/bare-metal/microcontrollers/hals.md
|
|
msgid "// Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n"
|
|
msgstr "// GPIO 0 핀 21 및 28을 푸시-풀 출력으로 구성합니다.\n"
|
|
|
|
#: src/bare-metal/microcontrollers/mmio.md
|
|
msgid ""
|
|
"// Safe because the pointers are to valid peripheral control registers, and\n"
|
|
" // no aliases exist.\n"
|
|
msgstr ""
|
|
"// 유효한 주변기기 제어 레지스터에 대한 포인터이고\n"
|
|
" // 별칭이 없으므로 안전합니다.\n"
|
|
|
|
#: src/bare-metal/microcontrollers/mmio.md
|
|
#: src/bare-metal/microcontrollers/pacs.md
|
|
#: src/bare-metal/microcontrollers/hals.md
|
|
msgid "// Set pin 28 low and pin 21 high to turn the LED on.\n"
|
|
msgstr "// 핀 28을 낮게, 핀 21을 높게 설정하여 LED를 켭니다.\n"
|
|
|
|
#: src/bare-metal/microcontrollers/mmio.md
|
|
msgid ""
|
|
"GPIO 0 pin 21 is connected to the first column of the LED matrix, and pin 28 "
|
|
"to the first row."
|
|
msgstr ""
|
|
"GPIO 0 핀 21은 LED 매트릭스의 첫 번째 열에 연결되고 핀 28은 첫 번째 행에 연결"
|
|
"됩니다."
|
|
|
|
#: src/bare-metal/microcontrollers/mmio.md
|
|
#: src/bare-metal/microcontrollers/pacs.md
|
|
#: src/bare-metal/microcontrollers/hals.md
|
|
#: src/bare-metal/microcontrollers/board-support.md
|
|
msgid "Run the example with:"
|
|
msgstr "아래 명령어로 예제 코드를 실행하세요."
|
|
|
|
#: src/bare-metal/microcontrollers/pacs.md
|
|
msgid "Peripheral Access Crates"
|
|
msgstr "주변기기 액세스 크레이트"
|
|
|
|
#: src/bare-metal/microcontrollers/pacs.md
|
|
msgid ""
|
|
"[`svd2rust`](https://crates.io/crates/svd2rust) generates mostly-safe Rust "
|
|
"wrappers for memory-mapped peripherals from [CMSIS-SVD](https://www.keil.com/"
|
|
"pack/doc/CMSIS/SVD/html/index.html) files."
|
|
msgstr ""
|
|
"[`svd2rust`](https://crates.io/crates/svd2rust) 크레이트를 이용하면 메모리 매"
|
|
"핑된 주변장치를 기술하는 [CMSIS-SVD](https://www.keil.com/pack/doc/CMSIS/SVD/"
|
|
"html/index.html) 파일로부터 Rust 래퍼를 생성할 수 있습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/pacs.md
|
|
msgid ""
|
|
"SVD (System View Description) files are XML files typically provided by "
|
|
"silicon vendors which describe the memory map of the device."
|
|
msgstr ""
|
|
"SVD(System View Description) 파일은 일반적으로 실리콘 공급업체에서 제공하는 "
|
|
"XML 파일로, 기기의 메모리 맵을 기술합니다."
|
|
|
|
#: src/bare-metal/microcontrollers/pacs.md
|
|
msgid ""
|
|
"They are organised by peripheral, register, field and value, with names, "
|
|
"descriptions, addresses and so on."
|
|
msgstr ""
|
|
"주변기기, 레지스터, 필드, 값으로 구성되며 이름, 설명, 주소 등이 포함됩니다."
|
|
|
|
#: src/bare-metal/microcontrollers/pacs.md
|
|
msgid ""
|
|
"SVD files are often buggy and incomplete, so there are various projects "
|
|
"which patch the mistakes, add missing details, and publish the generated "
|
|
"crates."
|
|
msgstr ""
|
|
"SVD 파일에는 버그가 있을 수 있고 불완전하기 때문에, 이러한 문제들을 패치하는 "
|
|
"다양한 프로젝트들이 있습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/pacs.md
|
|
msgid "`cortex-m-rt` provides the vector table, among other things."
|
|
msgstr "`cortex-m-rt`는 무엇보다도 벡터 테이블을 제공합니다."
|
|
|
|
#: src/bare-metal/microcontrollers/pacs.md
|
|
msgid ""
|
|
"If you `cargo install cargo-binutils` then you can run `cargo objdump --bin "
|
|
"pac -- -d --no-show-raw-insn` to see the resulting binary."
|
|
msgstr ""
|
|
"`cargo install cargo-binutils`을 실행한 후, `cargo objdump --bin pac -- -d --"
|
|
"no-show-raw-insn`을 실행하여 생성된 바이너리의 내용을 확인할 수 있습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/hals.md
|
|
msgid "HAL crates"
|
|
msgstr "HAL 크레이트들"
|
|
|
|
#: src/bare-metal/microcontrollers/hals.md
|
|
msgid ""
|
|
"[HAL crates](https://github.com/rust-embedded/awesome-embedded-rust#hal-"
|
|
"implementation-crates) for many microcontrollers provide wrappers around "
|
|
"various peripherals. These generally implement traits from [`embedded-hal`]"
|
|
"(https://crates.io/crates/embedded-hal)."
|
|
msgstr ""
|
|
"다양한 주변 장치에 대한 래퍼를 제공하는 [HAL 크레이트](https://github.com/"
|
|
"rust-embedded/awesome-embedded-rust#hal-implementation-crates)들이 있습니다. "
|
|
"이 크레이트들은 일반적으로 [`embedded-hal`](https://crates.io/crates/"
|
|
"embedded-hal)의 트레잇을 구현합니다."
|
|
|
|
#: src/bare-metal/microcontrollers/hals.md
|
|
msgid "// Create HAL wrapper for GPIO port 0.\n"
|
|
msgstr "// GPIO 포트 0의 HAL 래퍼를 만듭니다.\n"
|
|
|
|
#: src/bare-metal/microcontrollers/hals.md
|
|
msgid ""
|
|
"`set_low` and `set_high` are methods on the `embedded_hal` `OutputPin` trait."
|
|
msgstr ""
|
|
"`set_low` 및 `set_high`는 `embedded_hal` `OutputPin` 트레잇의 메서드입니다."
|
|
|
|
#: src/bare-metal/microcontrollers/hals.md
|
|
msgid ""
|
|
"HAL crates exist for many Cortex-M and RISC-V devices, including various "
|
|
"STM32, GD32, nRF, NXP, MSP430, AVR and PIC microcontrollers."
|
|
msgstr ""
|
|
"다양한 STM32, GD32, nRF, NXP, MSP430, AVR, PIC 마이크로컨트롤러를 비롯한 많"
|
|
"은 Cortex-M 및 RISC-V 기기를 위한 HAL 크레이트가 있습니다"
|
|
|
|
#: src/bare-metal/microcontrollers/board-support.md
|
|
#, fuzzy
|
|
msgid "Board support crates"
|
|
msgstr "보드 지원 크레이트"
|
|
|
|
#: src/bare-metal/microcontrollers/board-support.md
|
|
msgid ""
|
|
"Board support crates provide a further level of wrapping for a specific "
|
|
"board for convenience."
|
|
msgstr ""
|
|
"보드 지원 크레이트들은, 특정 보드를 더 손쉽게 사용할 수 있게 해 주는 더 높은 "
|
|
"수준의 추상화를 제공합니다."
|
|
|
|
#: src/bare-metal/microcontrollers/board-support.md
|
|
msgid ""
|
|
"In this case the board support crate is just providing more useful names, "
|
|
"and a bit of initialisation."
|
|
msgstr ""
|
|
"이 경우 보드 지원 크레이트는 좀 더 직관적인 이름들과 적당한 수준의 초기화를 "
|
|
"제공합니다."
|
|
|
|
#: src/bare-metal/microcontrollers/board-support.md
|
|
msgid ""
|
|
"The crate may also include drivers for some on-board devices outside of the "
|
|
"microcontroller itself."
|
|
msgstr ""
|
|
"이 크레이트는 마이크로컨트롤 밖에 있는 (즉, 보드에 설치된) 장치에 대한 드라이"
|
|
"버도 포함할 수 있습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/board-support.md
|
|
msgid "`microbit-v2` includes a simple driver for the LED matrix."
|
|
msgstr ""
|
|
"`microbit-v2`에는 LED 매트릭스를 위한 간단한 드라이버가 포함되어 있습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/type-state.md
|
|
msgid "The type state pattern"
|
|
msgstr "타입 상태 패턴"
|
|
|
|
#: src/bare-metal/microcontrollers/type-state.md
|
|
msgid "// let gpio0_01_again = gpio0.p0_01; // Error, moved.\n"
|
|
msgstr ""
|
|
"// let gpio0_01_again = gpio0.p0_01; // 오류가 발생하여 이동했습니다.\n"
|
|
|
|
#: src/bare-metal/microcontrollers/type-state.md
|
|
msgid "// pin_input.is_high(); // Error, moved.\n"
|
|
msgstr "// pin_input.is_high(); // 오류가 발생하여 이동했습니다.\n"
|
|
|
|
#: src/bare-metal/microcontrollers/type-state.md
|
|
msgid ""
|
|
"Pins don't implement `Copy` or `Clone`, so only one instance of each can "
|
|
"exist. Once a pin is moved out of the port struct nobody else can take it."
|
|
msgstr ""
|
|
"핀은 `Copy` 또는 `Clone`을 구현하지 않으므로 각각 하나의 인스턴스만 존재할 "
|
|
"수 있습니다. 핀을 포트 구조체 밖으로 이동하면 아무도 사용할 수 없습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/type-state.md
|
|
msgid ""
|
|
"Changing the configuration of a pin consumes the old pin instance, so you "
|
|
"can’t keep use the old instance afterwards."
|
|
msgstr ""
|
|
"핀 구성을 변경하면 이전 핀 인스턴스가 사용되므로 이후에 이전 인스턴스를 계속 "
|
|
"사용할 수 없습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/type-state.md
|
|
msgid ""
|
|
"The type of a value indicates the state that it is in: e.g. in this case, "
|
|
"the configuration state of a GPIO pin. This encodes the state machine into "
|
|
"the type system, and ensures that you don't try to use a pin in a certain "
|
|
"way without properly configuring it first. Illegal state transitions are "
|
|
"caught at compile time."
|
|
msgstr ""
|
|
"값 타입은 현재 상태를 나타냅니다. 예를 들어 이 경우에는 GPIO 핀의 구성 상태입"
|
|
"니다. 이렇게 하면 상태 머신이 타입 시스템으로 인코딩되며, 먼저 올바르게 구성"
|
|
"한 후 특정 방식으로 핀을 사용하도록 합니다. 잘못된 상태 전환은 컴파일 시간에 "
|
|
"포착됩니다."
|
|
|
|
#: src/bare-metal/microcontrollers/type-state.md
|
|
msgid ""
|
|
"You can call `is_high` on an input pin and `set_high` on an output pin, but "
|
|
"not vice-versa."
|
|
msgstr ""
|
|
"입력 핀에서 `is_high`를 호출하고 출력 핀에서 `set_high`를 호출할 수 있지만 "
|
|
"그 반대로는 안 됩니다."
|
|
|
|
#: src/bare-metal/microcontrollers/type-state.md
|
|
msgid "Many HAL crates follow this pattern."
|
|
msgstr "많은 HAL 크레이트들이 이 패턴을 따릅니다."
|
|
|
|
#: src/bare-metal/microcontrollers/embedded-hal.md
|
|
msgid ""
|
|
"The [`embedded-hal`](https://crates.io/crates/embedded-hal) crate provides a "
|
|
"number of traits covering common microcontroller peripherals."
|
|
msgstr ""
|
|
"[`embedded-hal`](https://crates.io/crates/embedded-hal) 크레이트는 다양한 마"
|
|
"이크로컨트롤러에서 공통적으로 찾아볼 수 있는 주변기기를 추상회 하는 다양한 트"
|
|
"레잇을 제공합니다."
|
|
|
|
#: src/bare-metal/microcontrollers/embedded-hal.md
|
|
msgid "GPIO"
|
|
msgstr "GPIO"
|
|
|
|
#: src/bare-metal/microcontrollers/embedded-hal.md
|
|
msgid "ADC"
|
|
msgstr "ADC"
|
|
|
|
#: src/bare-metal/microcontrollers/embedded-hal.md
|
|
msgid "I2C, SPI, UART, CAN"
|
|
msgstr "I2C, SPI, UART, CAN"
|
|
|
|
#: src/bare-metal/microcontrollers/embedded-hal.md
|
|
msgid "RNG"
|
|
msgstr "RNG"
|
|
|
|
#: src/bare-metal/microcontrollers/embedded-hal.md
|
|
msgid "Timers"
|
|
msgstr "타이머"
|
|
|
|
#: src/bare-metal/microcontrollers/embedded-hal.md
|
|
msgid "Watchdogs"
|
|
msgstr "워치독"
|
|
|
|
#: src/bare-metal/microcontrollers/embedded-hal.md
|
|
msgid ""
|
|
"Other crates then implement [drivers](https://github.com/rust-embedded/"
|
|
"awesome-embedded-rust#driver-crates) in terms of these traits, e.g. an "
|
|
"accelerometer driver might need an I2C or SPI bus implementation."
|
|
msgstr ""
|
|
"그러면 다른 크레이트는 이 트레잇들을 활용하여 [드라이버](https://github.com/"
|
|
"rust-embedded/awesome-embedded-rust#driver-crates)를 구현합니다. 예를 들어 가"
|
|
"속도계 드라이버를 구현할 떄 I2C 또는 SPI 버스 구현을 사용할 수 있습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/embedded-hal.md
|
|
msgid ""
|
|
"There are implementations for many microcontrollers, as well as other "
|
|
"platforms such as Linux on Raspberry Pi."
|
|
msgstr ""
|
|
"라스베리 파이에서 돌아가는 리눅스 같은 플랫폼 뿐만 아니라 다른 여러 마이크로"
|
|
"컨트롤러에 대한 구현이 있습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/embedded-hal.md
|
|
msgid ""
|
|
"There is work in progress on an `async` version of `embedded-hal`, but it "
|
|
"isn't stable yet."
|
|
msgstr ""
|
|
"`embedded-hal`의 'async' 버전에 관한 작업이 진행 중이지만 아직 안정적이지 않"
|
|
"습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/probe-rs.md
|
|
msgid ""
|
|
"[probe-rs](https://probe.rs/) is a handy toolset for embedded debugging, "
|
|
"like OpenOCD but better integrated."
|
|
msgstr ""
|
|
"[probe-rs](https://probe.rs/)는 임베디드 시스템을 위한 도구 모임입니다. "
|
|
"OpenOCD와 비슷하지만, Rust에 더 잘 통합되어 있습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/probe-rs.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"SWD (Serial Wire Debug) and JTAG via CMSIS-DAP, ST-Link and J-Link probes"
|
|
msgstr " 및 JTAG(CMSIS-DAP, ST-Link, J-Link 프로브를 통함)"
|
|
|
|
#: src/bare-metal/microcontrollers/probe-rs.md
|
|
msgid "GDB stub and Microsoft DAP (Debug Adapter Protocol) server"
|
|
msgstr "GDB 스텁 및 Microsoft DAP(디버그 어댑터 프로토콜) 서버"
|
|
|
|
#: src/bare-metal/microcontrollers/probe-rs.md
|
|
msgid "Cargo integration"
|
|
msgstr "Cargo에 통합됨"
|
|
|
|
#: src/bare-metal/microcontrollers/probe-rs.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`cargo-embed` is a cargo subcommand to build and flash binaries, log RTT "
|
|
"(Real Time Transfers) output and connect GDB. It's configured by an `Embed."
|
|
"toml` file in your project directory."
|
|
msgstr ""
|
|
" 출력을 기록하고, GDB를 연결해 줍니다. 이 명령어의 세부 동작은 프로젝트 디렉"
|
|
"터리의 `Embed.toml` 파일을 통해 설정합니다."
|
|
|
|
#: src/bare-metal/microcontrollers/probe-rs.md
|
|
msgid ""
|
|
"[CMSIS-DAP](https://arm-software.github.io/CMSIS_5/DAP/html/index.html) is "
|
|
"an Arm standard protocol over USB for an in-circuit debugger to access the "
|
|
"CoreSight Debug Access Port of various Arm Cortex processors. It's what the "
|
|
"on-board debugger on the BBC micro:bit uses."
|
|
msgstr ""
|
|
"[CMSIS-DAP](https://arm-software.github.io/CMSIS_5/DAP/html/index.html)는 Arm"
|
|
"에서 정의한 프로토콜로, USB를 통해 Arm Cortex 프로세서의 CoreSight 디버그 액"
|
|
"세스 포트에 접근할 수 있게 해 줍니다. BBC micro:bit에 있는 온보드 디버거도 "
|
|
"이 프로토콜을 지원합니다."
|
|
|
|
#: src/bare-metal/microcontrollers/probe-rs.md
|
|
msgid ""
|
|
"ST-Link is a range of in-circuit debuggers from ST Microelectronics, J-Link "
|
|
"is a range from SEGGER."
|
|
msgstr ""
|
|
"ST-Link는 ST Microelectronics사에서 만든 in-circuit 디버거들이며, J-Link는 "
|
|
"SEGGER사의 in-circuit 디버거들입니다."
|
|
|
|
#: src/bare-metal/microcontrollers/probe-rs.md
|
|
msgid ""
|
|
"The Debug Access Port is usually either a 5-pin JTAG interface or 2-pin "
|
|
"Serial Wire Debug."
|
|
msgstr ""
|
|
"디버그 액세스 포트의 물리적인 구성은 일반적으로 5핀 JTAG 인터페이스 혹은, 2"
|
|
"핀 Serial Wire Debug 인터페이스 입니다."
|
|
|
|
#: src/bare-metal/microcontrollers/probe-rs.md
|
|
msgid ""
|
|
"probe-rs is a library which you can integrate into your own tools if you "
|
|
"want to."
|
|
msgstr ""
|
|
"probe-rs는 라이브러리로 구현되어 있어서, 다른 도구들에 통합되기가 쉽습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/probe-rs.md
|
|
msgid ""
|
|
"The [Microsoft Debug Adapter Protocol](https://microsoft.github.io/debug-"
|
|
"adapter-protocol/) lets VSCode and other IDEs debug code running on any "
|
|
"supported microcontroller."
|
|
msgstr ""
|
|
"[Microsoft 디버그 어댑터 프로토콜](https://microsoft.github.io/debug-adapter-"
|
|
"protocol/)을 사용하면 VSCode나 다른 IDE 상에서 마이크로컨트롤러에서 수행중인 "
|
|
"코드를 디버깅 할 수 있습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/probe-rs.md
|
|
msgid "cargo-embed is a binary built using the probe-rs library."
|
|
msgstr "cargo-embed는 probe-rs 라이브러리를 사용하여 빌드된 바이너리입니다."
|
|
|
|
#: src/bare-metal/microcontrollers/probe-rs.md
|
|
msgid ""
|
|
"RTT (Real Time Transfers) is a mechanism to transfer data between the debug "
|
|
"host and the target through a number of ringbuffers."
|
|
msgstr ""
|
|
"RTT(Real Time Transfers)는 여러 링 버퍼를 통해 디버그 호스트와 타겟 간에 데이"
|
|
"터를 전송하는 메커니즘입니다."
|
|
|
|
#: src/bare-metal/microcontrollers/debugging.md
|
|
msgid "_Embed.toml_:"
|
|
msgstr "_Embed.toml_:"
|
|
|
|
#: src/bare-metal/microcontrollers/debugging.md
|
|
msgid "In one terminal under `src/bare-metal/microcontrollers/examples/`:"
|
|
msgstr "`src/bare-metal/microcontrollers/example/` 에 터미널을 열고:"
|
|
|
|
#: src/bare-metal/microcontrollers/debugging.md
|
|
#, fuzzy
|
|
msgid "In another terminal in the same directory:"
|
|
msgstr "다른 터미널을 띄워서 서비스가 잘 수행되고 있는지 확인합니다:"
|
|
|
|
#: src/bare-metal/microcontrollers/debugging.md
|
|
msgid "On gLinux or Debian:"
|
|
msgstr "gLinux 또는 Debian에서:"
|
|
|
|
#: src/bare-metal/microcontrollers/debugging.md
|
|
msgid "In GDB, try running:"
|
|
msgstr "GDB에서 다음을 실행해 보세요."
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
#: src/bare-metal/aps/other-projects.md
|
|
msgid "Other projects"
|
|
msgstr "다른 프로젝트"
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid "[RTIC](https://rtic.rs/)"
|
|
msgstr "[RTIC](https://rtic.rs/)"
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid "\"Real-Time Interrupt-driven Concurrency\""
|
|
msgstr ""
|
|
"\"실시간 인터럽트 기반 동시 실행(Real-Time Interrupt-driven Concurrency)\""
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid ""
|
|
"Shared resource management, message passing, task scheduling, timer queue"
|
|
msgstr "공유 리소스 관리, 메시지 전달, 태스크 스케줄링, 타이머 대기열 지원"
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid "[Embassy](https://embassy.dev/)"
|
|
msgstr "[Embassy](https://embassy.dev/)"
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid "`async` executors with priorities, timers, networking, USB"
|
|
msgstr "우선순위, 타이머, 네트워킹, USB가 포함된 `async` 실행자"
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid "[TockOS](https://www.tockos.org/documentation/getting-started)"
|
|
msgstr "[TockOS](https://www.tockos.org/documentation/getting-started)"
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid ""
|
|
"Security-focused RTOS with preemptive scheduling and Memory Protection Unit "
|
|
"support"
|
|
msgstr "선점형 스케줄링 및 MMU를 지원하는, 보안에 중점을 둔 실시간 운영체제"
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid "[Hubris](https://hubris.oxide.computer/)"
|
|
msgstr "[Hubris](https://hubris.oxide.computer/)"
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid ""
|
|
"Microkernel RTOS from Oxide Computer Company with memory protection, "
|
|
"unprivileged drivers, IPC"
|
|
msgstr ""
|
|
"Oxide Computer Company에서 만든 마이크로커널 기반 실시간 운영체제로, 메모리 "
|
|
"보호, 권한이 없이 수행되는 드라이버 등을 지원함."
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid "[Bindings for FreeRTOS](https://github.com/lobaro/FreeRTOS-rust)"
|
|
msgstr "[FreeRTOS용 바인딩](https://github.com/lobaro/FreeRTOS-rust)"
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid ""
|
|
"Some platforms have `std` implementations, e.g. [esp-idf](https://esp-rs."
|
|
"github.io/book/overview/using-the-standard-library.html)."
|
|
msgstr ""
|
|
"`std`가 구현된 플랫폼도 있습니다(예: [esp-idf](https://esp-rs.github.io/book/"
|
|
"overview/using-the-standard-library.html))."
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid "RTIC can be considered either an RTOS or a concurrency framework."
|
|
msgstr ""
|
|
"RTIC는 실시간 운영체제로 볼 수도 있고, 동시성 지원을 위한 프레임워크로 볼 수"
|
|
"도 있습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid "It doesn't include any HALs."
|
|
msgstr "HAL을 포함하지는 않습니다."
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid ""
|
|
"It uses the Cortex-M NVIC (Nested Virtual Interrupt Controller) for "
|
|
"scheduling rather than a proper kernel."
|
|
msgstr ""
|
|
"스케줄링은 커널이 아니라 Cortex-M NVIC(Nested Virtual Interrupt Controller)"
|
|
"로 구현이 됩니다."
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid "Cortex-M only."
|
|
msgstr "Cortex-M 전용입니다."
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid ""
|
|
"Google uses TockOS on the Haven microcontroller for Titan security keys."
|
|
msgstr ""
|
|
"Google에서는 Titan 보안 키에 사용되는 Haven 마이크로컨트롤러에서 TockOS를 사"
|
|
"용합니다."
|
|
|
|
#: src/bare-metal/microcontrollers/other-projects.md
|
|
msgid ""
|
|
"FreeRTOS is mostly written in C, but there are Rust bindings for writing "
|
|
"applications."
|
|
msgstr ""
|
|
"FreeRTOS는 대부분 C로 작성되지만, 애플리케이션을 Rust로 작성할 수 있도록 해 "
|
|
"주는 Rust 바인딩이 제공됩니다."
|
|
|
|
#: src/exercises/bare-metal/morning.md
|
|
msgid ""
|
|
"We will read the direction from an I2C compass, and log the readings to a "
|
|
"serial port."
|
|
msgstr "I2C 나침반에서 방향을 읽고, 읽은 값을 직렬 포트에 기록하세요."
|
|
|
|
#: src/exercises/bare-metal/morning.md src/exercises/concurrency/morning.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"After looking at the exercises, you can look at the [solutions](solutions-"
|
|
"morning.md) provided."
|
|
msgstr ""
|
|
"연습문제를 살펴 본 후, 제공된 [해답](solutions-afternoon.md)을 살펴볼 수 있습"
|
|
"니다."
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid ""
|
|
"We will read the direction from an I2C compass, and log the readings to a "
|
|
"serial port. If you have time, try displaying it on the LEDs somehow too, or "
|
|
"use the buttons somehow."
|
|
msgstr ""
|
|
"I2C 나침반에서 방향을 읽고 판독값을 직렬 포트에 기록하세요. 시간이 있으면 어"
|
|
"떻게든 LED에 표시하거나 버튼을 사용하세요."
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid "Hints:"
|
|
msgstr "힌트:"
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid ""
|
|
"Check the documentation for the [`lsm303agr`](https://docs.rs/lsm303agr/"
|
|
"latest/lsm303agr/) and [`microbit-v2`](https://docs.rs/microbit-v2/latest/"
|
|
"microbit/) crates, as well as the [micro:bit hardware](https://tech.microbit."
|
|
"org/hardware/)."
|
|
msgstr ""
|
|
"[`lsm303agr`](https://docs.rs/lsm303agr/latest/lsm303agr/) 및 [`microbit-v2`]"
|
|
"(https://docs.rs/microbit-v2/latest/microbit/) 크레이트 및 [micro:bit 하드웨"
|
|
"어](https://tech.microbit.org/hardware/)의 문서를 확인하세요."
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid ""
|
|
"The LSM303AGR Inertial Measurement Unit is connected to the internal I2C bus."
|
|
msgstr "LSM303AGR 관성 측정 장치는 내부 I2C 버스에 연결됩니다."
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid ""
|
|
"TWI is another name for I2C, so the I2C master peripheral is called TWIM."
|
|
msgstr ""
|
|
"TWI는 I2C의 또 다른 이름이므로 I2C 마스터 주변기기는 TWIM이라고 합니다."
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid ""
|
|
"The LSM303AGR driver needs something implementing the `embedded_hal::"
|
|
"blocking::i2c::WriteRead` trait. The [`microbit::hal::Twim`](https://docs.rs/"
|
|
"microbit-v2/latest/microbit/hal/struct.Twim.html) struct implements this."
|
|
msgstr ""
|
|
"LSM303AGR 드라이버에는 `embedded_hal::blocking::i2c::WriteRead` 트레잇을 구현"
|
|
"하는 것이 필요합니다. [`microbit::hal::Twim`](https://docs.rs/microbit-v2/"
|
|
"latest/microbit/hal/struct.Twim.html) 구조체가 이를 구현합니다."
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid ""
|
|
"You have a [`microbit::Board`](https://docs.rs/microbit-v2/latest/microbit/"
|
|
"struct.Board.html) struct with fields for the various pins and peripherals."
|
|
msgstr ""
|
|
"다양한 핀과 주변기기에 관한 필드가 있는 [`microbit::Board`](https://docs.rs/"
|
|
"microbit-v2/latest/microbit/struct.Board.html) 구조체가 있습니다."
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid ""
|
|
"You can also look at the [nRF52833 datasheet](https://infocenter.nordicsemi."
|
|
"com/pdf/nRF52833_PS_v1.5.pdf) if you want, but it shouldn't be necessary for "
|
|
"this exercise."
|
|
msgstr ""
|
|
"원하는 경우 [nRF52833 데이터시트](https://infocenter.nordicsemi.com/pdf/"
|
|
"nRF52833_PS_v1.5.pdf)를 확인할 수도 있지만 이 연습에서 반드시 필요한 것은 아"
|
|
"닙니다."
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid ""
|
|
"Download the [exercise template](../../comprehensive-rust-exercises.zip) and "
|
|
"look in the `compass` directory for the following files."
|
|
msgstr ""
|
|
"[연습 템플릿](../../comprehensive-rust-exercises.zip)을 다운로드하고 "
|
|
"`compass` 디렉터리에서 다음 파일을 찾습니다."
|
|
|
|
#: src/exercises/bare-metal/compass.md src/exercises/bare-metal/rtc.md
|
|
#, fuzzy
|
|
msgid "_src/main.rs_:"
|
|
msgstr "_hello_rust/src/main.rs_:"
|
|
|
|
#: src/exercises/bare-metal/compass.md src/exercises/bare-metal/rtc.md
|
|
msgid "_Cargo.toml_ (you shouldn't need to change this):"
|
|
msgstr "_Cargo.toml_ (변경할 필요가 없음):"
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid "_Embed.toml_ (you shouldn't need to change this):"
|
|
msgstr "_Embed.toml_ (변경할 필요가 없음):"
|
|
|
|
#: src/exercises/bare-metal/compass.md src/exercises/bare-metal/rtc.md
|
|
msgid "_.cargo/config.toml_ (you shouldn't need to change this):"
|
|
msgstr "_.cargo/config.toml_ (변경할 필요가 없음):"
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid "See the serial output on Linux with:"
|
|
msgstr "다음을 사용하여 Linux에서 직렬 출력을 확인하세요."
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid ""
|
|
"Or on Mac OS something like (the device name may be slightly different):"
|
|
msgstr "또는 다음과 같이 Mac OS(기기 이름은 약간 다를 수 있음)에서 확인하세요."
|
|
|
|
#: src/exercises/bare-metal/compass.md
|
|
msgid "Use Ctrl+A Ctrl+Q to quit picocom."
|
|
msgstr "Ctrl+A Ctrl+Q를 사용하여 picocom을 종료합니다."
|
|
|
|
#: src/exercises/bare-metal/solutions-morning.md
|
|
#, fuzzy
|
|
msgid "Bare Metal Rust Morning Exercise"
|
|
msgstr "Bare Metal Rust 오전 연습"
|
|
|
|
#: src/exercises/bare-metal/solutions-morning.md
|
|
msgid "([back to exercise](compass.md))"
|
|
msgstr "([연습문제로 돌아가기](compass.md))"
|
|
|
|
#: src/exercises/bare-metal/solutions-morning.md
|
|
msgid "// Configure serial port.\n"
|
|
msgstr "// 직렬 포트를 설정하세요.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-morning.md
|
|
msgid "// Use the system timer as a delay provider.\n"
|
|
msgstr ""
|
|
|
|
#: src/exercises/bare-metal/solutions-morning.md
|
|
msgid "// Set up the I2C controller and Inertial Measurement Unit.\n"
|
|
msgstr "// I2C 컨트롤러와 관성 측정 장치를 설정합니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-morning.md
|
|
msgid "\"Setting up IMU...\""
|
|
msgstr "\"IMU 설정 중...\""
|
|
|
|
#: src/exercises/bare-metal/solutions-morning.md
|
|
msgid "// Set up display and timer.\n"
|
|
msgstr "// 디스플레이 및 타이머를 설정합니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-morning.md
|
|
msgid "\"Ready.\""
|
|
msgstr "\"Ready\""
|
|
|
|
#: src/exercises/bare-metal/solutions-morning.md
|
|
msgid "// Read compass data and log it to the serial port.\n"
|
|
msgstr "// 나침반 데이터를 읽고 직렬 포트에 기록합니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-morning.md
|
|
msgid "\"{},{},{}\\t{},{},{}\""
|
|
msgstr "\"{},{},{}\\t{},{},{}\""
|
|
|
|
#: src/exercises/bare-metal/solutions-morning.md
|
|
msgid ""
|
|
"// If button A is pressed, switch to the next mode and briefly blink all "
|
|
"LEDs\n"
|
|
" // on.\n"
|
|
msgstr "// 버튼 A를 누르면 다음 모드로 전환되고 모든 LED가 잠시 깜박입니다.\n"
|
|
|
|
#: src/bare-metal/aps.md
|
|
msgid "Application processors"
|
|
msgstr "애플리케이션 프로세서"
|
|
|
|
#: src/bare-metal/aps.md
|
|
msgid ""
|
|
"So far we've talked about microcontrollers, such as the Arm Cortex-M series. "
|
|
"Now let's try writing something for Cortex-A. For simplicity we'll just work "
|
|
"with QEMU's aarch64 ['virt'](https://qemu-project.gitlab.io/qemu/system/arm/"
|
|
"virt.html) board."
|
|
msgstr ""
|
|
"지금까지 Arm Cortex-M 시리즈와 같은 마이크로컨트롤러에 관해 알아봤습니다. 이"
|
|
"제 애플리케이션 프로세서인 Cortex-A를 위한 코드를 작성해 보겠습니다. 편의상 "
|
|
"QEMU의 aarch64 ['virt'](https://qemu-project.gitlab.io/qemu/system/arm/virt."
|
|
"html) 보드를 사용합니다."
|
|
|
|
#: src/bare-metal/aps.md
|
|
msgid ""
|
|
"Broadly speaking, microcontrollers don't have an MMU or multiple levels of "
|
|
"privilege (exception levels on Arm CPUs, rings on x86), while application "
|
|
"processors do."
|
|
msgstr ""
|
|
"일반적으로 마이크로컨트롤러에는 MMU 또는 다중 레벨 권한(Arm CPU에서는 익셉션 "
|
|
"레벨(exception level), x86에서는 링(ring))이 없습니다. 애플리케이션 프로세서"
|
|
"는 이들을 가지고 있습니다."
|
|
|
|
#: src/bare-metal/aps.md
|
|
msgid ""
|
|
"QEMU supports emulating various different machines or board models for each "
|
|
"architecture. The 'virt' board doesn't correspond to any particular real "
|
|
"hardware, but is designed purely for virtual machines."
|
|
msgstr ""
|
|
"QEMU는 아키텍처별로 다양한 머신 또는 보드 모델을 에뮬레이션할 수 있습니다. "
|
|
"'virt' 보드는 특정 실제 하드웨어를 에뮬레이션 하지 않으며, 가상 머신용으로만 "
|
|
"설계되었습니다."
|
|
|
|
#: src/bare-metal/aps/entry-point.md
|
|
msgid ""
|
|
"Before we can start running Rust code, we need to do some initialisation."
|
|
msgstr "Rust 코드 실행을 시작하기 전에 몇 가지 초기화를 실행해야 합니다."
|
|
|
|
#: src/bare-metal/aps/entry-point.md
|
|
msgid ""
|
|
"```armasm\n"
|
|
".section .init.entry, \"ax\"\n"
|
|
".global entry\n"
|
|
"entry:\n"
|
|
" /*\n"
|
|
" * Load and apply the memory management configuration, ready to enable "
|
|
"MMU and\n"
|
|
" * caches.\n"
|
|
" */\n"
|
|
" adrp x30, idmap\n"
|
|
" msr ttbr0_el1, x30\n"
|
|
"\n"
|
|
" mov_i x30, .Lmairval\n"
|
|
" msr mair_el1, x30\n"
|
|
"\n"
|
|
" mov_i x30, .Ltcrval\n"
|
|
" /* Copy the supported PA range into TCR_EL1.IPS. */\n"
|
|
" mrs x29, id_aa64mmfr0_el1\n"
|
|
" bfi x30, x29, #32, #4\n"
|
|
"\n"
|
|
" msr tcr_el1, x30\n"
|
|
"\n"
|
|
" mov_i x30, .Lsctlrval\n"
|
|
"\n"
|
|
" /*\n"
|
|
" * Ensure everything before this point has completed, then invalidate "
|
|
"any\n"
|
|
" * potentially stale local TLB entries before they start being used.\n"
|
|
" */\n"
|
|
" isb\n"
|
|
" tlbi vmalle1\n"
|
|
" ic iallu\n"
|
|
" dsb nsh\n"
|
|
" isb\n"
|
|
"\n"
|
|
" /*\n"
|
|
" * Configure sctlr_el1 to enable MMU and cache and don't proceed until "
|
|
"this\n"
|
|
" * has completed.\n"
|
|
" */\n"
|
|
" msr sctlr_el1, x30\n"
|
|
" isb\n"
|
|
"\n"
|
|
" /* Disable trapping floating point access in EL1. */\n"
|
|
" mrs x30, cpacr_el1\n"
|
|
" orr x30, x30, #(0x3 << 20)\n"
|
|
" msr cpacr_el1, x30\n"
|
|
" isb\n"
|
|
"\n"
|
|
" /* Zero out the bss section. */\n"
|
|
" adr_l x29, bss_begin\n"
|
|
" adr_l x30, bss_end\n"
|
|
"0: cmp x29, x30\n"
|
|
" b.hs 1f\n"
|
|
" stp xzr, xzr, [x29], #16\n"
|
|
" b 0b\n"
|
|
"\n"
|
|
"1: /* Prepare the stack. */\n"
|
|
" adr_l x30, boot_stack_end\n"
|
|
" mov sp, x30\n"
|
|
"\n"
|
|
" /* Set up exception vector. */\n"
|
|
" adr x30, vector_table_el1\n"
|
|
" msr vbar_el1, x30\n"
|
|
"\n"
|
|
" /* Call into Rust code. */\n"
|
|
" bl main\n"
|
|
"\n"
|
|
" /* Loop forever waiting for interrupts. */\n"
|
|
"2: wfi\n"
|
|
" b 2b\n"
|
|
"```"
|
|
msgstr ""
|
|
"```armasm\n"
|
|
".section .init.entry, \"ax\"\n"
|
|
".global entry\n"
|
|
"entry:\n"
|
|
" /*\n"
|
|
" * 메모리 관리 구성을 로드하고 적용합니다. MMU와 캐시를\n"
|
|
" * 사용 설정할 준비가 되었습니다. .\n"
|
|
" */\n"
|
|
" adrp x30, idmap\n"
|
|
" msr ttbr0_el1, x30\n"
|
|
"\n"
|
|
" mov_i x30, .Lmairval\n"
|
|
" msr mair_el1, x30\n"
|
|
"\n"
|
|
" mov_i x30, .Ltcrval\n"
|
|
" /* 지원되는 PA 범위를 TCR_EL1.IPS에 복사합니다. */\n"
|
|
" mrs x29, id_aa64mmfr0_el1\n"
|
|
" bfi x30, x29, #32, #4\n"
|
|
"\n"
|
|
" msr tcr_el1, x30\n"
|
|
"\n"
|
|
" mov_i x30, .Lsctlrval\n"
|
|
"\n"
|
|
" /*\n"
|
|
" * 이 지점 앞에 오는 모든 내용이 완료되었는지 확인하고\n"
|
|
" * 오래된 로컬 TLB 항목을 사용하기 전에 무효화합니다.\n"
|
|
" */\n"
|
|
" isb\n"
|
|
" tlbi vmalle1\n"
|
|
" ic iallu\n"
|
|
" dsb nsh\n"
|
|
" isb\n"
|
|
"\n"
|
|
" /*\n"
|
|
" * MMU와 캐시를 사용하도록 sctlr_el1을 구성하고 이 작업이\n"
|
|
" * 완료될 때까지 진행하지 않습니다.\n"
|
|
" */\n"
|
|
" msr sctlr_el1, x30\n"
|
|
" isb\n"
|
|
"\n"
|
|
" /* EL1에서 트래핑 부동 소수점 액세스를 사용 중지합니다. */\n"
|
|
" mrs x30, cpacr_el1\n"
|
|
" orr x30, x30, #(0x3 << 20)\n"
|
|
" msr cpacr_el1, x30\n"
|
|
" isb\n"
|
|
"\n"
|
|
" /* bss 섹션을 0으로 만듭니다. */\n"
|
|
" adr_l x29, bss_begin\n"
|
|
" adr_l x30, bss_end\n"
|
|
"0: cmp x29, x30\n"
|
|
" b.hs 1f\n"
|
|
" stp xzr, xzr, [x29], #16\n"
|
|
" b 0b\n"
|
|
"\n"
|
|
"1: /* 스택을 준비합니다. */\n"
|
|
" adr_l x30, boot_stack_end\n"
|
|
" mov sp, x30\n"
|
|
"\n"
|
|
" /* 예외 벡터를 설정합니다. */\n"
|
|
" adr x30, vector_table_el1\n"
|
|
" msr vbar_el1, x30\n"
|
|
"\n"
|
|
" /* Rust 코드를 호출합니다. */\n"
|
|
" bl main\n"
|
|
"\n"
|
|
" /* 루프가 인터럽트를 영원히 기다립니다. */\n"
|
|
"2: wfi\n"
|
|
" b 2b\n"
|
|
"```"
|
|
|
|
#: src/bare-metal/aps/entry-point.md
|
|
msgid ""
|
|
"This is the same as it would be for C: initialising the processor state, "
|
|
"zeroing the BSS, and setting up the stack pointer."
|
|
msgstr ""
|
|
"이는 C의 경우와 동일합니다. 프로세서 상태를 초기화하고 BSS를 0으로 설정하고 "
|
|
"스택 포인터를 설정합니다."
|
|
|
|
#: src/bare-metal/aps/entry-point.md
|
|
msgid ""
|
|
"The BSS (block starting symbol, for historical reasons) is the part of the "
|
|
"object file which containing statically allocated variables which are "
|
|
"initialised to zero. They are omitted from the image, to avoid wasting space "
|
|
"on zeroes. The compiler assumes that the loader will take care of zeroing "
|
|
"them."
|
|
msgstr ""
|
|
"BSS(역사적인 이유로, 블록 시작 기호 block starting symbol 이라고 불림)는 오브"
|
|
"젝트 파일에서 0으로 초기화된 정적으로 할당된 변수들을 담고 있습니다. BSS는 실"
|
|
"제로 이미지에 포함되지는 않습니다. 어차피 0으로 초기화 될 것이기 때문입니다. "
|
|
"컴파일러는 로더 프로그램이 BSS에 속하는 변수들을 0으로 초기화 할 것으로기대하"
|
|
"고 오브젝트 파일을 만듭니다."
|
|
|
|
#: src/bare-metal/aps/entry-point.md
|
|
msgid ""
|
|
"The BSS may already be zeroed, depending on how memory is initialised and "
|
|
"the image is loaded, but we zero it to be sure."
|
|
msgstr ""
|
|
"메모리가 초기화되고 이미지가 로드되는 방식에 따라 BSS가 이미 0으로 설정되었"
|
|
"을 수도 있지만 확실히 하기 위해 0으로 설정합니다."
|
|
|
|
#: src/bare-metal/aps/entry-point.md
|
|
msgid ""
|
|
"We need to enable the MMU and cache before reading or writing any memory. If "
|
|
"we don't:"
|
|
msgstr ""
|
|
"메모리를 읽거나 쓰기 전에 MMU와 캐시를 사용 설정해야 합니다. 그러지 않으면 다"
|
|
"음과 같은 상황이 발생할 수 있습니다."
|
|
|
|
#: src/bare-metal/aps/entry-point.md
|
|
msgid ""
|
|
"Unaligned accesses will fault. We build the Rust code for the `aarch64-"
|
|
"unknown-none` target which sets `+strict-align` to prevent the compiler "
|
|
"generating unaligned accesses, so it should be fine in this case, but this "
|
|
"is not necessarily the case in general."
|
|
msgstr ""
|
|
"정렬되지 않은 액세스에 오류가 발생합니다. 컴파일러가 정렬되지 않은 액세스를 "
|
|
"생성하지 않도록 `+strict-align`을 설정하는 `aarch64-unknown-none` 타겟의 "
|
|
"Rust 코드를 빌드하므로 이 경우에는 문제가 없지만, 일반적으로 반드시 그런 것"
|
|
"은 아닙니다."
|
|
|
|
#: src/bare-metal/aps/entry-point.md
|
|
msgid ""
|
|
"If it were running in a VM, this can lead to cache coherency issues. The "
|
|
"problem is that the VM is accessing memory directly with the cache disabled, "
|
|
"while the host has cacheable aliases to the same memory. Even if the host "
|
|
"doesn't explicitly access the memory, speculative accesses can lead to cache "
|
|
"fills, and then changes from one or the other will get lost when the cache "
|
|
"is cleaned or the VM enables the cache. (Cache is keyed by physical address, "
|
|
"not VA or IPA.)"
|
|
msgstr ""
|
|
"VM에서 실행한다면 캐시 일관성 문제가 발생할 수 있습니다. 문제는 VM은 캐시가 "
|
|
"사용 중지된 상태로 메모리에 직접 액세스하는 반면 호스트에는 동일한 메모리에 "
|
|
"대해 캐시할 수 있는 별칭이 있다는 점입니다. 호스트가 메모리에 명시적으로 액세"
|
|
"스하지 않더라도 추측 액세스는 캐시 채우기로 이어질 수 있으며, 캐시가 정리되거"
|
|
"나 VM이 캐시를 사용 설정하면 둘 중 하나의 변경사항이 손실됩니다. 캐시는 VA 또"
|
|
"는 IPA가 아닌 실제 주소로 키가 지정됩니다."
|
|
|
|
#: src/bare-metal/aps/entry-point.md
|
|
msgid ""
|
|
"For simplicity, we just use a hardcoded pagetable (see `idmap.S`) which "
|
|
"identity maps the first 1 GiB of address space for devices, the next 1 GiB "
|
|
"for DRAM, and another 1 GiB higher up for more devices. This matches the "
|
|
"memory layout that QEMU uses."
|
|
msgstr ""
|
|
"편의상 기기용 주소 공간의 처음 1GiB, DRAM용 다음 1GiB, 더 많은 기기를 위한 "
|
|
"또 다른 1GiB를 ID 매핑하는 하드코딩된 페이지 테이블(`idmap.S` 참고)을 사용합"
|
|
"니다. 이는 QEMU에서 사용하는 메모리 레이아웃과 일치합니다."
|
|
|
|
#: src/bare-metal/aps/entry-point.md
|
|
msgid ""
|
|
"We also set up the exception vector (`vbar_el1`), which we'll see more about "
|
|
"later."
|
|
msgstr ""
|
|
"예외 벡터(`vbar_el1`)도 설정합니다. 이에 관해서는 나중에 자세히 알아봅니다."
|
|
|
|
#: src/bare-metal/aps/entry-point.md
|
|
msgid ""
|
|
"All examples this afternoon assume we will be running at exception level 1 "
|
|
"(EL1). If you need to run at a different exception level you'll need to "
|
|
"modify `entry.S` accordingly."
|
|
msgstr ""
|
|
"오늘 오후의 모든 예에서는 예외 수준 1(EL1)에서 실행한다고 가정합니다. 다른 예"
|
|
"외 수준에서 실행해야 하는 경우 이에 따라 `entry.S`를 수정해야 합니다."
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid "Inline assembly"
|
|
msgstr "인라인 어셈블리"
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Sometimes we need to use assembly to do things that aren't possible with "
|
|
"Rust code. For example, to make an HVC (hypervisor call) to tell the "
|
|
"firmware to power off the system:"
|
|
msgstr ""
|
|
"가끔 Rust 코드로는 구현이 불가능한 작업들이 있으며, 이 경우 어셈블리를 사용해"
|
|
"야 합니다. 예를 들어 펌웨어를 향해서 시스템 전원을 끄라고 "
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid ""
|
|
"// Safe because this only uses the declared registers and doesn't do\n"
|
|
" // anything with memory.\n"
|
|
msgstr ""
|
|
"// 선언된 레지스터만 사용하고 메모리로는\n"
|
|
" // 아무것도 하지 않으므로 안전합니다.\n"
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid "\"hvc #0\""
|
|
msgstr "\"hvc #0\""
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid "\"w0\""
|
|
msgstr "\"w0\""
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid "\"w1\""
|
|
msgstr "\"w1\""
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid "\"w2\""
|
|
msgstr "\"w2\""
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid "\"w3\""
|
|
msgstr "\"w3\""
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid "\"w4\""
|
|
msgstr "\"w4\""
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid "\"w5\""
|
|
msgstr "\"w5\""
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid "\"w6\""
|
|
msgstr "\"w6\""
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid "\"w7\""
|
|
msgstr "\"w7\""
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid ""
|
|
"(If you actually want to do this, use the [`smccc`](https://crates.io/crates/"
|
|
"smccc) crate which has wrappers for all these functions.)"
|
|
msgstr ""
|
|
"실제로 이를 실행하려면 이러한 모든 함수를 위한 래퍼가 포함된 [`smccc`]"
|
|
"(https://crates.io/crates/smccc) 크레이트를 사용하세요."
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid ""
|
|
"PSCI is the Arm Power State Coordination Interface, a standard set of "
|
|
"functions to manage system and CPU power states, among other things. It is "
|
|
"implemented by EL3 firmware and hypervisors on many systems."
|
|
msgstr ""
|
|
"PSCI (Power State Coordination Interface)는 시스템 및 CPU 전원 상태를 관리하"
|
|
"는 Arm의 표준 인터페이스입니다. 이 인터페이스는 EL3 펌웨어와 하이퍼바이저에 "
|
|
"의해 구현됩니다."
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid ""
|
|
"The `0 => _` syntax means initialise the register to 0 before running the "
|
|
"inline assembly code, and ignore its contents afterwards. We need to use "
|
|
"`inout` rather than `in` because the call could potentially clobber the "
|
|
"contents of the registers."
|
|
msgstr ""
|
|
"`0 => _` 문법은 인라인 어셈블리 코드를 실행하기 전에 레지스터를 0으로 초기화"
|
|
"하고 그 후에는 그 레지스터의 값을 무시함을 의미합니다. 호출 시 레지스터의 값"
|
|
"이 덮어 써질 수 있으므로 `in` 대신 `inout`을 사용해야 합니다."
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid ""
|
|
"This `main` function needs to be `#[no_mangle]` and `extern \"C\"` because "
|
|
"it is called from our entry point in `entry.S`."
|
|
msgstr ""
|
|
"이 `main` 함수는 `#[no_mangle]` 및 `extern \"C\"`여야 합니다. 왜냐하면 이 함"
|
|
"수는 Rust 코드가 아닌, 어셈블러로 작성된 `entry.S`에서 호출되기 때문입니다."
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid ""
|
|
"`_x0`–`_x3` are the values of registers `x0`–`x3`, which are conventionally "
|
|
"used by the bootloader to pass things like a pointer to the device tree. "
|
|
"According to the standard aarch64 calling convention (which is what `extern "
|
|
"\"C\"` specifies to use), registers `x0`–`x7` are used for the first 8 "
|
|
"arguments passed to a function, so `entry.S` doesn't need to do anything "
|
|
"special except make sure it doesn't change these registers."
|
|
msgstr ""
|
|
"`_x0`–`_x3`는 `x0`에서 `x3` 레지스터들의 값입니다. 이 레지스터들은 일반적으"
|
|
"로 부트로더에서 디바이스 트리에 대한 포인터 등을 전달할 때 사용됩니다. 표준 "
|
|
"aarch64 호출 규약(`extern \"C\"`에서 사용하도록 지정)에 따라 레지스터 `x0`에"
|
|
"서 `x7`이 함수에 전달된 처음 8개 인수에 사용되므로 `entry.S`는 이러한 레지스"
|
|
"터를 변경하지 않는지 확인하는 것 외에는 특별히 할 작업이 없습니다."
|
|
|
|
#: src/bare-metal/aps/inline-assembly.md
|
|
msgid ""
|
|
"Run the example in QEMU with `make qemu_psci` under `src/bare-metal/aps/"
|
|
"examples`."
|
|
msgstr ""
|
|
"`src/bare-metal/aps/examples`에서 `make qemu_psci`를 입력하면 예제 코드가 "
|
|
"QEMU에서 수행됩니다."
|
|
|
|
#: src/bare-metal/aps/mmio.md
|
|
msgid "Volatile memory access for MMIO"
|
|
msgstr "MMIO를 위한 휘발성(volatile) 메모리 액세스"
|
|
|
|
#: src/bare-metal/aps/mmio.md
|
|
msgid "Use `pointer::read_volatile` and `pointer::write_volatile`."
|
|
msgstr "`pointer::read_volatile` 및 `pointer::write_volatile`을 사용하세요."
|
|
|
|
#: src/bare-metal/aps/mmio.md
|
|
msgid "Never hold a reference."
|
|
msgstr "참조를 유지하지 마세요."
|
|
|
|
#: src/bare-metal/aps/mmio.md
|
|
msgid ""
|
|
"`addr_of!` lets you get fields of structs without creating an intermediate "
|
|
"reference."
|
|
msgstr ""
|
|
"`addr_of!` 를 사용하면 임시 용도의 참조를 만들지 않고도 구조체의 필드를 읽을 "
|
|
"수 있습니다."
|
|
|
|
#: src/bare-metal/aps/mmio.md
|
|
msgid ""
|
|
"Volatile access: read or write operations may have side-effects, so prevent "
|
|
"the compiler or hardware from reordering, duplicating or eliding them."
|
|
msgstr ""
|
|
"휘발성(volatile) 액세스: 읽기 또는 쓰기 작업이 부수 효과(side effect)를 동반"
|
|
"할 수 있기 때문에 컴파일러나 하드웨어가 임의로 이를 읽기 쓰기 작업의 순서를 "
|
|
"바꾸거나, 중복해서 수행하거나 또는 제거하지 못하게 합니다."
|
|
|
|
#: src/bare-metal/aps/mmio.md
|
|
msgid ""
|
|
"Usually if you write and then read, e.g. via a mutable reference, the "
|
|
"compiler may assume that the value read is the same as the value just "
|
|
"written, and not bother actually reading memory."
|
|
msgstr ""
|
|
"일반적으로 쓰고 난 후 읽으면(예: 변경 가능한 참조를 통해) 컴파일러는 읽은 값"
|
|
"이 방금 쓴 값과 동일하다고 가정하고 실제로 메모리를 읽지 않을 수 있습니다."
|
|
|
|
#: src/bare-metal/aps/mmio.md
|
|
msgid ""
|
|
"Some existing crates for volatile access to hardware do hold references, but "
|
|
"this is unsound. Whenever a reference exist, the compiler may choose to "
|
|
"dereference it."
|
|
msgstr ""
|
|
"하드웨어에 대한 휘발성 액세스를 위한 일부 기존 크레이트는 참조를 유지하지만 "
|
|
"이는 올바른 것이 아닙니다. 참조가 있을 때마다 컴파일러는 이를 역참조하도록 선"
|
|
"택할 수 있습니다."
|
|
|
|
#: src/bare-metal/aps/mmio.md
|
|
msgid ""
|
|
"Use the `addr_of!` macro to get struct field pointers from a pointer to the "
|
|
"struct."
|
|
msgstr ""
|
|
"`addr_of!` 매크로를 사용하여 구조체 포인터에서 구조체 필드 포인터를 가져옵니"
|
|
"다."
|
|
|
|
#: src/bare-metal/aps/uart.md
|
|
msgid "Let's write a UART driver"
|
|
msgstr "UART 드라이버 작성"
|
|
|
|
#: src/bare-metal/aps/uart.md
|
|
msgid ""
|
|
"The QEMU 'virt' machine has a [PL011](https://developer.arm.com/"
|
|
"documentation/ddi0183/g) UART, so let's write a driver for that."
|
|
msgstr ""
|
|
"QEMU의 'virt' 보드에는 [PL011](https://developer.arm.com/documentation/"
|
|
"ddi0183/g) UART가 있으므로 이를 위한 드라이버를 작성해 보겠습니다."
|
|
|
|
#: src/bare-metal/aps/uart.md
|
|
msgid "/// Minimal driver for a PL011 UART.\n"
|
|
msgstr "/// PL011 UART의 최소 드라이버입니다.\n"
|
|
|
|
#: src/bare-metal/aps/uart.md src/bare-metal/aps/better-uart/driver.md
|
|
msgid ""
|
|
"/// Constructs a new instance of the UART driver for a PL011 device at the\n"
|
|
" /// given base address.\n"
|
|
" ///\n"
|
|
" /// # Safety\n"
|
|
" ///\n"
|
|
" /// The given base address must point to the 8 MMIO control registers of "
|
|
"a\n"
|
|
" /// PL011 device, which must be mapped into the address space of the "
|
|
"process\n"
|
|
" /// as device memory and not have any other aliases.\n"
|
|
msgstr ""
|
|
"/// 지정된 기본 주소에 PL011 기기에 대한 UART 드라이버의 새 인스턴스를\n"
|
|
" /// 생성합니다.\n"
|
|
" ///\n"
|
|
" /// # 안전\n"
|
|
" ///\n"
|
|
" /// 지정된 기본 주소는 PL011 기기의\n"
|
|
" /// MMIO 제어 레지스터 8개를 가리켜야 하며,\n"
|
|
" /// 이는 프로세스의 주소 공간에 기기 메모리로\n"
|
|
" /// 매핑되어야 하며 다른 별칭은 없어야 합니다.\n"
|
|
|
|
#: src/bare-metal/aps/uart.md src/bare-metal/aps/better-uart/driver.md
|
|
msgid "/// Writes a single byte to the UART.\n"
|
|
msgstr "/// UART에 단일 바이트를 씁니다.\n"
|
|
|
|
#: src/bare-metal/aps/uart.md src/bare-metal/aps/better-uart/driver.md
|
|
msgid "// Wait until there is room in the TX buffer.\n"
|
|
msgstr "// TX 버퍼에 공간이 확보될 때까지 기다립니다.\n"
|
|
|
|
#: src/bare-metal/aps/uart.md
|
|
msgid ""
|
|
"// Safe because we know that the base address points to the control\n"
|
|
" // registers of a PL011 device which is appropriately mapped.\n"
|
|
msgstr ""
|
|
"// 기본 주소가 적절하게 매핑된 PL011 기기의 제어 레지스터를\n"
|
|
" // 가리키고 있으므로 안전합니다.\n"
|
|
|
|
#: src/bare-metal/aps/uart.md src/bare-metal/aps/better-uart/driver.md
|
|
msgid "// Write to the TX buffer.\n"
|
|
msgstr "// TX 버퍼에 씁니다.\n"
|
|
|
|
#: src/bare-metal/aps/uart.md src/bare-metal/aps/better-uart/driver.md
|
|
msgid "// Wait until the UART is no longer busy.\n"
|
|
msgstr "// UART가 더 이상 사용 중이 아닐 때까지 기다립니다.\n"
|
|
|
|
#: src/bare-metal/aps/uart.md
|
|
msgid ""
|
|
"Note that `Uart::new` is unsafe while the other methods are safe. This is "
|
|
"because as long as the caller of `Uart::new` guarantees that its safety "
|
|
"requirements are met (i.e. that there is only ever one instance of the "
|
|
"driver for a given UART, and nothing else aliasing its address space), then "
|
|
"it is always safe to call `write_byte` later because we can assume the "
|
|
"necessary preconditions."
|
|
msgstr ""
|
|
"`Uart::new`는 안전하지 않지만(usafe), 그 외 다른 메서드들은 안전한(safe) 점"
|
|
"에 주목하세요.다른 메서드들이 안전할 수 있는 이유는, `Uart::new`의 안전 요구"
|
|
"사항(즉, 지정된 UART의 드라이버 인스턴스가 하나만 있으며 주소 공간에 별칭을 "
|
|
"지정하는 다른 항목이 없음) 이 만족되기만 하면 `write_byte`와 같은 함수를 안전"
|
|
"하게 호출하는데 있어서 필요한 모든 전제조건이 만족되기 때문입니다."
|
|
|
|
#: src/bare-metal/aps/uart.md
|
|
msgid ""
|
|
"We could have done it the other way around (making `new` safe but "
|
|
"`write_byte` unsafe), but that would be much less convenient to use as every "
|
|
"place that calls `write_byte` would need to reason about the safety"
|
|
msgstr ""
|
|
"반대 방법으로도 실행할 수 있지만(`new`를 안전하게 만들고 `write_byte`를 안전"
|
|
"하지 않게 만듦) 이는 `write_byte`를 호출하는 모든 위치에서 안전성에 관해 추론"
|
|
"해야 하므로 사용 편의성이 훨씬 떨어집니다."
|
|
|
|
#: src/bare-metal/aps/uart.md
|
|
msgid ""
|
|
"This is a common pattern for writing safe wrappers of unsafe code: moving "
|
|
"the burden of proof for soundness from a large number of places to a smaller "
|
|
"number of places."
|
|
msgstr ""
|
|
"이는 안전하지 않은 코드의 안전한 래퍼를 작성하는 일반적인 패턴입니다. 안전에 "
|
|
"관한 증명 부담을 여러 많은 위치에서 소수의 위치로 옮기는 것입니다."
|
|
|
|
#: src/bare-metal/aps/uart/traits.md
|
|
#, fuzzy
|
|
msgid "More traits"
|
|
msgstr "트레잇(Trait)"
|
|
|
|
#: src/bare-metal/aps/uart/traits.md
|
|
msgid ""
|
|
"We derived the `Debug` trait. It would be useful to implement a few more "
|
|
"traits too."
|
|
msgstr ""
|
|
"`Debug` 트레잇을 상속했습니다. 몇 가지 트레잇을 추가로 더 구현하는 것도 유용"
|
|
"할 수 있습니다."
|
|
|
|
#: src/bare-metal/aps/uart/traits.md
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid ""
|
|
"// Safe because it just contains a pointer to device memory, which can be\n"
|
|
"// accessed from any context.\n"
|
|
msgstr ""
|
|
"// 모든 컨텍스트에서 액세스할 수 있는 기기 메모리에 대한\n"
|
|
"// 포인터만 포함하므로 안전합니다.\n"
|
|
|
|
#: src/bare-metal/aps/uart/traits.md
|
|
msgid ""
|
|
"Implementing `Write` lets us use the `write!` and `writeln!` macros with our "
|
|
"`Uart` type."
|
|
msgstr ""
|
|
"`Write`를 구현하면 `write!` 및 `writeln!` 매크로를 `Uart` 타입과 함께 사용할 "
|
|
"수 있습니다."
|
|
|
|
#: src/bare-metal/aps/uart/traits.md
|
|
msgid ""
|
|
"Run the example in QEMU with `make qemu_minimal` under `src/bare-metal/aps/"
|
|
"examples`."
|
|
msgstr ""
|
|
"`src/bare-metal/aps/examples`에서 `make qemu_minimal`을 사용하여 QEMU에서 예"
|
|
"를 실행합니다."
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "A better UART driver"
|
|
msgstr "더 나은 UART 드라이버"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid ""
|
|
"The PL011 actually has [a bunch more registers](https://developer.arm.com/"
|
|
"documentation/ddi0183/g/programmers-model/summary-of-registers), and adding "
|
|
"offsets to construct pointers to access them is error-prone and hard to "
|
|
"read. Plus, some of them are bit fields which would be nice to access in a "
|
|
"structured way."
|
|
msgstr ""
|
|
"PL011에는 실제로 [훨씬 더 많은 레지스터](https://developer.arm.com/"
|
|
"documentation/ddi0183/g/programmers-model/summary-of-registers)가 있으며, 이"
|
|
"에 액세스할 포인터를 구성하기 위해 오프셋을 추가하면 오류가 발생하기 쉽고 읽"
|
|
"기 어렵습니다. 또한 그중 일부는 구조화된 방식으로 액세스할 수 있는 비트 필드"
|
|
"입니다."
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "Offset"
|
|
msgstr "오프셋"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "Register name"
|
|
msgstr "레지스터 이름"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "Width"
|
|
msgstr "너비"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x00"
|
|
msgstr "0x00"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "DR"
|
|
msgstr "DR"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "12"
|
|
msgstr "12"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x04"
|
|
msgstr "0x04"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "RSR"
|
|
msgstr "RSR"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x18"
|
|
msgstr "0x18"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "FR"
|
|
msgstr "FR"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "9"
|
|
msgstr "9"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x20"
|
|
msgstr "0x20"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "ILPR"
|
|
msgstr "ILPR"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x24"
|
|
msgstr "0x24"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "IBRD"
|
|
msgstr "IBRD"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "16"
|
|
msgstr "16"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x28"
|
|
msgstr "0x28"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "FBRD"
|
|
msgstr "FBRD"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x2c"
|
|
msgstr "0x2c"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "LCR_H"
|
|
msgstr "LCR_H"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x30"
|
|
msgstr "0x30"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "CR"
|
|
msgstr "CR"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x34"
|
|
msgstr "0x34"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "IFLS"
|
|
msgstr "IFLS"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x38"
|
|
msgstr "0x38"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "IMSC"
|
|
msgstr "IMSC"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "11"
|
|
msgstr "11"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x3c"
|
|
msgstr "0x3c"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "RIS"
|
|
msgstr "RIS"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x40"
|
|
msgstr "0x40"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "MIS"
|
|
msgstr "MIS"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x44"
|
|
msgstr "0x44"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "ICR"
|
|
msgstr "ICR"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "0x48"
|
|
msgstr "0x48"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "DMACR"
|
|
msgstr "DMACR"
|
|
|
|
#: src/bare-metal/aps/better-uart.md
|
|
msgid "There are also some ID registers which have been omitted for brevity."
|
|
msgstr "간결성을 위해 일부 ID 레지스터는 생략되었습니다."
|
|
|
|
#: src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid ""
|
|
"The [`bitflags`](https://crates.io/crates/bitflags) crate is useful for "
|
|
"working with bitflags."
|
|
msgstr ""
|
|
"[`bitflags`](https://crates.io/crates/bitflags) 크레이트는 비트플래그를 사용"
|
|
"하는 데 유용합니다."
|
|
|
|
#: src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid "/// Flags from the UART flag register.\n"
|
|
msgstr "/// UART 플래그 레지스터의 플래그입니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid "/// Clear to send.\n"
|
|
msgstr "/// 보내려면 지웁니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid "/// Data set ready.\n"
|
|
msgstr "/// 데이터 세트가 준비되었습니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid "/// Data carrier detect.\n"
|
|
msgstr "/// 데이터 이동통신사 감지\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid "/// UART busy transmitting data.\n"
|
|
msgstr "/// UART에서 데이터를 전송 중입니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid "/// Receive FIFO is empty.\n"
|
|
msgstr "/// 수신 FIFO가 비어 있습니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid "/// Transmit FIFO is full.\n"
|
|
msgstr "/// 전송 FIFO가 가득 찼습니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid "/// Receive FIFO is full.\n"
|
|
msgstr "/// 수신 FIFO가 가득 찼습니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid "/// Transmit FIFO is empty.\n"
|
|
msgstr "/// 전송 FIFO가 비어 있습니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid "/// Ring indicator.\n"
|
|
msgstr "/// 벨소리 표시기입니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/bitflags.md
|
|
msgid ""
|
|
"The `bitflags!` macro creates a newtype something like `Flags(u16)`, along "
|
|
"with a bunch of method implementations to get and set flags."
|
|
msgstr ""
|
|
"`bitflags!` 매크로는 플래그를 가져오고 설정하기 위한 여러 메서드 구현과 함께 "
|
|
"`Flags(u16)`와 같은 새로운 타입을 생성합니다."
|
|
|
|
#: src/bare-metal/aps/better-uart/registers.md
|
|
#, fuzzy
|
|
msgid "Multiple registers"
|
|
msgstr "더 많은 레지스터"
|
|
|
|
#: src/bare-metal/aps/better-uart/registers.md
|
|
msgid ""
|
|
"We can use a struct to represent the memory layout of the UART's registers."
|
|
msgstr ""
|
|
"구조체를 사용하여 UART 레지스터의 메모리 레이아웃을 나타낼 수 있습니다."
|
|
|
|
#: src/bare-metal/aps/better-uart/registers.md
|
|
msgid ""
|
|
"[`#[repr(C)]`](https://doc.rust-lang.org/reference/type-layout.html#the-c-"
|
|
"representation) tells the compiler to lay the struct fields out in order, "
|
|
"following the same rules as C. This is necessary for our struct to have a "
|
|
"predictable layout, as default Rust representation allows the compiler to "
|
|
"(among other things) reorder fields however it sees fit."
|
|
msgstr ""
|
|
"[`#[repr(C)]`](https://doc.rust-lang.org/reference/type-layout.html#the-c-"
|
|
"representation)는 C와 동일한 규칙에 따라 구조체 필드를 순서대로 배치하도록 컴"
|
|
"파일러에 지시합니다. 기본 Rust 표현을 사용하면 컴파일러가 원하는 대로 필드의 "
|
|
"순서를 변경할 수 있으므로 구조체에서 예측 가능한 레이아웃을 사용하는 데 필요"
|
|
"합니다."
|
|
|
|
#: src/bare-metal/aps/better-uart/driver.md
|
|
msgid "Now let's use the new `Registers` struct in our driver."
|
|
msgstr "이제 드라이버에서 새로운 `Registers` 구조체를 사용해 보겠습니다."
|
|
|
|
#: src/bare-metal/aps/better-uart/driver.md
|
|
msgid "/// Driver for a PL011 UART.\n"
|
|
msgstr "/// PL011 UART용 드라이버\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/driver.md
|
|
msgid ""
|
|
"// Safe because we know that self.registers points to the control\n"
|
|
" // registers of a PL011 device which is appropriately mapped.\n"
|
|
msgstr ""
|
|
"// self.registers가 적절하게 매핑된 PL011 기기의 제어 레지스터를\n"
|
|
" // 가리키고 있으므로 안전합니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/driver.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"/// Reads and returns a pending byte, or `None` if nothing has been\n"
|
|
" /// received.\n"
|
|
msgstr ""
|
|
"/// 대기 중인 바이트를 읽고 반환하거나, 아무것도 수신되지 않은 경우 `None`을 "
|
|
"반환합니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/driver.md
|
|
msgid "// TODO: Check for error conditions in bits 8-11.\n"
|
|
msgstr "// TODO: 비트 8~11에서 오류 상태를 확인합니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/driver.md
|
|
msgid ""
|
|
"Note the use of `addr_of!` / `addr_of_mut!` to get pointers to individual "
|
|
"fields without creating an intermediate reference, which would be unsound."
|
|
msgstr ""
|
|
"`addr_of!` / `addr_of_mut!`를 사용하여 중간 참조를 만들지 않고 개별 필드 포인"
|
|
"터를 가져오는 것은 불안정할 수 있습니다."
|
|
|
|
#: src/bare-metal/aps/better-uart/using.md src/bare-metal/aps/logging/using.md
|
|
#, fuzzy
|
|
msgid "Using it"
|
|
msgstr "Bindgen 사용하기"
|
|
|
|
#: src/bare-metal/aps/better-uart/using.md
|
|
msgid ""
|
|
"Let's write a small program using our driver to write to the serial console, "
|
|
"and echo incoming bytes."
|
|
msgstr ""
|
|
"드라이버를 사용하여 직렬 콘솔에 쓰고 수신되는 바이트를 에코하는 간단한 프로그"
|
|
"램을 작성해 보겠습니다."
|
|
|
|
#: src/bare-metal/aps/better-uart/using.md src/bare-metal/aps/logging/using.md
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Base address of the primary PL011 UART.\n"
|
|
msgstr "/// 기본 PL011 UART의 기본 주소입니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/using.md src/bare-metal/aps/logging/using.md
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid ""
|
|
"// Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 device,\n"
|
|
" // and nothing else accesses that address range.\n"
|
|
msgstr ""
|
|
"// `PL011_BASE_ADDRESS`가 PL011 기기의 기본 주소이고\n"
|
|
" // 이 주소 범위에 액세스하는 다른 항목이 없으므로 안전합니다.\n"
|
|
|
|
#: src/bare-metal/aps/better-uart/using.md src/bare-metal/aps/logging/using.md
|
|
msgid "\"main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})\""
|
|
msgstr "\"main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})\""
|
|
|
|
#: src/bare-metal/aps/better-uart/using.md
|
|
#, fuzzy
|
|
msgid "b'\\r'"
|
|
msgstr "b'\\r\""
|
|
|
|
#: src/bare-metal/aps/better-uart/using.md src/async/pitfalls/cancellation.md
|
|
#, fuzzy
|
|
msgid "b'\\n'"
|
|
msgstr "b'\\n\""
|
|
|
|
#: src/bare-metal/aps/better-uart/using.md
|
|
msgid "b'q'"
|
|
msgstr "b'q'"
|
|
|
|
#: src/bare-metal/aps/better-uart/using.md
|
|
msgid "\"Bye!\""
|
|
msgstr "\"안녕!\""
|
|
|
|
#: src/bare-metal/aps/better-uart/using.md
|
|
msgid ""
|
|
"As in the [inline assembly](../inline-assembly.md) example, this `main` "
|
|
"function is called from our entry point code in `entry.S`. See the speaker "
|
|
"notes there for details."
|
|
msgstr ""
|
|
"[인라인 어셈블리](../inline-assembly.md) 예에서와 같이 이 `main` 함수는 "
|
|
"`entry.S`의 진입점 코드에서 호출됩니다. 자세한 내용은 해당 발표자 노트를 참고"
|
|
"하세요."
|
|
|
|
#: src/bare-metal/aps/better-uart/using.md
|
|
msgid ""
|
|
"Run the example in QEMU with `make qemu` under `src/bare-metal/aps/examples`."
|
|
msgstr ""
|
|
"`src/bare-metal/aps/examples`에서 `make qemu`를 사용하여 QEMU에서 예를 실행합"
|
|
"니다."
|
|
|
|
#: src/bare-metal/aps/logging.md
|
|
msgid ""
|
|
"It would be nice to be able to use the logging macros from the [`log`]"
|
|
"(https://crates.io/crates/log) crate. We can do this by implementing the "
|
|
"`Log` trait."
|
|
msgstr ""
|
|
"[`log`](https://crates.io/crates/log) 크레이트의 로깅 매크로를 사용할 수 있으"
|
|
"면 좋습니다. 이는 `Log` 트레잇을 구현하면 됩니다."
|
|
|
|
#: src/bare-metal/aps/logging.md
|
|
msgid "\"[{}] {}\""
|
|
msgstr "\"[{}] {}\""
|
|
|
|
#: src/bare-metal/aps/logging.md
|
|
msgid "/// Initialises UART logger.\n"
|
|
msgstr "/// UART 로거를 초기화합니다.\n"
|
|
|
|
#: src/bare-metal/aps/logging.md
|
|
msgid ""
|
|
"The unwrap in `log` is safe because we initialise `LOGGER` before calling "
|
|
"`set_logger`."
|
|
msgstr ""
|
|
"`log`함수 안에서 `unwrap`하는 것은 괜찮습니다.. 왜냐하면 `set_logger`를 호출"
|
|
"하기 전에 `LOGGER`를 초기화하기 때문입니다."
|
|
|
|
#: src/bare-metal/aps/logging/using.md
|
|
msgid "We need to initialise the logger before we use it."
|
|
msgstr "로거를 사용하려면 먼저 초기화해야 합니다."
|
|
|
|
#: src/bare-metal/aps/logging/using.md
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "\"{info}\""
|
|
msgstr "\"{info}\""
|
|
|
|
#: src/bare-metal/aps/logging/using.md
|
|
msgid "Note that our panic handler can now log details of panics."
|
|
msgstr "패닉 핸들러가 이제 패닉의 세부정보를 기록할 수 있습니다."
|
|
|
|
#: src/bare-metal/aps/logging/using.md
|
|
msgid ""
|
|
"Run the example in QEMU with `make qemu_logger` under `src/bare-metal/aps/"
|
|
"examples`."
|
|
msgstr ""
|
|
"`src/bare-metal/aps/examples`에서 `make qemu_logger`를 사용하여 QEMU에서 예"
|
|
"를 실행합니다."
|
|
|
|
#: src/bare-metal/aps/exceptions.md
|
|
msgid ""
|
|
"AArch64 defines an exception vector table with 16 entries, for 4 types of "
|
|
"exceptions (synchronous, IRQ, FIQ, SError) from 4 states (current EL with "
|
|
"SP0, current EL with SPx, lower EL using AArch64, lower EL using AArch32). "
|
|
"We implement this in assembly to save volatile registers to the stack before "
|
|
"calling into Rust code:"
|
|
msgstr ""
|
|
"AArch64는 4개 상태(SP0을 사용하는 현재 EL, SPx를 사용하는 현재 EL, AArch64를 "
|
|
"사용하는 하위 EL, AArch32를 사용하는 하위 EL)의 4가지 예외 타입(동기, IRQ, "
|
|
"FIQ, SError)에 대해 16개 항목이 있는 예외 벡터 테이블을 정의합니다. Rust 코드"
|
|
"를 호출하기 전에 휘발성 레지스터를 스택에 저장하기 위해 어셈블리에서 이를 구"
|
|
"현합니다."
|
|
|
|
#: src/bare-metal/aps/exceptions.md
|
|
msgid "EL is exception level; all our examples this afternoon run in EL1."
|
|
msgstr "EL은 예외 수준입니다. 오늘 오후의 모든 예는 EL1에서 실행됩니다."
|
|
|
|
#: src/bare-metal/aps/exceptions.md
|
|
msgid ""
|
|
"For simplicity we aren't distinguishing between SP0 and SPx for the current "
|
|
"EL exceptions, or between AArch32 and AArch64 for the lower EL exceptions."
|
|
msgstr ""
|
|
"편의상 현재 EL 예외의 SP0과 SPx를 구별하거나 하위 EL 예외의 AArch32와 AArch64"
|
|
"를 구별하지 않습니다."
|
|
|
|
#: src/bare-metal/aps/exceptions.md
|
|
msgid ""
|
|
"For this example we just log the exception and power down, as we don't "
|
|
"expect any of them to actually happen."
|
|
msgstr ""
|
|
"이 예에서는 예외가 실제로 발생할 것으로 예상되지 않으므로 예외를 기록하고 전"
|
|
"원을 끕니다."
|
|
|
|
#: src/bare-metal/aps/exceptions.md
|
|
msgid ""
|
|
"We can think of exception handlers and our main execution context more or "
|
|
"less like different threads. [`Send` and `Sync`](../../concurrency/send-sync."
|
|
"md) will control what we can share between them, just like with threads. For "
|
|
"example, if we want to share some value between exception handlers and the "
|
|
"rest of the program, and it's `Send` but not `Sync`, then we'll need to wrap "
|
|
"it in something like a `Mutex` and put it in a static."
|
|
msgstr ""
|
|
"예외 핸들러와 기본 실행 컨텍스트는 서로 다른 스레드와 거의 비슷하다고 생각할 "
|
|
"수 있습니다. [`Send` 및 `Sync`](../../concurrency/send-sync.md)는 스레드와 마"
|
|
"찬가지로 이들 간에 공유할 수 있는 항목을 제어합니다. 예를 들어 예외 핸들러와 "
|
|
"프로그램의 나머지 부분 간에 값을 공유하려고 하는데 `Send`이지만 `Sync`는 아"
|
|
"닌 경우, `Mutex`와 같은 것으로 래핑하고 정적인 것으로 배치해야 합니다."
|
|
|
|
#: src/bare-metal/aps/other-projects.md
|
|
#, fuzzy
|
|
msgid "[oreboot](https://github.com/oreboot/oreboot)"
|
|
msgstr "[oreboot](https://github.com/oreboot/oreboot)"
|
|
|
|
#: src/bare-metal/aps/other-projects.md
|
|
#, fuzzy
|
|
msgid "\"coreboot without the C\""
|
|
msgstr "\"C가 없는 coreboot\""
|
|
|
|
#: src/bare-metal/aps/other-projects.md
|
|
#, fuzzy
|
|
msgid "Supports x86, aarch64 and RISC-V."
|
|
msgstr "x86, aarch64, RISC-V를 지원합니다."
|
|
|
|
#: src/bare-metal/aps/other-projects.md
|
|
#, fuzzy
|
|
msgid "Relies on LinuxBoot rather than having many drivers itself."
|
|
msgstr "자체적으로 여러 드라이버를 보유하는 대신 LinuxBoot에 의존합니다."
|
|
|
|
#: src/bare-metal/aps/other-projects.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[Rust RaspberryPi OS tutorial](https://github.com/rust-embedded/rust-"
|
|
"raspberrypi-OS-tutorials)"
|
|
msgstr ""
|
|
"[Rust RaspberryPi OS tutorial](https://github.com/rust-embedded/rust-"
|
|
"raspberrypi-OS-tutorials)"
|
|
|
|
#: src/bare-metal/aps/other-projects.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Initialisation, UART driver, simple bootloader, JTAG, exception levels, "
|
|
"exception handling, page tables"
|
|
msgstr ""
|
|
"초기화, UART 드라이버, 간단한 부트로더, JTAG, 예외 수준, 예외 처리, 페이지 테"
|
|
"이블"
|
|
|
|
#: src/bare-metal/aps/other-projects.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Some dodginess around cache maintenance and initialisation in Rust, not "
|
|
"necessarily a good example to copy for production code."
|
|
msgstr "잘 작성되지 않은 것도 있으므로 주의하세요."
|
|
|
|
#: src/bare-metal/aps/other-projects.md
|
|
#, fuzzy
|
|
msgid "[`cargo-call-stack`](https://crates.io/crates/cargo-call-stack)"
|
|
msgstr "[`cargo-call-stack`](https://crates.io/crates/cargo-call-stack)"
|
|
|
|
#: src/bare-metal/aps/other-projects.md
|
|
#, fuzzy
|
|
msgid "Static analysis to determine maximum stack usage."
|
|
msgstr "최대 스택 사용량을 결정하는 정적 분석"
|
|
|
|
#: src/bare-metal/aps/other-projects.md
|
|
msgid ""
|
|
"The RaspberryPi OS tutorial runs Rust code before the MMU and caches are "
|
|
"enabled. This will read and write memory (e.g. the stack). However:"
|
|
msgstr ""
|
|
"RaspberryPi OS 튜토리얼에서는 MMU와 캐시가 사용 설정되기 전에 Rust 코드를 실"
|
|
"행합니다. 이렇게 하면 메모리(예: 스택)를 읽고 쓸 수 있습니다. 하지만 다음과 "
|
|
"같은 예외가 적용됩니다."
|
|
|
|
#: src/bare-metal/aps/other-projects.md
|
|
msgid ""
|
|
"Without the MMU and cache, unaligned accesses will fault. It builds with "
|
|
"`aarch64-unknown-none` which sets `+strict-align` to prevent the compiler "
|
|
"generating unaligned accesses so it should be alright, but this is not "
|
|
"necessarily the case in general."
|
|
msgstr ""
|
|
"MMU와 캐시가 없으면 정렬되지 않은 액세스에 오류가 발생합니다. 컴파일러가 정렬"
|
|
"되지 않은 액세스를 생성하지 않도록 `+strict-align`을 설정하는 `aarch64-"
|
|
"unknown-none`으로 빌드되므로 문제가 없지만, 일반적으로 반드시 그런 것은 아닙"
|
|
"니다."
|
|
|
|
#: src/bare-metal/aps/other-projects.md
|
|
msgid ""
|
|
"If it were running in a VM, this can lead to cache coherency issues. The "
|
|
"problem is that the VM is accessing memory directly with the cache disabled, "
|
|
"while the host has cacheable aliases to the same memory. Even if the host "
|
|
"doesn't explicitly access the memory, speculative accesses can lead to cache "
|
|
"fills, and then changes from one or the other will get lost. Again this is "
|
|
"alright in this particular case (running directly on the hardware with no "
|
|
"hypervisor), but isn't a good pattern in general."
|
|
msgstr ""
|
|
"VM에서 실행한다면 캐시 일관성 문제가 발생할 수 있습니다. 문제는 VM은 캐시가 "
|
|
"사용 중지된 상태로 메모리에 직접 액세스하는 반면 호스트에는 동일한 메모리에 "
|
|
"대해 캐시할 수 있는 별칭이 있다는 점입니다. 호스트가 메모리에 명시적으로 액세"
|
|
"스하지 않더라도 추측 액세스는 캐시 채우기로 이어질 수 있으며 둘 중 하나의 변"
|
|
"경사항이 손실됩니다. 이번에도 하이퍼바이저 없이 하드웨어에서 직접 실행되는 "
|
|
"이 특정 경우에는 문제가 없지만, 일반적으로 좋은 패턴은 아닙니다."
|
|
|
|
#: src/bare-metal/useful-crates.md
|
|
msgid "Useful crates"
|
|
msgstr "유용한 크레이트"
|
|
|
|
#: src/bare-metal/useful-crates.md
|
|
msgid ""
|
|
"We'll go over a few crates which solve some common problems in bare-metal "
|
|
"programming."
|
|
msgstr ""
|
|
"bare-metal 프로그래밍의 몇 가지 일반적인 문제를 해결하는 크레이트를 살펴봅니"
|
|
"다."
|
|
|
|
#: src/bare-metal/useful-crates/zerocopy.md
|
|
msgid ""
|
|
"The [`zerocopy`](https://docs.rs/zerocopy/) crate (from Fuchsia) provides "
|
|
"traits and macros for safely converting between byte sequences and other "
|
|
"types."
|
|
msgstr ""
|
|
"Fuchsia팀이 만든 [`zerocopy`](https://docs.rs/zerocopy/) 크레이트는 바이트 시"
|
|
"퀀스를 다른 타입으로 안전하게 변환하기 위한 트레잇 및 매크로를 제공합니다."
|
|
|
|
#: src/bare-metal/useful-crates/zerocopy.md
|
|
msgid ""
|
|
"This is not suitable for MMIO (as it doesn't use volatile reads and writes), "
|
|
"but can be useful for working with structures shared with hardware e.g. by "
|
|
"DMA, or sent over some external interface."
|
|
msgstr ""
|
|
"이 크레이트는 휘발성(volatile) 읽기 및 쓰기를 사용하지 않으므로 MMIO에 적합하"
|
|
"지 않지만, 하드웨어와 공유되거나(예: DMA에서) 외장 인터페이스를 통해 전송되"
|
|
"는 구조체를 다루는 데에는 유용할 수 있습니다."
|
|
|
|
#: src/bare-metal/useful-crates/zerocopy.md
|
|
msgid ""
|
|
"`FromBytes` can be implemented for types for which any byte pattern is "
|
|
"valid, and so can safely be converted from an untrusted sequence of bytes."
|
|
msgstr ""
|
|
"어떤 타입이 가능한 모든 바이트 패턴들에 대해 올바른 값을 가질 때에만 , 그 타"
|
|
"입이 `FromBytes`를 구현할 수 있습니다. 그렇게 해서 신뢰할 수 없는 바이트 시퀀"
|
|
"스를 안전하게 해당 타입으로 변환할 수 있습니다."
|
|
|
|
#: src/bare-metal/useful-crates/zerocopy.md
|
|
msgid ""
|
|
"Attempting to derive `FromBytes` for these types would fail, because "
|
|
"`RequestType` doesn't use all possible u32 values as discriminants, so not "
|
|
"all byte patterns are valid."
|
|
msgstr ""
|
|
"위 코드에서 정의한 타입에 대해 `FromBytes`를 구현하려고 하면 에러가 발생합니"
|
|
"다. `RequestType`은 가능한 모든 u32 값을 식별자로 받아들이지 않기 때문입니"
|
|
"다. 즉 모든 바이트 패턴이 유효한 `RequestType`값은 아닙니다."
|
|
|
|
#: src/bare-metal/useful-crates/zerocopy.md
|
|
msgid ""
|
|
"`zerocopy::byteorder` has types for byte-order aware numeric primitives."
|
|
msgstr ""
|
|
"`zerocopy::byteorder`에는 바이트 오더에 따른 서로 다른 표현 방식을 지원하는 "
|
|
"숫자 타입을 제공합니다."
|
|
|
|
#: src/bare-metal/useful-crates/zerocopy.md
|
|
msgid ""
|
|
"Run the example with `cargo run` under `src/bare-metal/useful-crates/"
|
|
"zerocopy-example/`. (It won't run in the Playground because of the crate "
|
|
"dependency.)"
|
|
msgstr ""
|
|
"`src/bare-metal/useful-crates/zerocopy-example/`에서 `cargo run`을 사용하여 "
|
|
"예시를 실행합니다(종속성 문제로 인해 플레이그라운드에서는 실행되지 않습니다)."
|
|
|
|
#: src/bare-metal/useful-crates/aarch64-paging.md
|
|
msgid ""
|
|
"The [`aarch64-paging`](https://crates.io/crates/aarch64-paging) crate lets "
|
|
"you create page tables according to the AArch64 Virtual Memory System "
|
|
"Architecture."
|
|
msgstr ""
|
|
"[`aarch64-paging`](https://crates.io/crates/aarch64-paging) 크레이트를 사용하"
|
|
"면 AArch64 가상 메모리 시스템 아키텍처에 따라 페이지 테이블을 만들 수 있습니"
|
|
"다."
|
|
|
|
#: src/bare-metal/useful-crates/aarch64-paging.md
|
|
msgid "// Create a new page table with identity mapping.\n"
|
|
msgstr "// ID 매핑을 사용하여 새 페이지 테이블을 만듭니다.\n"
|
|
|
|
#: src/bare-metal/useful-crates/aarch64-paging.md
|
|
msgid "// Map a 2 MiB region of memory as read-only.\n"
|
|
msgstr "// 2MiB 메모리 영역을 읽기 전용으로 매핑합니다.\n"
|
|
|
|
#: src/bare-metal/useful-crates/aarch64-paging.md
|
|
msgid "// Set `TTBR0_EL1` to activate the page table.\n"
|
|
msgstr "// `TTBR0_EL1`을 설정하여 페이지 테이블을 활성화합니다.\n"
|
|
|
|
#: src/bare-metal/useful-crates/aarch64-paging.md
|
|
msgid ""
|
|
"For now it only supports EL1, but support for other exception levels should "
|
|
"be straightforward to add."
|
|
msgstr ""
|
|
"현재는 EL1만 지원하지만 다른 익셉션 레벨(Exception Level: EL)도 어렵지 않게 "
|
|
"추가할 수 있습니다."
|
|
|
|
#: src/bare-metal/useful-crates/aarch64-paging.md
|
|
msgid ""
|
|
"This is used in Android for the [Protected VM Firmware](https://cs.android."
|
|
"com/android/platform/superproject/+/master:packages/modules/Virtualization/"
|
|
"pvmfw/)."
|
|
msgstr ""
|
|
"Android에서 [보호된 VM 펌웨어](https://cs.android.com/android/platform/"
|
|
"superproject/+/master:packages/modules/Virtualization/pvmfw/)에 사용됩니다."
|
|
|
|
#: src/bare-metal/useful-crates/aarch64-paging.md
|
|
msgid ""
|
|
"There's no easy way to run this example, as it needs to run on real hardware "
|
|
"or under QEMU."
|
|
msgstr ""
|
|
"이 예시를 간단하게 실행하는 방법은 없습니다. 실제 하드웨어 또는 QEMU에서 실행"
|
|
"해야 하기 때문입니다."
|
|
|
|
#: src/bare-metal/useful-crates/buddy_system_allocator.md
|
|
msgid ""
|
|
"[`buddy_system_allocator`](https://crates.io/crates/buddy_system_allocator) "
|
|
"is a third-party crate implementing a basic buddy system allocator. It can "
|
|
"be used both for [`LockedHeap`](https://docs.rs/buddy_system_allocator/0.9.0/"
|
|
"buddy_system_allocator/struct.LockedHeap.html) implementing [`GlobalAlloc`]"
|
|
"(https://doc.rust-lang.org/core/alloc/trait.GlobalAlloc.html) so you can use "
|
|
"the standard `alloc` crate (as we saw [before](../alloc.md)), or for "
|
|
"allocating other address space. For example, we might want to allocate MMIO "
|
|
"space for PCI BARs:"
|
|
msgstr ""
|
|
"[`buddy_system_allocator`](https://crates.io/crates/buddy_system_allocator)"
|
|
"는 버디 시스템 할당자를 구현하는 서드 파티 크레이트입니다. 이 크레이트의 "
|
|
"[`LockedHeap`](https://docs.rs/buddy_system_allocator/0.9.0/"
|
|
"buddy_system_allocator/struct.LockedHeap.html)은 [`GlobalAlloc`](https://doc."
|
|
"rust-lang.org/core/alloc/trait.GlobalAlloc.html)를 구현합니다. 따라서 여러분"
|
|
"은 버디 시스템 할당자를 'alloc' 크레이트를 통해서 사용할 수 있습니다([이전]"
|
|
"(../alloc.md)에 확인함). 또는 다른 주소 공간을 할당하는 데 사용할 수 있습니"
|
|
"다. 예를 들어 PCI BAR에 MMIO 공간을 할당할 수 있습니다."
|
|
|
|
#: src/bare-metal/useful-crates/buddy_system_allocator.md
|
|
msgid "PCI BARs always have alignment equal to their size."
|
|
msgstr "PCI BAR는 BAR영역의 크기에 맞추어 정렬됩니다."
|
|
|
|
#: src/bare-metal/useful-crates/buddy_system_allocator.md
|
|
msgid ""
|
|
"Run the example with `cargo run` under `src/bare-metal/useful-crates/"
|
|
"allocator-example/`. (It won't run in the Playground because of the crate "
|
|
"dependency.)"
|
|
msgstr ""
|
|
"`src/bare-metal/useful-crates/allocator-example/`에서 `cargo run`을 사용하여 "
|
|
"예시를 실행합니다(종속성 문제로 인해 플레이그라운드에서는 실행되지 않습니다)."
|
|
|
|
#: src/bare-metal/useful-crates/tinyvec.md
|
|
msgid ""
|
|
"Sometimes you want something which can be resized like a `Vec`, but without "
|
|
"heap allocation. [`tinyvec`](https://crates.io/crates/tinyvec) provides "
|
|
"this: a vector backed by an array or slice, which could be statically "
|
|
"allocated or on the stack, which keeps track of how many elements are used "
|
|
"and panics if you try to use more than are allocated."
|
|
msgstr ""
|
|
"힙에 메모리 할당하지 않고 크기 조절이 가능한 컨테이너(예: `Vec` 같은)가 필요"
|
|
"할 때가 있습니다. [`tinyvec`](https://crates.io/crates/tinyvec)을 사용하면 됩"
|
|
"니다. `tinyvec`에서 벡터는 배열 또는 슬라이스로부터 생성이 되며, 이들은 정적"
|
|
"으로 할당되었거나 스택에 할당되어 있을 수 있습니다.`tinyvec`은 현재 벡터 안"
|
|
"에 얼마나 많은 엘리먼트들이 존재하는 지를 추적하고 있으며, 할당된 양보다 더 "
|
|
"많이 사용하려고 하면 패닉을 발생시킵니다."
|
|
|
|
#: src/bare-metal/useful-crates/tinyvec.md
|
|
msgid ""
|
|
"`tinyvec` requires that the element type implement `Default` for "
|
|
"initialisation."
|
|
msgstr ""
|
|
"`tinyvec`를 사용하려면 엘리먼트의 타입이 `Default`를 통해 초기화 될 수 있어"
|
|
"야 합니다."
|
|
|
|
#: src/bare-metal/useful-crates/tinyvec.md
|
|
msgid ""
|
|
"The Rust Playground includes `tinyvec`, so this example will run fine inline."
|
|
msgstr ""
|
|
"Rust 플레이그라운드에는 `tinyvec`가 포함되어 있으므로 이 예시는 인라인으로 실"
|
|
"행됩니다."
|
|
|
|
#: src/bare-metal/useful-crates/spin.md
|
|
msgid ""
|
|
"`std::sync::Mutex` and the other synchronisation primitives from `std::sync` "
|
|
"are not available in `core` or `alloc`. How can we manage synchronisation or "
|
|
"interior mutability, such as for sharing state between different CPUs?"
|
|
msgstr ""
|
|
"`std::sync::Mutex` 및 `std::sync`의 기타 동기화 프리미티브는 `core` 또는 "
|
|
"`alloc`에서 사용할 수 없습니다. 그러면 어떻게 동기화 또는 interior mutability"
|
|
"와 같은 기능이 필요할 경우 어떻게 해야 할까요? "
|
|
|
|
#: src/bare-metal/useful-crates/spin.md
|
|
msgid ""
|
|
"The [`spin`](https://crates.io/crates/spin) crate provides spinlock-based "
|
|
"equivalents of many of these primitives."
|
|
msgstr ""
|
|
"[`spin`](https://crates.io/crates/spin) 크레이트는 이러한 동기화 프리미티브들"
|
|
"을 스핀록으로 구현하고 있습니다."
|
|
|
|
#: src/bare-metal/useful-crates/spin.md
|
|
msgid "Be careful to avoid deadlock if you take locks in interrupt handlers."
|
|
msgstr ""
|
|
"인터럽트 핸들러에서 락을 걸 경우, 교착 상태가 발생하지 않도록 주의하세요."
|
|
|
|
#: src/bare-metal/useful-crates/spin.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`spin` also has a ticket lock mutex implementation; equivalents of `RwLock`, "
|
|
"`Barrier` and `Once` from `std::sync`; and `Lazy` for lazy initialisation."
|
|
msgstr ""
|
|
"`spin`에는 티켓 잠금 뮤텍스 구현도 있습니다. `std::sync`의 `RwLock`, "
|
|
"`Barrier`, `Once` 에 해당하는 것들이 제공되며, 지연된 초기화를 위한 `Lazy`"
|
|
"에 해당하는 것도 제공됩니다."
|
|
|
|
#: src/bare-metal/useful-crates/spin.md
|
|
msgid ""
|
|
"The [`once_cell`](https://crates.io/crates/once_cell) crate also has some "
|
|
"useful types for late initialisation with a slightly different approach to "
|
|
"`spin::once::Once`."
|
|
msgstr ""
|
|
"[`once_cell`](https://crates.io/crates/once_cell) 크레이트에는 지연된 초기화"
|
|
"를 위한 몇 가지 유용한 타입이 있는데 `spin::once::Once`와는 약간 다른 접근 방"
|
|
"식을 사용합니다."
|
|
|
|
#: src/bare-metal/useful-crates/spin.md
|
|
msgid ""
|
|
"The Rust Playground includes `spin`, so this example will run fine inline."
|
|
msgstr ""
|
|
"Rust 플레이그라운드에는 `spin`이 포함되어 있으므로 이 예시는 인라인으로 실행"
|
|
"됩니다."
|
|
|
|
#: src/bare-metal/android.md
|
|
msgid ""
|
|
"To build a bare-metal Rust binary in AOSP, you need to use a "
|
|
"`rust_ffi_static` Soong rule to build your Rust code, then a `cc_binary` "
|
|
"with a linker script to produce the binary itself, and then a `raw_binary` "
|
|
"to convert the ELF to a raw binary ready to be run."
|
|
msgstr ""
|
|
"AOSP에서 bare-metal Rust 바이너리를 빌드하려면 `rust_ffi_static` 을 사용하여 "
|
|
"Rust 코드를 빌드하고, 링커 스크립트가 포함된 `cc_binary`를 사용하여 ELF 바이"
|
|
"너리를 생성하고, `raw_binary`를 사용해 ELF를 곧바로 수행될 수 있는 원시(raw) "
|
|
"바이너리로 변환합니다."
|
|
|
|
#: src/bare-metal/android/vmbase.md
|
|
msgid "vmbase"
|
|
msgstr "vmbase"
|
|
|
|
#: src/bare-metal/android/vmbase.md
|
|
msgid ""
|
|
"For VMs running under crosvm on aarch64, the [vmbase](https://android."
|
|
"googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/"
|
|
"master/vmbase/) library provides a linker script and useful defaults for the "
|
|
"build rules, along with an entry point, UART console logging and more."
|
|
msgstr ""
|
|
"[vmbase](https://android.googlesource.com/platform/packages/modules/"
|
|
"Virtualization/+/refs/heads/master/vmbase/) 라이브러리는, aarch64의 crosvm에"
|
|
"서 실행되는 VM을 타겟하여, 진입점, UART 콘솔 로깅, 링커 스크립트, 빌드 룰 등"
|
|
"에 대한 기본 구현들을 제공합니다."
|
|
|
|
#: src/bare-metal/android/vmbase.md
|
|
msgid ""
|
|
"The `main!` macro marks your main function, to be called from the `vmbase` "
|
|
"entry point."
|
|
msgstr "`main!` 매크로는 `vmbase` 진입점에서 호출될 main 함수를 표시합니다."
|
|
|
|
#: src/bare-metal/android/vmbase.md
|
|
msgid ""
|
|
"The `vmbase` entry point handles console initialisation, and issues a "
|
|
"PSCI_SYSTEM_OFF to shutdown the VM if your main function returns."
|
|
msgstr ""
|
|
"`vmbase`가 제공하는 진입점은 콘솔을 초기화 하며, main 함수가 리턴하면 "
|
|
"PSCI_SYSTEM_OFF 메시지를 PSCI를 통해 보내어서 VM을 종료시킵니다."
|
|
|
|
#: src/exercises/bare-metal/afternoon.md
|
|
msgid "We will write a driver for the PL031 real-time clock device."
|
|
msgstr "PL031 실시간 시계 기기용 드라이버를 작성합니다."
|
|
|
|
#: src/exercises/bare-metal/afternoon.md src/exercises/concurrency/afternoon.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"After looking at the exercises, you can look at the [solutions](solutions-"
|
|
"afternoon.md) provided."
|
|
msgstr ""
|
|
"연습문제를 살펴 본 후, 제공된 [해답](solutions-afternoon.md)을 살펴볼 수 있습"
|
|
"니다."
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
#, fuzzy
|
|
msgid "RTC driver"
|
|
msgstr "RTC 드라이버"
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The QEMU aarch64 virt machine has a [PL031](https://developer.arm.com/"
|
|
"documentation/ddi0224/c) real-time clock at 0x9010000. For this exercise, "
|
|
"you should write a driver for it."
|
|
msgstr ""
|
|
"QEMU의 'virt' 보드에는 [PL011](https://developer.arm.com/documentation/"
|
|
"ddi0224/c) UART가 있으므로 이를 위한 드라이버를 작성해 보겠습니다."
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid ""
|
|
"Use it to print the current time to the serial console. You can use the "
|
|
"[`chrono`](https://crates.io/crates/chrono) crate for date/time formatting."
|
|
msgstr ""
|
|
"직렬 콘솔에 현재 시간을 출력하는 데 사용합니다. 날짜/시간 형식 지정에는 "
|
|
"[`chrono`](https://crates.io/crates/chrono) 크레이트를 사용할 수 있습니다."
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid ""
|
|
"Use the match register and raw interrupt status to busy-wait until a given "
|
|
"time, e.g. 3 seconds in the future. (Call [`core::hint::spin_loop`](https://"
|
|
"doc.rust-lang.org/core/hint/fn.spin_loop.html) inside the loop.)"
|
|
msgstr ""
|
|
"일치 레지스터와 원시 인터럽트 상태를 사용하여 특정 시간(예: 향후 3초)까지 바"
|
|
"쁜 대기합니다. 루프 내에서 [`core::hint::spin_loop`](https://doc.rust-lang."
|
|
"org/core/hint/fn.spin_loop.html)를 호출합니다."
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid ""
|
|
"_Extension if you have time:_ Enable and handle the interrupt generated by "
|
|
"the RTC match. You can use the driver provided in the [`arm-gic`](https://"
|
|
"docs.rs/arm-gic/) crate to configure the Arm Generic Interrupt Controller."
|
|
msgstr ""
|
|
"_시간이 있는 경우 연장:_ RTC 일치로 생성된 인터럽트를 사용 설정하고 처리합니"
|
|
"다. [`arm-gic`](https://docs.rs/arm-gic/) 크레이트에 제공된 드라이버를 사용하"
|
|
"여 Arm 일반 인터럽트 컨트롤러를 구성할 수 있습니다."
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid "Use the RTC interrupt, which is wired to the GIC as `IntId::spi(2)`."
|
|
msgstr "GIC에 `IntId::spi(2)`로 연결된 RTC 인터럽트를 사용합니다."
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid ""
|
|
"Once the interrupt is enabled, you can put the core to sleep via `arm_gic::"
|
|
"wfi()`, which will cause the core to sleep until it receives an interrupt."
|
|
msgstr ""
|
|
"인터럽트를 사용 설정한 후에는 `arm_gic::wfi()`를 통해 코어를 절전 모드로 전환"
|
|
"할 수 있습니다. 이 경우 인터럽트를 수신할 때까지 코어가 절전 모드로 전환됩니"
|
|
"다."
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid ""
|
|
"Download the [exercise template](../../comprehensive-rust-exercises.zip) and "
|
|
"look in the `rtc` directory for the following files."
|
|
msgstr ""
|
|
"[연습 템플릿](../../comprehensive-rust-exercises.zip)을 다운로드하고 `rtc` 디"
|
|
"렉터리에서 다음 파일을 찾습니다."
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid ""
|
|
"_src/exceptions.rs_ (you should only need to change this for the 3rd part of "
|
|
"the exercise):"
|
|
msgstr "_src/exceptions.rs_는 연습의 세 번째 부분에서만 변경하면 됩니다."
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid "_src/logger.rs_ (you shouldn't need to change this):"
|
|
msgstr "_src/logger.rs_(변경할 필요가 없음):"
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid "_src/pl011.rs_ (you shouldn't need to change this):"
|
|
msgstr "_src/pl011.rs_ (변경할 필요가 없음):"
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid "_build.rs_ (you shouldn't need to change this):"
|
|
msgstr "_build.rs_(변경할 필요가 없음):"
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid "_entry.S_ (you shouldn't need to change this):"
|
|
msgstr "_entry.S_(변경할 필요가 없음):"
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid "_exceptions.S_ (you shouldn't need to change this):"
|
|
msgstr "_exceptions.S_(변경할 필요가 없음):"
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid "_idmap.S_ (you shouldn't need to change this):"
|
|
msgstr "_idmap.S_(변경할 필요가 없음):"
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid "_image.ld_ (you shouldn't need to change this):"
|
|
msgstr "_image.ld_(변경할 필요가 없음):"
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid "_Makefile_ (you shouldn't need to change this):"
|
|
msgstr "_Makefile_(변경할 필요가 없음):"
|
|
|
|
#: src/exercises/bare-metal/rtc.md
|
|
msgid "Run the code in QEMU with `make qemu`."
|
|
msgstr "`make qemu`를 사용하여 QEMU에서 코드를 실행합니다."
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "Bare Metal Rust Afternoon"
|
|
msgstr "전Bare Metal 오후"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "([back to exercise](rtc.md))"
|
|
msgstr "([연습문제로 돌아가기](rtc.md))"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
#, fuzzy
|
|
msgid "_main.rs_:"
|
|
msgstr "_hello_rust/src/main.rs_:"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Base addresses of the GICv3.\n"
|
|
msgstr "/// GICv3의 기본 주소입니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Base address of the PL031 RTC.\n"
|
|
msgstr "/// PL031 RTC의 기본 주소입니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// The IRQ used by the PL031 RTC.\n"
|
|
msgstr "/// PL031 RTC에서 사용하는 IRQ입니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "\"main({:#x}, {:#x}, {:#x}, {:#x})\""
|
|
msgstr "\"main({:#x}, {:#x}, {:#x}, {:#x})\""
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid ""
|
|
"// Safe because `GICD_BASE_ADDRESS` and `GICR_BASE_ADDRESS` are the base\n"
|
|
" // addresses of a GICv3 distributor and redistributor respectively, and\n"
|
|
" // nothing else accesses those address ranges.\n"
|
|
msgstr ""
|
|
"// `GICD_BASE_ADDRESS` 및 `GICR_BASE_ADDRESS`가 각각 GICv3 배포자 및 재배포자"
|
|
"의\n"
|
|
" // 기본 주소이이고\n"
|
|
" // 이러한 주소 범위에 액세스하는 다른 항목이 없으므로 안전합니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid ""
|
|
"// Safe because `PL031_BASE_ADDRESS` is the base address of a PL031 device,\n"
|
|
" // and nothing else accesses that address range.\n"
|
|
msgstr ""
|
|
"// `PL031_BASE_ADDRESS`가 PL031 기기의 기본 주소이고\n"
|
|
" // 이 주소 범위에 액세스하는 다른 항목이 없으므로 안전합니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "\"RTC: {time}\""
|
|
msgstr "\"RTC: {time}\""
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "// Wait for 3 seconds, without interrupts.\n"
|
|
msgstr "// 인터럽트 없이 3초간 기다립니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "\"Waiting for {}\""
|
|
msgstr "\"{}을(를) 기다리는 중\""
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "\"matched={}, interrupt_pending={}\""
|
|
msgstr "\"matched={}, interrupt_pending={}\""
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "\"Finished waiting\""
|
|
msgstr "\"대기 완료됨\""
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "// Wait another 3 seconds for an interrupt.\n"
|
|
msgstr "// 인터럽트를 위해 3초 더 기다립니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "_pl031.rs_:"
|
|
msgstr "_pl031.rs_:"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Data register\n"
|
|
msgstr "/// 데이터 레지스터\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Match register\n"
|
|
msgstr "/// 일치 레지스터\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Load register\n"
|
|
msgstr "/// 로드 레지스터\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Control register\n"
|
|
msgstr "/// 제어 레지스터\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Interrupt Mask Set or Clear register\n"
|
|
msgstr "/// 인터럽트 마스크 세트 또는 정리 레지스터\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Raw Interrupt Status\n"
|
|
msgstr "/// 원시 인터럽트 상태\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Masked Interrupt Status\n"
|
|
msgstr "/// 마스킹된 인터럽트 상태\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Interrupt Clear Register\n"
|
|
msgstr "/// 인터럽트 정리 레지스터\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Driver for a PL031 real-time clock.\n"
|
|
msgstr "/// PL031 실시간 시계용 드라이버\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid ""
|
|
"/// Constructs a new instance of the RTC driver for a PL031 device at the\n"
|
|
" /// given base address.\n"
|
|
" ///\n"
|
|
" /// # Safety\n"
|
|
" ///\n"
|
|
" /// The given base address must point to the MMIO control registers of "
|
|
"a\n"
|
|
" /// PL031 device, which must be mapped into the address space of the "
|
|
"process\n"
|
|
" /// as device memory and not have any other aliases.\n"
|
|
msgstr ""
|
|
"/// 지정된 기본 주소에 PL031 기기에 대한 RTC 드라이버의 새 인스턴스를\n"
|
|
" /// 생성합니다.\n"
|
|
" ///\n"
|
|
" /// # 안전\n"
|
|
" ///\n"
|
|
" /// 지정된 기본 주소는 PL031 기기의\n"
|
|
" /// MMIO 제어 레지스터를 가리켜야 하며,\n"
|
|
" /// 이는 프로세스의 주소 공간에 기기 메모리로\n"
|
|
" /// 매핑되어야 하며 다른 별칭은 없어야 합니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Reads the current RTC value.\n"
|
|
msgstr "/// 현재 RTC 값을 읽습니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid ""
|
|
"// Safe because we know that self.registers points to the control\n"
|
|
" // registers of a PL031 device which is appropriately mapped.\n"
|
|
msgstr ""
|
|
"// self.registers가 적절하게 매핑된 PL031 기기의 제어 레지스터를\n"
|
|
" // 가리키고 있으므로 안전합니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid ""
|
|
"/// Writes a match value. When the RTC value matches this then an interrupt\n"
|
|
" /// will be generated (if it is enabled).\n"
|
|
msgstr ""
|
|
"/// 일치 값을 작성합니다. RTC 값이 이 값과 일치하면 인터럽트가\n"
|
|
" /// 생성됩니다(사용 설정된 경우).\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid ""
|
|
"/// Returns whether the match register matches the RTC value, whether or "
|
|
"not\n"
|
|
" /// the interrupt is enabled.\n"
|
|
msgstr ""
|
|
"/// 인터럽트가 활성화되었는지 여부와 관계없이 일치 레지스터가 RTC 값과 일치하"
|
|
"는지 여부를\n"
|
|
" /// 반환합니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid ""
|
|
"/// Returns whether there is currently an interrupt pending.\n"
|
|
" ///\n"
|
|
" /// This should be true if and only if `matched` returns true and the\n"
|
|
" /// interrupt is masked.\n"
|
|
msgstr ""
|
|
"/// 현재 대기 중인 인터럽트가 있는지 여부를 반환합니다.\n"
|
|
" ///\n"
|
|
" /// 이는 'matched'가 true를 반환하고 인터럽트가 마스킹된 경우에만\n"
|
|
" /// true여야 합니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid ""
|
|
"/// Sets or clears the interrupt mask.\n"
|
|
" ///\n"
|
|
" /// When the mask is true the interrupt is enabled; when it is false "
|
|
"the\n"
|
|
" /// interrupt is disabled.\n"
|
|
msgstr ""
|
|
"/// 인터럽트 마스크를 설정하거나 지웁니다.\n"
|
|
" ///\n"
|
|
" /// 마스크가 true인 경우 인터럽트가 사용 설정됩니다. false이면\n"
|
|
" /// 인터럽트가 사용 중지됩니다.\n"
|
|
|
|
#: src/exercises/bare-metal/solutions-afternoon.md
|
|
msgid "/// Clears a pending interrupt, if any.\n"
|
|
msgstr "/// 대기 중인 인터럽트가 있는 경우 이를 지웁니다.\n"
|
|
|
|
#: src/concurrency.md
|
|
#, fuzzy
|
|
msgid "Welcome to Concurrency in Rust"
|
|
msgstr "Welcome to Comprehensive Rust 🦀"
|
|
|
|
#: src/concurrency.md
|
|
msgid ""
|
|
"Rust has full support for concurrency using OS threads with mutexes and "
|
|
"channels."
|
|
msgstr ""
|
|
"러스트는 동시성 지원이 막강합니다. 운영체제 레벨의 스레드를 사용하며, 뮤택스"
|
|
"와 채널도 지원합니다."
|
|
|
|
#: src/concurrency.md
|
|
msgid ""
|
|
"The Rust type system plays an important role in making many concurrency bugs "
|
|
"compile time bugs. This is often referred to as _fearless concurrency_ since "
|
|
"you can rely on the compiler to ensure correctness at runtime."
|
|
msgstr ""
|
|
"러스트의 타입 시스템은 프로그램에 동시성 버그가 있을 경우, 컴파일 시에 에러"
|
|
"가 발생하도록 해 줍니다. 컴파일러를 이용해서 프로그램이 수행시에 정확히 동작"
|
|
"함을 미리 보장해 주기 때문에, 사람들은 이를 종종 _겁없는 동시성_ 이라고 합니"
|
|
"다."
|
|
|
|
#: src/concurrency.md
|
|
msgid ""
|
|
"Rust lets us access OS concurrency toolkit: threads, sync. primitives, etc."
|
|
msgstr ""
|
|
|
|
#: src/concurrency.md
|
|
msgid ""
|
|
"The type system gives us safety for concurrency without any special features."
|
|
msgstr ""
|
|
|
|
#: src/concurrency.md
|
|
msgid ""
|
|
"The same tools that help with \"concurrent\" access in a single thread (e."
|
|
"g., a called function that might mutate an argument or save references to it "
|
|
"to read later) save us from multi-threading issues."
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Rust threads work similarly to threads in other languages:"
|
|
msgstr "러스트의 스레드는 다른 언어의 스레드와 유사하게 동작합니다:"
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "\"Count in thread: {i}!\""
|
|
msgstr "\"스레드의 개수: {i}!\""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "\"Main thread: {i}\""
|
|
msgstr "\"기본 스레드: {i}\""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Threads are all daemon threads, the main thread does not wait for them."
|
|
msgstr ""
|
|
"스레드는 모두 데몬 스레드입니다. 따라서 메인 스레드는 이 스레드들이 끝나기를 "
|
|
"기다리지 않습니다."
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Thread panics are independent of each other."
|
|
msgstr "한 스레드에서 발생한 패닉은 다른 스레드에게 영향을 끼치지 않습니다."
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Panics can carry a payload, which can be unpacked with `downcast_ref`."
|
|
msgstr ""
|
|
"패닉은 추가정보(페이로드)를 포함할 수 있으며, 이는 `downcast_ref`로 풀어볼 "
|
|
"수 있습니다."
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Rust thread APIs look not too different from e.g. C++ ones."
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
#, fuzzy
|
|
msgid "Run the example."
|
|
msgstr "아래 명령어로 예제 코드를 실행하세요."
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid ""
|
|
"5ms timing is loose enough that main and spawned threads stay mostly in "
|
|
"lockstep."
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Notice that the program ends before the spawned thread reaches 10!"
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid ""
|
|
"This is because main ends the program and spawned threads do not make it "
|
|
"persist."
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Compare to pthreads/C++ std::thread/boost::thread if desired."
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "How do we wait around for the spawned thread to complete?"
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[`thread::spawn`](https://doc.rust-lang.org/std/thread/fn.spawn.html) "
|
|
"returns a `JoinHandle`. Look at the docs."
|
|
msgstr ""
|
|
"[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) 트레잇"
|
|
"은 어떤 타입의 기본값 인스턴스를 만들때 사용됩니다."
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid ""
|
|
"`JoinHandle` has a [`.join()`](https://doc.rust-lang.org/std/thread/struct."
|
|
"JoinHandle.html#method.join) method that blocks."
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Use `let handle = thread::spawn(...)` and later `handle.join()` to wait for "
|
|
"the thread to finish and have the program count all the way to 10."
|
|
msgstr ""
|
|
"만약 메인 스레드가 자식 스레드가 끝날 때 까지 기다리기를 원한다면 `let "
|
|
"handle = thread::spawn(...)`으로 스레드를 선언한 후 `handle.join()`로 연결하"
|
|
"여 사용합니다."
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Now what if we want to return a value?"
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Look at docs again:"
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[`thread::spawn`](https://doc.rust-lang.org/std/thread/fn.spawn.html)'s "
|
|
"closure returns `T`"
|
|
msgstr ""
|
|
"하지만, [scoped thread](https://doc.rust-lang.org/std/thread/fn.scope.html)에"
|
|
"서는 가능합니다:"
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid ""
|
|
"`JoinHandle` [`.join()`](https://doc.rust-lang.org/std/thread/struct."
|
|
"JoinHandle.html#method.join) returns `thread::Result<T>`"
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Use the `Result` return value from `handle.join()` to get access to the "
|
|
"returned value."
|
|
msgstr ""
|
|
"`handle.join()`사용시 `Result` 반환값을 통해 패닉의 추가정보에 접근할 수 있습"
|
|
"니다. 이 시점에서 [`Any`](https://doc.rust-lang.org/std/any/index.html)에 대"
|
|
"해 이야기를 해 보면 좋습니다."
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Ok, what about the other case?"
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
#, fuzzy
|
|
msgid "Trigger a panic in the thread. Note that this doesn't panic `main`."
|
|
msgstr ""
|
|
"자식 스레드에서 발생한 패닉이 메인 스레드에는 영향을 주지 않음을 확인하시기 "
|
|
"바랍니다."
|
|
|
|
#: src/concurrency/threads.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Access the panic payload. This is a good time to talk about [`Any`](https://"
|
|
"doc.rust-lang.org/std/any/index.html)."
|
|
msgstr ""
|
|
"`handle.join()`사용시 `Result` 반환값을 통해 패닉의 추가정보에 접근할 수 있습"
|
|
"니다. 이 시점에서 [`Any`](https://doc.rust-lang.org/std/any/index.html)에 대"
|
|
"해 이야기를 해 보면 좋습니다."
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Now we can return values from threads! What about taking inputs?"
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Capture something by reference in the thread closure."
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "An error message indicates we must move it."
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "Move it in, see we can compute and then return a derived value."
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "If we want to borrow?"
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid ""
|
|
"Main kills child threads when it returns, but another function would just "
|
|
"return and leave them running."
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "That would be stack use-after-return, which violates memory safety!"
|
|
msgstr ""
|
|
|
|
#: src/concurrency/threads.md
|
|
msgid "How do we avoid this? see next slide."
|
|
msgstr ""
|
|
|
|
#: src/concurrency/scoped-threads.md
|
|
msgid "Normal threads cannot borrow from their environment:"
|
|
msgstr "보통, 스레드는 스레드 밖에서 데이터를 빌릴 수 없습니다:"
|
|
|
|
#: src/concurrency/scoped-threads.md
|
|
msgid ""
|
|
"However, you can use a [scoped thread](https://doc.rust-lang.org/std/thread/"
|
|
"fn.scope.html) for this:"
|
|
msgstr ""
|
|
"하지만, [scoped thread](https://doc.rust-lang.org/std/thread/fn.scope.html)에"
|
|
"서는 가능합니다:"
|
|
|
|
#: src/concurrency/scoped-threads.md
|
|
msgid ""
|
|
"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."
|
|
msgstr ""
|
|
"`thread::scope` 함수가 완료되면 그 안에서 생성된 모든 스레드들이 종료했음이 "
|
|
"보장되기 때문에, 그 때 빌렸던 데이터들을 다시 반환할 수 있기 때문입니다."
|
|
|
|
#: src/concurrency/scoped-threads.md
|
|
msgid ""
|
|
"Normal Rust borrowing rules apply: you can either borrow mutably by one "
|
|
"thread, or immutably by any number of threads."
|
|
msgstr ""
|
|
"일반적인 러스트의 빌림 규칙이 적용됩니다: 한 스레드에 의한 가변 빌림 또는 여"
|
|
"러 스레드에 대한 불변 빌림중 하나만 가능합니다."
|
|
|
|
#: src/concurrency/channels.md
|
|
msgid ""
|
|
"Rust channels have two parts: a `Sender<T>` and a `Receiver<T>`. The two "
|
|
"parts are connected via the channel, but you only see the end-points."
|
|
msgstr ""
|
|
"러스트의 채널은 `Sender<T>` 와 `Receiver<T>` 두 부분으로 구성됩니다. 이 둘은 "
|
|
"채널을 통해 서로 연결되어 있지만, 우리는 채널을 볼 수는 없고 이 양 끝단만을 "
|
|
"사용하게 됩니다."
|
|
|
|
#: src/concurrency/channels.md
|
|
msgid "\"Received: {:?}\""
|
|
msgstr "\"수신됨: {:?}\""
|
|
|
|
#: src/concurrency/channels.md
|
|
msgid ""
|
|
"`mpsc` stands for Multi-Producer, Single-Consumer. `Sender` and `SyncSender` "
|
|
"implement `Clone` (so you can make multiple producers) but `Receiver` does "
|
|
"not."
|
|
msgstr ""
|
|
"`mpsc`는 “Multi-Produce, Single-Consumer”를 의미합니다. `Sender`와 "
|
|
"`SyncSender`는 `Clone`을 구현하지만 (즉, 여러개의 producer를 만들수 있습니"
|
|
"다) `Receiver`는 `Clone`을 구현하지 않습니다."
|
|
|
|
#: src/concurrency/channels.md
|
|
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
|
|
msgid "You get an unbounded and asynchronous channel with `mpsc::channel()`:"
|
|
msgstr "`mpsc::channel()` 함수는 경계가 없는 비동기 채널을 생성합니다:"
|
|
|
|
#: src/concurrency/channels/unbounded.md src/concurrency/channels/bounded.md
|
|
msgid "\"Message {i}\""
|
|
msgstr "\"메시지 {i}\""
|
|
|
|
#: src/concurrency/channels/unbounded.md src/concurrency/channels/bounded.md
|
|
msgid "\"{thread_id:?}: sent Message {i}\""
|
|
msgstr "\"{thread_id:?}: 보낸 메시지 {i}\""
|
|
|
|
#: src/concurrency/channels/unbounded.md src/concurrency/channels/bounded.md
|
|
msgid "\"{thread_id:?}: done\""
|
|
msgstr "\"{thread_id:?}: 완료\""
|
|
|
|
#: src/concurrency/channels/unbounded.md src/concurrency/channels/bounded.md
|
|
msgid "\"Main: got {msg}\""
|
|
msgstr "\"기본: {msg} 받음\""
|
|
|
|
#: src/concurrency/channels/bounded.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"With bounded (synchronous) channels, `send` can block the current thread:"
|
|
msgstr "경계가 있는 동기 채널은 `send`가 현제 스레드를 블로킹 하도록 만듭니다:"
|
|
|
|
#: src/concurrency/channels/bounded.md
|
|
msgid ""
|
|
"Calling `send` will block the current thread until there is space in the "
|
|
"channel for the new message. The thread can be blocked indefinitely if there "
|
|
"is nobody who reads from the channel."
|
|
msgstr ""
|
|
"`send`를 호출하면 채널에 새 메시지를 위한 공간이 확보될 때까지 현재 스레드가 "
|
|
"차단됩니다. 채널에서 읽는 사람이 없는 경우 스레드가 무기한 차단될 수 있습니"
|
|
"다."
|
|
|
|
#: src/concurrency/channels/bounded.md
|
|
msgid ""
|
|
"A call to `send` will abort with an error (that is why it returns `Result`) "
|
|
"if the channel is closed. A channel is closed when the receiver is dropped."
|
|
msgstr ""
|
|
"`send` 호출은 오류와 함께 중단됩니다. 따라서 채널이 닫히면 `Result`를 반환합"
|
|
"니다. 수신자를 삭제하면 채널이 닫힙니다."
|
|
|
|
#: src/concurrency/channels/bounded.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"A bounded channel with a size of zero is called a \"rendezvous channel\". "
|
|
"Every send will block the current thread until another thread calls `recv`."
|
|
msgstr ""
|
|
"크기가 0인 제한된 채널을 'rendezvous 채널'이라고 합니다. 모든 전송은 다른 스"
|
|
"레드가 `read`를 호출할 때까지 현재 스레드를 차단합니다."
|
|
|
|
#: src/concurrency/send-sync.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"How does Rust know to forbid shared access across threads? The answer is in "
|
|
"two traits:"
|
|
msgstr ""
|
|
"러스트는 어떻게 해서 스레드 간에 특정 데이터 타입이 공유될 수 있거나, 안된다"
|
|
"는 것을 알까요? 정답은 다음 두 트레잇에 있습니다:"
|
|
|
|
#: src/concurrency/send-sync.md
|
|
msgid ""
|
|
"[`Send`](https://doc.rust-lang.org/std/marker/trait.Send.html): a type `T` "
|
|
"is `Send` if it is safe to move a `T` across a thread boundary."
|
|
msgstr ""
|
|
"[`Send`](https://doc.rust-lang.org/std/marker/trait.Send.html): `T`가 스레드 "
|
|
"간 이동이 안전하다면, `T`의 타입은 `Send`입니다."
|
|
|
|
#: src/concurrency/send-sync.md
|
|
msgid ""
|
|
"[`Sync`](https://doc.rust-lang.org/std/marker/trait.Sync.html): a type `T` "
|
|
"is `Sync` if it is safe to move a `&T` across a thread boundary."
|
|
msgstr ""
|
|
"[`Sync`](https://doc.rust-lang.org/std/marker/trait.Sync.html): `&T`가 스레"
|
|
"드 간 이동이 안전하다면, `&T`의 타입은 `Sync`입니다."
|
|
|
|
#: src/concurrency/send-sync.md
|
|
msgid ""
|
|
"`Send` and `Sync` are [unsafe traits](../unsafe/unsafe-traits.md). The "
|
|
"compiler will automatically derive them for your types as long as they only "
|
|
"contain `Send` and `Sync` types. You can also implement them manually when "
|
|
"you know it is valid."
|
|
msgstr ""
|
|
"`Send`와 `Sync` 트레잇은 [안전하지 않은 트레잇](../unsafe/unsafe-traits.md)입"
|
|
"니다. 컴파일러는 타입의 요소들이 모두 `Send`와 `Sync` 타입이면 자동으로 이 트"
|
|
"레잇들을 적용시켜 줍니다. 물론 여러분 스스로 맞다고 알고 있다면 직접 구현해"
|
|
"도 됩니다."
|
|
|
|
#: src/concurrency/send-sync.md
|
|
msgid ""
|
|
"One can think of these traits as markers that the type has certain thread-"
|
|
"safety properties."
|
|
msgstr ""
|
|
"`Sync`와 `Send`는 어떤 타입이 특정한 스레드-안전 속성을 가짐을 나타내는 마커"
|
|
"로 생각할 수 있습니다."
|
|
|
|
#: src/concurrency/send-sync.md
|
|
msgid "They can be used in the generic constraints as normal traits."
|
|
msgstr ""
|
|
"이 두 트레이트는 제너릭에서 제약 조건을 나타내는 트레이트로 사용될 수도 있습"
|
|
"니다."
|
|
|
|
#: src/concurrency/send-sync/send.md
|
|
msgid ""
|
|
"A type `T` is [`Send`](https://doc.rust-lang.org/std/marker/trait.Send.html) "
|
|
"if it is safe to move a `T` value to another thread."
|
|
msgstr ""
|
|
"`T`가 스레드 간에 안전하게 이동될 수 있다면, `T`의 타입은 `Send`입니다."
|
|
|
|
#: src/concurrency/send-sync/send.md
|
|
msgid ""
|
|
"The effect of moving ownership to another thread is that _destructors_ will "
|
|
"run in that thread. So the question is when you can allocate a value in one "
|
|
"thread and deallocate it in another."
|
|
msgstr ""
|
|
"소유권을 다른 스레드로 이동하면 소멸자가 해당 스레드에서 실행됩니다. 여기서 "
|
|
"의문은 \"언제 한 스레드에서 값을 할당하고 다른 스레드에서 값을 할당 해제할 "
|
|
"수 있는가\" 입니다."
|
|
|
|
#: src/concurrency/send-sync/send.md
|
|
msgid ""
|
|
"As an example, a connection to the SQLite library must only be accessed from "
|
|
"a single thread."
|
|
msgstr ""
|
|
"예를 들어 SQLite 라이브러리 연결은 단일 스레드에서만 액세스해야 합니다."
|
|
|
|
#: src/concurrency/send-sync/sync.md
|
|
msgid ""
|
|
"A type `T` is [`Sync`](https://doc.rust-lang.org/std/marker/trait.Sync.html) "
|
|
"if it is safe to access a `T` value from multiple threads at the same time."
|
|
msgstr ""
|
|
"`&T`가 여러 스레드에서 안전하게 접근될 수 있다면, `&T`의 타입은 `Sync`입니다."
|
|
|
|
#: src/concurrency/send-sync/sync.md
|
|
msgid "More precisely, the definition is:"
|
|
msgstr "좀 더 정확한 정의는 다음과 같습니다:"
|
|
|
|
#: src/concurrency/send-sync/sync.md
|
|
msgid "`T` is `Sync` if and only if `&T` is `Send`"
|
|
msgstr "`&T`가 `Send`인 경우에만 `T`의 타입이 `Sync`가 됩니다"
|
|
|
|
#: src/concurrency/send-sync/sync.md
|
|
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
|
|
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
|
|
msgid "`Send + Sync`"
|
|
msgstr "`Send + Sync`"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "Most types you come across are `Send + Sync`:"
|
|
msgstr "여러분이 다루게 될 대부분의 타입은 `Send + Sync`입니다:"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`i8`, `f32`, `bool`, `char`, `&str`, ..."
|
|
msgstr "`i8`, `f32`, `bool`, `char`, `&str`, ..."
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`(T1, T2)`, `[T; N]`, `&[T]`, `struct { x: T }`, ..."
|
|
msgstr "`(T1, T2)`, `[T; N]`, `&[T]`, `struct { x: T }`, ..."
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`String`, `Option<T>`, `Vec<T>`, `Box<T>`, ..."
|
|
msgstr "`String`, `Option<T>`, `Vec<T>`, `Box<T>`, ..."
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`Arc<T>`: Explicitly thread-safe via atomic reference count."
|
|
msgstr "`Arc<T>`: 참조 카운트 조작을 아토믹 하기 때문에 스레드 안전함."
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`Mutex<T>`: Explicitly thread-safe via internal locking."
|
|
msgstr ""
|
|
"`Mutex<T>`: 값을 접근하기 위해 뮤택스를 잠궈야 하기 때문에 스레드 안전함."
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`AtomicBool`, `AtomicU8`, ...: Uses special atomic instructions."
|
|
msgstr ""
|
|
"`AtomicBool`, `AtomicU8`, ...: 값을 접근할 때 특별한 아토믹 명령어들을 사용합"
|
|
"니다."
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid ""
|
|
"The generic types are typically `Send + Sync` when the type parameters are "
|
|
"`Send + Sync`."
|
|
msgstr ""
|
|
"제네릭 타입은 일반적으로 타입 파라메터가 `Send + Sync`이면 `Send + Sync` 입니"
|
|
"다."
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`Send + !Sync`"
|
|
msgstr "`Send + !Sync`"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid ""
|
|
"These types can be moved to other threads, but they're not thread-safe. "
|
|
"Typically because of interior mutability:"
|
|
msgstr ""
|
|
"아래 타입들은 다른 스레드로 이동될 수 있지만 내부적으로 값이 변경될 수 있기 "
|
|
"때문에 스레드 안전하지 않습니다:"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`mpsc::Sender<T>`"
|
|
msgstr "`mpsc::Sender<T>`"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`mpsc::Receiver<T>`"
|
|
msgstr "`mpsc::Receiver<T>`"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`Cell<T>`"
|
|
msgstr "`Cell<T>`"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`RefCell<T>`"
|
|
msgstr "`RefCell<T>`"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`!Send + Sync`"
|
|
msgstr "`!Send + Sync`"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid ""
|
|
"These types are thread-safe, but they cannot be moved to another thread:"
|
|
msgstr "아래 타입들은 스레드 안전하지만 다른 스레드로 이동될 수 없습니다:"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`MutexGuard<T: Sync>`: Uses OS level primitives which must be deallocated on "
|
|
"the thread which created them."
|
|
msgstr ""
|
|
"`MutexGuard<T>`: 내부적으로, 운영체제가 제공하는 primitive를 사용하는데, 이 "
|
|
"primitive는 생성된 스레드에서 해제가 이루어져야 합니다. (_역주_: 그래서 다른 "
|
|
"스레드로 옮길 수 없습니다.)"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "`!Send + !Sync`"
|
|
msgstr "`!Send + !Sync`"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid "These types are not thread-safe and cannot be moved to other threads:"
|
|
msgstr ""
|
|
"아래 타입들은 스레드 안전하지도 않고 다른 스레드로 이동될 수도 없습니다:"
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid ""
|
|
"`Rc<T>`: each `Rc<T>` has a reference to an `RcBox<T>`, which contains a non-"
|
|
"atomic reference count."
|
|
msgstr ""
|
|
"`Rc<T>`: `Rc<T>` 는 아토믹하지 않은 방식으로 참조 카운트를 조작하는 "
|
|
"`RcBox<T>`를 참조합니다."
|
|
|
|
#: src/concurrency/send-sync/examples.md
|
|
msgid ""
|
|
"`*const T`, `*mut T`: Rust assumes raw pointers may have special concurrency "
|
|
"considerations."
|
|
msgstr ""
|
|
"`*const T`, `*mut T`: 러스트는 포인터가 스레드 안전하지 않다고 가정합니다."
|
|
|
|
#: src/concurrency/shared_state.md
|
|
msgid ""
|
|
"Rust uses the type system to enforce synchronization of shared data. This is "
|
|
"primarily done via two types:"
|
|
msgstr ""
|
|
"러스트는 주로 아래 두 가지 타입을 이용해서 공유 데이터 동기화를 수행합니다:"
|
|
|
|
#: src/concurrency/shared_state.md
|
|
msgid ""
|
|
"[`Arc<T>`](https://doc.rust-lang.org/std/sync/struct.Arc.html), atomic "
|
|
"reference counted `T`: handles sharing between threads and takes care to "
|
|
"deallocate `T` when the last reference is dropped,"
|
|
msgstr ""
|
|
"[`Arc<T>`](https://doc.rust-lang.org/std/sync/struct.Arc.html), `T`에 대한 아"
|
|
"토믹 참조 카운트: 이 참조는 다수의 스레드 사이에서 공유될 수 있고, 참조하던 "
|
|
"마지막 스레드가 종료할 경우 `T`를 반환합니다."
|
|
|
|
#: src/concurrency/shared_state.md
|
|
msgid ""
|
|
"[`Mutex<T>`](https://doc.rust-lang.org/std/sync/struct.Mutex.html): ensures "
|
|
"mutually exclusive access to the `T` value."
|
|
msgstr ""
|
|
"[`Mutex<T>`](https://doc.rust-lang.org/std/sync/struct.Mutex.html): `T`값에 "
|
|
"대한 상호 배제 엑세스를 보장합니다."
|
|
|
|
#: src/concurrency/shared_state/arc.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[`Arc<T>`](https://doc.rust-lang.org/std/sync/struct.Arc.html) allows shared "
|
|
"read-only access via `Arc::clone`:"
|
|
msgstr ""
|
|
"[`Arc<T>`](https://doc.rust-lang.org/std/sync/struct.Arc.html)의 `clone` 메서"
|
|
"드를 이용하면 여러 스레드가 한 데이터를 동시에 (_역주_: 그리고 안전하게. 스레"
|
|
"드가 하나라도 살아있는 동안에는 `T`가 반환되지 않음) 읽을 수 있습니다:"
|
|
|
|
#: src/concurrency/shared_state/arc.md
|
|
msgid "\"{thread_id:?}: {v:?}\""
|
|
msgstr "\"{thread_id:?}: {v:?}\""
|
|
|
|
#: src/concurrency/shared_state/arc.md src/concurrency/shared_state/example.md
|
|
msgid "\"v: {v:?}\""
|
|
msgstr "\"v: {v:?}\""
|
|
|
|
#: src/concurrency/shared_state/arc.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`Arc` stands for \"Atomic Reference Counted\", a thread safe version of `Rc` "
|
|
"that uses atomic operations."
|
|
msgstr ""
|
|
"`Arc`는 \"Atomic Reference Counted\"를 의미하며, 스레드 안정성을 보장하는 "
|
|
"`Rc`라고 생각하면 됩니다."
|
|
|
|
#: src/concurrency/shared_state/arc.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`Arc<T>` implements `Clone` whether or not `T` does. It implements `Send` "
|
|
"and `Sync` if and only if `T` implements them both."
|
|
msgstr ""
|
|
"`T`가 `Clone`을 구현하든 안하든 `Arc<T>`는 `Clone`을 구현합니다. `Send`와 "
|
|
"`Sync`는 `T`가 이들을 구현하는 경우에만 구현됩니다."
|
|
|
|
#: src/concurrency/shared_state/arc.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`Arc::clone()` has the cost of atomic operations that get executed, but "
|
|
"after that the use of the `T` is free."
|
|
msgstr ""
|
|
"`Arc::clone()`는 아토믹 연산을 수행하기 때문에 그 때 코스트가 좀 있지만, 일"
|
|
"단 `clone()`이 끝난 후 `T`를 사용하는 대에는 아무런 오버헤드가 없습니다."
|
|
|
|
#: src/concurrency/shared_state/arc.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Beware of reference cycles, `Arc` does not use a garbage collector to detect "
|
|
"them."
|
|
msgstr ""
|
|
"순환 참조가 발생하지 않도록 주의해야 합니다. 러스트는 순환 참조를 감지하는 가"
|
|
"비지 컬랙터가 없습니다."
|
|
|
|
#: src/concurrency/shared_state/arc.md
|
|
#, fuzzy
|
|
msgid "`std::sync::Weak` can help."
|
|
msgstr "순환 참조를 피하는데 `std::sync::Weak`가 도움이 될 것입니다."
|
|
|
|
#: src/concurrency/shared_state/mutex.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[`Mutex<T>`](https://doc.rust-lang.org/std/sync/struct.Mutex.html) ensures "
|
|
"mutual exclusion _and_ allows mutable access to `T` behind a read-only "
|
|
"interface (another form of [interior mutability](../../borrowing/interior-"
|
|
"mutability)):"
|
|
msgstr ""
|
|
"[`Mutex<T>`](https://doc.rust-lang.org/std/sync/struct.Mutex.html)를 이용하"
|
|
"면 불변 참조를 통해서도 `T`의 값을 수정할 수가 있으며, _이에 더해서_ 한 번에 "
|
|
"한 스레드만 `T`의 값을 접근(읽거나 쓰거나)함을 보장해 줍니다:"
|
|
|
|
#: src/concurrency/shared_state/mutex.md
|
|
msgid "\"v: {:?}\""
|
|
msgstr "\"v: {:?}\""
|
|
|
|
#: src/concurrency/shared_state/mutex.md
|
|
msgid ""
|
|
"Notice how we have a [`impl<T: Send> Sync for Mutex<T>`](https://doc.rust-"
|
|
"lang.org/std/sync/struct.Mutex.html#impl-Sync-for-Mutex%3CT%3E) blanket "
|
|
"implementation."
|
|
msgstr ""
|
|
"모든 `Mutex<T>`는 [`impl<T: Send> Sync for Mutex<T>`](https://doc.rust-lang."
|
|
"org/std/sync/struct.Mutex.html#impl-Sync-for-Mutex%3CT%3E)를 자동으로 구현함"
|
|
"을 참조하세요."
|
|
|
|
#: src/concurrency/shared_state/mutex.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`Mutex` in Rust looks like a collection with just one element --- the "
|
|
"protected data."
|
|
msgstr ""
|
|
"러스트의 `Mutex`는 오직 하나의 데이터만 담을 수 있는 컬렉션처럼 볼 수도 있습"
|
|
"니다. 다른 컬렉션과 다른 점은, 그 데이터가 동시성 문제로부터 자유롭다는 점입"
|
|
"니다."
|
|
|
|
#: src/concurrency/shared_state/mutex.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"It is not possible to forget to acquire the mutex before accessing the "
|
|
"protected data."
|
|
msgstr ""
|
|
"`Mutex`는 뮤텍스를 획득하지 않으면 보호된 데이터에 접근하는 것이 불가능 하도"
|
|
"록 디자인 되어 있습니다."
|
|
|
|
#: src/concurrency/shared_state/mutex.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"You can get an `&mut T` from an `&Mutex<T>` by taking the lock. The "
|
|
"`MutexGuard` ensures that the `&mut T` doesn't outlive the lock being held."
|
|
msgstr ""
|
|
"`&Mutex<T>`에 대해 lock을 획득하면 `&mut T`를 얻을 수 있습니다. `MutexGuard`"
|
|
"는 `&mut T`가 획득한 lock보다 오래 살아남지 않음을 보장합니다."
|
|
|
|
#: src/concurrency/shared_state/mutex.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`Mutex<T>` implements both `Send` and `Sync` iff (if and only if) `T` "
|
|
"implements `Send`."
|
|
msgstr ""
|
|
"`Mutex<T>`는 오직 `T`가 `Send`를 구현하는 경우에만 `Send`와 `Sync`를 구현합니"
|
|
"다."
|
|
|
|
#: src/concurrency/shared_state/mutex.md
|
|
#, fuzzy
|
|
msgid "A read-write lock counterpart: `RwLock`."
|
|
msgstr "읽기-쓰기 lock은 `RwLock`을 사용합니다."
|
|
|
|
#: src/concurrency/shared_state/mutex.md
|
|
#, fuzzy
|
|
msgid "Why does `lock()` return a `Result`?"
|
|
msgstr "왜 `lock()`이 `Result`를 반환할까요?"
|
|
|
|
#: src/concurrency/shared_state/mutex.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"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`](https://doc.rust-lang.org/std/sync/struct.PoisonError.html). "
|
|
"You can call `into_inner()` on the error to recover the data regardless."
|
|
msgstr ""
|
|
"`Mutex`를 획득한 스레드에서 패닉이 발생하면, 데이터가 올바르지 않은 상황이 "
|
|
"될 수 있습니다. 이를 `Mutex`가 \"중독(poisoned)\" 되었다고 표현하며, 중독된 "
|
|
"뮤텍스에서 `lock()`을 호출하면 실패하고 [`PoisonError`](https://doc.rust-"
|
|
"lang.org/std/sync/struct.PoisonError.html)가 발생합니다. 이러한 오류로부터 데"
|
|
"이터를 복구하기 위해 `into_inner()`를 호출할 수 있습니다."
|
|
|
|
#: src/concurrency/shared_state/example.md
|
|
msgid "Let us see `Arc` and `Mutex` in action:"
|
|
msgstr "`Arc`와 `Mutex`의 동작을 살펴봅시다:"
|
|
|
|
#: src/concurrency/shared_state/example.md
|
|
msgid "// use std::sync::{Arc, Mutex};\n"
|
|
msgstr "// std::sync::{Arc, Mutex}; 사용\n"
|
|
|
|
#: src/concurrency/shared_state/example.md
|
|
msgid "Possible solution:"
|
|
msgstr "가능한 해결책:"
|
|
|
|
#: src/concurrency/shared_state/example.md
|
|
msgid "Notable parts:"
|
|
msgstr "눈여겨 볼 부분:"
|
|
|
|
#: src/concurrency/shared_state/example.md
|
|
msgid ""
|
|
"`v` is wrapped in both `Arc` and `Mutex`, because their concerns are "
|
|
"orthogonal."
|
|
msgstr ""
|
|
"`v`는 `Arc`와 `Mutex` 모두에 포함되어 있습니다. 이는 `Arc`와 `Mutex`가 서로 "
|
|
"완전히 다른 문제를 위한 도구이기 때문입니다."
|
|
|
|
#: src/concurrency/shared_state/example.md
|
|
msgid ""
|
|
"Wrapping a `Mutex` in an `Arc` is a common pattern to share mutable state "
|
|
"between threads."
|
|
msgstr ""
|
|
"`Mutex`를 `Arc`로 래핑하는 것은 가변 상태를 스레드들 간에 공유할 때 흔히 사용"
|
|
"하는 패턴입니다."
|
|
|
|
#: src/concurrency/shared_state/example.md
|
|
msgid ""
|
|
"`v: Arc<_>` needs to be cloned as `v2` before it can be moved into another "
|
|
"thread. Note `move` was added to the lambda signature."
|
|
msgstr ""
|
|
"`v: Arc<_>`를 다른 스레드에서 사용하려면, 먼저 `v2`로 복사를 하고 이를 그 스"
|
|
"레드로 이동 해야 합니다. 그래서 람다의 시그니처에 `move`가 있는 것입니다."
|
|
|
|
#: src/concurrency/shared_state/example.md
|
|
msgid ""
|
|
"Blocks are introduced to narrow the scope of the `LockGuard` as much as "
|
|
"possible."
|
|
msgstr "블록은 `LockGuard`의 범위를 최대한 좁히기 위해 사용되었습니다."
|
|
|
|
#: src/exercises/concurrency/morning.md
|
|
msgid "Let us practice our new concurrency skills with"
|
|
msgstr "동시성 기법들을 연습해 봅시다"
|
|
|
|
#: src/exercises/concurrency/morning.md
|
|
msgid "Dining philosophers: a classic problem in concurrency."
|
|
msgstr "식사하는 철학자 문제: 고적적인 동시성 문제입니다."
|
|
|
|
#: src/exercises/concurrency/morning.md
|
|
msgid ""
|
|
"Multi-threaded link checker: a larger project where you'll use Cargo to "
|
|
"download dependencies and then check links in parallel."
|
|
msgstr ""
|
|
"멀티 스레드 링크 검사기: 병렬적으로 웹페이지의 링크들을 체크합니다. 카고를 통"
|
|
"해 몇 가지 의존성들을 다운도르 받아야 하는 큰 프로젝트 입니다."
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
msgid "The dining philosophers problem is a classic problem in concurrency:"
|
|
msgstr "식사하는 철학자 문제는 동시성에 있어서 고전적인 문제입니다:"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
msgid ""
|
|
"Five philosophers dine together at the same table. Each philosopher has "
|
|
"their own place at the table. There is a fork between each plate. The dish "
|
|
"served is a kind of spaghetti which has to be eaten with two forks. Each "
|
|
"philosopher can only alternately think and eat. Moreover, a philosopher can "
|
|
"only eat their spaghetti when they have both a left and right fork. Thus two "
|
|
"forks will only be available when their two nearest neighbors are thinking, "
|
|
"not eating. After an individual philosopher finishes eating, they will put "
|
|
"down both forks."
|
|
msgstr ""
|
|
"5명의 철학자가 원탁에서 식사를 하고 있습니다. 철학자는 원탁에서 자신의 자리"
|
|
"에 앉아있습니다. 포크는 각 접시 사이에 있습니다. 제공되는 요리를 먹기 위해서"
|
|
"는 두 개의 포크를 모두 사용해야합니다. 철학자는 생각을 하다가 배가 고프면 자"
|
|
"신의 좌,우의 포크를 들어 요리를 먹습니다. 철학자는 요리를 먹은 후에는 포크를 "
|
|
"다시 자리에 내려놓습니다. 철학자는 자신의 좌,우에 포크가 있을때만 요리를 먹"
|
|
"을 수 있습니다. 따라서 두 개의 포크는 오직 자신의 좌,우 철학자가 생각을 할 때"
|
|
"만 사용할 수 있습니다."
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"You will need a local [Cargo installation](../../cargo/running-locally.md) "
|
|
"for this exercise. Copy the code below to a file called `src/main.rs`, fill "
|
|
"out the blanks, and test that `cargo run` does not deadlock:"
|
|
msgstr ""
|
|
"이번 훈련에서는 [카고 설치하기](../../cargo/running-locally.md)가 필요합니"
|
|
"다. 아래 코드를 복사해서 `src/main.rs`에 붙여놓고 빈 부분을 채우고, `cargo "
|
|
"run` 커맨드로 테스트 해서 교착상태(데드락)가 발생하지 않는지 확인합니다:"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
msgid ""
|
|
"// left_fork: ...\n"
|
|
" // right_fork: ...\n"
|
|
" // thoughts: ...\n"
|
|
msgstr ""
|
|
"// left_fork: ...\n"
|
|
" // right_fork: ...\n"
|
|
" // thoughts: ...\n"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"Eureka! {} has a new idea!\""
|
|
msgstr "\"유레카! {}에 새로운 아이디어가 있습니다.\""
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "// Pick up forks...\n"
|
|
msgstr "// 포크를 드세요...\n"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"{} is eating...\""
|
|
msgstr "\"{}님이 먹고 있습니다...\""
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
#, fuzzy
|
|
msgid "\"Socrates\""
|
|
msgstr "HAL 크레이트들"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"Hypatia\""
|
|
msgstr "\"히파티아\""
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"Plato\""
|
|
msgstr "\"플라톤\""
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"Aristotle\""
|
|
msgstr "\"아리스토텔레스\""
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"Pythagoras\""
|
|
msgstr "\"피타고라스\""
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "// Create forks\n"
|
|
msgstr "// 포크 만들기\n"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "// Create philosophers\n"
|
|
msgstr "// 철학자 만들기\n"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
msgid "// Make each of them think and eat 100 times\n"
|
|
msgstr "// 각각 100번 생각하고 먹도록 합니다.\n"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "// Output their thoughts\n"
|
|
msgstr "// 생각을 출력합니다.\n"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
msgid "You can use the following `Cargo.toml`:"
|
|
msgstr "다음과 같은 `Cargo.toml`을 사용할 수 있습니다."
|
|
|
|
#: src/exercises/concurrency/dining-philosophers.md
|
|
msgid ""
|
|
"```toml\n"
|
|
"[package]\n"
|
|
"name = \"dining-philosophers\"\n"
|
|
"version = \"0.1.0\"\n"
|
|
"edition = \"2021\"\n"
|
|
"```"
|
|
msgstr ""
|
|
"```toml\n"
|
|
"[package]\n"
|
|
"name = \"dining-philosophers\"\n"
|
|
"version = \"0.1.0\"\n"
|
|
"edition = \"2021\"\n"
|
|
"```"
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid ""
|
|
"Let us use our new knowledge to create a multi-threaded link checker. It "
|
|
"should start at a webpage and check that links on the page are valid. It "
|
|
"should recursively check other pages on the same domain and keep doing this "
|
|
"until all pages have been validated."
|
|
msgstr ""
|
|
"새로 배운것들을 활용해서 멀티 스레드 링크 검사기를 만듭니다. 이 검사기는 웹페"
|
|
"이지 안에 있는 링크들이 유효한지 확인합니다. 그리고 재귀적으로 동일 도메인의 "
|
|
"다른 모든 페이지가 유효한지 확인합니다."
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid ""
|
|
"For this, you will need an HTTP client such as [`reqwest`](https://docs.rs/"
|
|
"reqwest/). Create a new Cargo project and `reqwest` it as a dependency with:"
|
|
msgstr ""
|
|
"이를 위해서 [`reqwest`](https://docs.rs/reqwest/)와 같은 HTTP 클라이언트가 필"
|
|
"요합니다. 새로운 로컬 프로젝트를 만들고 [`reqwest`](https://docs.rs/reqwest/)"
|
|
"를 의존성에 추가하십시요:"
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid ""
|
|
"If `cargo add` fails with `error: no such subcommand`, then please edit the "
|
|
"`Cargo.toml` file by hand. Add the dependencies listed below."
|
|
msgstr ""
|
|
"만일 `cargo add` 커맨드가 `error: no such subcommand` 로 실패한다면 `Cargo."
|
|
"toml` 파일을 직접 수정해도 됩니다. 아래에 전체 의존성 내용이 있습니다."
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid ""
|
|
"You will also need a way to find links. We can use [`scraper`](https://docs."
|
|
"rs/scraper/) for that:"
|
|
msgstr "링크를 찾기 위해서 [`scraper`](https://docs.rs/scraper/)도 추가합니다:"
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid ""
|
|
"Finally, we'll need some way of handling errors. We use [`thiserror`]"
|
|
"(https://docs.rs/thiserror/) for that:"
|
|
msgstr ""
|
|
"마지막으로 오류 처리하는 방법으로 [`thiserror`](https://docs.rs/thiserror/)"
|
|
"도 추가합니다:"
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid ""
|
|
"The `cargo add` calls will update the `Cargo.toml` file to look like this:"
|
|
msgstr "모든 `cargo add`가 끝나면 `Cargo.toml`에 아래 내용이 추가됩니다:"
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid ""
|
|
"```toml\n"
|
|
"[package]\n"
|
|
"name = \"link-checker\"\n"
|
|
"version = \"0.1.0\"\n"
|
|
"edition = \"2021\"\n"
|
|
"publish = false\n"
|
|
"\n"
|
|
"[dependencies]\n"
|
|
"reqwest = { version = \"0.11.12\", features = [\"blocking\", \"rustls-"
|
|
"tls\"] }\n"
|
|
"scraper = \"0.13.0\"\n"
|
|
"thiserror = \"1.0.37\"\n"
|
|
"```"
|
|
msgstr ""
|
|
"```toml\n"
|
|
"[package]\n"
|
|
"name = \"link-checker\"\n"
|
|
"version = \"0.1.0\"\n"
|
|
"edition = \"2021\"\n"
|
|
"publish = false\n"
|
|
"\n"
|
|
"[dependencies]\n"
|
|
"reqwest = { version = \"0.11.12\", features = [\"blocking\", \"rustls-"
|
|
"tls\"] }\n"
|
|
"scraper = \"0.13.0\"\n"
|
|
"thiserror = \"1.0.37\"\n"
|
|
"```"
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid ""
|
|
"You can now download the start page. Try with a small site such as `https://"
|
|
"www.google.org/`."
|
|
msgstr "이제 `https://www.google.org/` 같은 웹 페이지를 탐색할 수 있습니다."
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid "Your `src/main.rs` file should look something like this:"
|
|
msgstr "`rc/main.rs`파일은 아래와 같습니다:"
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "\"request error: {0}\""
|
|
msgstr "\"요청 오류: {0}\""
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "\"bad http response: {0}\""
|
|
msgstr "\"잘못된 http 응답: {0}\""
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "\"Checking {:#}\""
|
|
msgstr "\"{:#} 확인 중\""
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "\"href\""
|
|
msgstr "\"href\""
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "\"On {base_url:#}: ignored unparsable {href:?}: {err}\""
|
|
msgstr "\"{base_url:#}에서: 파싱할 수 없는 {href:?}: {err}을(를) 무시함\""
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "\"https://www.google.org\""
|
|
msgstr "\"https://www.google.org\""
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid "\"Links: {links:#?}\""
|
|
msgstr "\"링크: {links:#?}\""
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid "\"Could not extract links: {err:#}\""
|
|
msgstr "\"링크를 추출할 수 없습니다: {err:#}\""
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid "Run the code in `src/main.rs` with"
|
|
msgstr "아래 커맨드로 소스를 실행합니다"
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid ""
|
|
"Use threads to check the links in parallel: send the URLs to be checked to a "
|
|
"channel and let a few threads check the URLs in parallel."
|
|
msgstr ""
|
|
"스레드를 사용하여 링크를 병렬로 확인합니다: URL을 채널로 보내서 몇 개의 스레"
|
|
"드가 URL을 병렬로 체크하도록 합니다."
|
|
|
|
#: src/exercises/concurrency/link-checker.md
|
|
msgid ""
|
|
"Extend this to recursively extract links from all pages on the `www.google."
|
|
"org` domain. Put an upper limit of 100 pages or so so that you don't end up "
|
|
"being blocked by the site."
|
|
msgstr ""
|
|
"`www.google.org`도메인의 모든 페이지를 재귀적으로 확인하기 위해 코드를 확장해"
|
|
"서 작성합니다: 차단당하지 않도록 100페이지 정도로 제한을 두시기 바랍니다."
|
|
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
#, fuzzy
|
|
msgid "Concurrency Morning Exercise"
|
|
msgstr "3일차 오전 연습문제"
|
|
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "([back to exercise](dining-philosophers.md))"
|
|
msgstr "([연습문제로 돌아가기](dining-philosophers.md)"
|
|
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "\"{} is trying to eat\""
|
|
msgstr "\"{}님이 식사를 하려고 합니다.\""
|
|
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
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"
|
|
msgstr ""
|
|
"// 교착 상태를 방지하려면 어딘가에서\n"
|
|
" // 대칭을 중단시켜야 합니다. 이렇게 하면 둘 중 어느 하나라도 초기화하"
|
|
"지 않고\n"
|
|
" // 포크가 교체됩니다.\n"
|
|
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "\"{thought}\""
|
|
msgstr "\"{thought}\""
|
|
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
#, fuzzy
|
|
msgid "Link Checker"
|
|
msgstr "멀티스레드 링크 검사기"
|
|
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "([back to exercise](link-checker.md))"
|
|
msgstr "([연습문제로 돌아가기](link-checker.md))"
|
|
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid ""
|
|
"/// Determine whether links within the given page should be extracted.\n"
|
|
msgstr "/// 주어진 페이지 내의 링크를 추출해야 하는지 여부를 결정합니다.\n"
|
|
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid ""
|
|
"/// Mark the given page as visited, returning false if it had already\n"
|
|
" /// been visited.\n"
|
|
msgstr ""
|
|
"/// 지정된 페이지를 방문한 것으로 표시하고 이미 방문한 경우\n"
|
|
" /// false를 반환합니다.\n"
|
|
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "// The sender got dropped. No more commands coming in.\n"
|
|
msgstr "// 발신자가 삭제되었습니다. 더 이상 명령어가 수신되지 않습니다.\n"
|
|
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "\"Got crawling error: {:#}\""
|
|
msgstr "\"크롤링 오류 발생: {:#}\""
|
|
|
|
#: src/exercises/concurrency/solutions-morning.md
|
|
msgid "\"Bad URLs: {:#?}\""
|
|
msgstr "\"잘못된 URL: {:#?}\""
|
|
|
|
#: src/async.md
|
|
#, fuzzy
|
|
msgid "Async Rust"
|
|
msgstr "비동기"
|
|
|
|
#: src/async.md
|
|
msgid ""
|
|
"\"Async\" is a concurrency model where multiple tasks are executed "
|
|
"concurrently by executing each task until it would block, then switching to "
|
|
"another task that is ready to make progress. The model allows running a "
|
|
"larger number of tasks on a limited number of threads. This is because the "
|
|
"per-task overhead is typically very low and operating systems provide "
|
|
"primitives for efficiently identifying I/O that is able to proceed."
|
|
msgstr ""
|
|
"\"Async\"는 블럭될(더 이상 진행할 수 없을) 때까지 각 작업을 실행한 다음 진행"
|
|
"할 준비가 된 다른 작업으로 전환하여 여러 작업을 동시에 실행하는 동시 실행 모"
|
|
"델입니다. 이 모델을 사용하면 제한된 수의 스레드에서 더 많은 작업을 실행할 수 "
|
|
"있습니다. 이는, 한 작업을 유지하고 수행하는데 필요한 오버헤드가 (스레드에 비"
|
|
"해) 매우 낮고 운영체제가 여러 I/O들에서 현재 진행 가능한 I/O들을 효과적으로 "
|
|
"식별해 주는 프리미티브를 제공하기 때문입니다."
|
|
|
|
#: src/async.md
|
|
msgid ""
|
|
"Rust's asynchronous operation is based on \"futures\", which represent work "
|
|
"that may be completed in the future. Futures are \"polled\" until they "
|
|
"signal that they are complete."
|
|
msgstr ""
|
|
"Rust의 비동기 작업은 \"futures\"를 기반으로 하며 이는 미래에 완료될 수 있는 "
|
|
"작업을 나타냅니다. Futures는 완료되었다는 신호를 보낼 때까지 \"폴링\"됩니다."
|
|
|
|
#: src/async.md
|
|
msgid ""
|
|
"Futures are polled by an async runtime, and several different runtimes are "
|
|
"available."
|
|
msgstr ""
|
|
"Futures는 비동기 런타임에 의해 폴링되며, 비동기 런타임에는 여러 다양한 종류"
|
|
"가 있습니다."
|
|
|
|
#: src/async.md
|
|
msgid ""
|
|
"Python has a similar model in its `asyncio`. However, its `Future` type is "
|
|
"callback-based, and not polled. Async Python programs require a \"loop\", "
|
|
"similar to a runtime in Rust."
|
|
msgstr ""
|
|
"파이썬에도 `asyncio`라는 유사한 모델이 있습니다. 그러나 파이썬의 `Future` 타"
|
|
"입은 콜백 기반이며 폴링되지 않습니다. 파이썬으로 비동기 프로그래밍을 할 때에"
|
|
"는, Rust에서 런타임이 내부적으로 해 주는 것과 유사한, \"루프\"를 명시적으로 "
|
|
"사용해야 합니다."
|
|
|
|
#: src/async.md
|
|
msgid ""
|
|
"JavaScript's `Promise` is similar, but again callback-based. The language "
|
|
"runtime implements the event loop, so many of the details of Promise "
|
|
"resolution are hidden."
|
|
msgstr ""
|
|
"자바스크립트의 `Promise`도 비슷하지만 역시 콜백 기반입니다. 자바스크립트에서"
|
|
"는 이벤트 루프가런타임 엔진에서 구현되므로 `Promise`가 처리되는 세부 과정이 "
|
|
"숨겨집니다."
|
|
|
|
#: src/async/async-await.md
|
|
msgid ""
|
|
"At a high level, async Rust code looks very much like \"normal\" sequential "
|
|
"code:"
|
|
msgstr ""
|
|
"겉에서 보았을 때, 비동기 Rust 코드는 일반적인 절차적 코드와 매우 유사합니다."
|
|
|
|
#: src/async/async-await.md
|
|
msgid "\"Count is: {i}!\""
|
|
msgstr "\"수: {i}개!\""
|
|
|
|
#: src/async/async-await.md
|
|
msgid ""
|
|
"Note that this is a simplified example to show the syntax. There is no long "
|
|
"running operation or any real concurrency in it!"
|
|
msgstr ""
|
|
"Rust 비동기 문법을 보여주는 간단한 예시입니다. 여기에는 오래 실행되는 작업이"
|
|
"나, 실제로 동시에 수행되는 것들은 없습니다."
|
|
|
|
#: src/async/async-await.md
|
|
msgid "What is the return type of an async call?"
|
|
msgstr "`async`함수의 리턴 타입은 무엇인가요?"
|
|
|
|
#: src/async/async-await.md
|
|
msgid "Use `let future: () = async_main(10);` in `main` to see the type."
|
|
msgstr ""
|
|
"`main`에서 \\`let future: () = async_main(10);을 사용하여 타입을 확인하세요."
|
|
|
|
#: src/async/async-await.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The \"async\" keyword is syntactic sugar. The compiler replaces the return "
|
|
"type with a future."
|
|
msgstr ""
|
|
"\"async\" 키워드는 문법 설탕(syntactic sugar)입니다. 컴파일러가 리턴 타입을 "
|
|
"future로 바꿉니다. "
|
|
|
|
#: src/async/async-await.md
|
|
msgid ""
|
|
"You cannot make `main` async, without additional instructions to the "
|
|
"compiler on how to use the returned future."
|
|
msgstr ""
|
|
"`main`을 비동기 함수로 만들수는 없습니다. 만약 그렇게 할 경우 컴파일러는 리"
|
|
"턴 타입인 future를 어떻게 사용할 지 모르기 때문입니다."
|
|
|
|
#: src/async/async-await.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"You need an executor to run async code. `block_on` blocks the current thread "
|
|
"until the provided future has run to completion."
|
|
msgstr ""
|
|
"비동기 코드를 실행하려면 실행자(executor)가 필요합니다. `block_on` 실행자는 "
|
|
"제공된 future가 완료될 때까지 현재 스레드를 블록합니다. "
|
|
|
|
#: src/async/async-await.md
|
|
msgid ""
|
|
"`.await` asynchronously waits for the completion of another operation. "
|
|
"Unlike `block_on`, `.await` doesn't block the current thread."
|
|
msgstr ""
|
|
"`.await`는 다른 작업이 완료될 때까지 비동기적으로 대기합니다. `block_on`과 달"
|
|
"리 `.await`는 현재 스레드를 블록하지 않습니다."
|
|
|
|
#: src/async/async-await.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"`.await` can only be used inside an `async` function (or block; these are "
|
|
"introduced later)."
|
|
msgstr ""
|
|
"`.await`는 `async` 함수(또는 나중에 소개될 `async` 블록) 안에서만 사용할 수 "
|
|
"있습니다. "
|
|
|
|
#: src/async/futures.md
|
|
msgid ""
|
|
"[`Future`](https://doc.rust-lang.org/std/future/trait.Future.html) is a "
|
|
"trait, implemented by objects that represent an operation that may not be "
|
|
"complete yet. A future can be polled, and `poll` returns a [`Poll`](https://"
|
|
"doc.rust-lang.org/std/task/enum.Poll.html)."
|
|
msgstr ""
|
|
"[`Future`](https://doc.rust-lang.org/std/future/trait.Future.html)는 트레잇입"
|
|
"니다.이 트레잇은 아직 완료되지 않았을 수도 있는 작업을 나타냅니다. Future는 "
|
|
"`poll` 함수를 통해 폴링될 수 있으며, 이 함수는 [`Poll`](https://doc.rust-"
|
|
"lang.org/std/task/enum.Poll.html)을 반환합니다."
|
|
|
|
#: src/async/futures.md
|
|
msgid ""
|
|
"An async function returns an `impl Future`. It's also possible (but "
|
|
"uncommon) to implement `Future` for your own types. For example, the "
|
|
"`JoinHandle` returned from `tokio::spawn` implements `Future` to allow "
|
|
"joining to it."
|
|
msgstr ""
|
|
"비동기 함수는 `impl Future`를 반환합니다. 새로운 타입을 만들고 이 타입이 "
|
|
"`Future`를 구현하게 할 수도 있지만 일반적이지는 않습니다. 예를 들어 `tokio::"
|
|
"spawn`가 리턴하는 `JoinHandle`은 `Future`를 구현하며, 이를 통해 생성된 스레드"
|
|
"에 join할 수 있습니다."
|
|
|
|
#: src/async/futures.md
|
|
msgid ""
|
|
"The `.await` keyword, applied to a Future, causes the current async function "
|
|
"to pause until that Future is ready, and then evaluates to its output."
|
|
msgstr ""
|
|
"Future에 `.await`를 호출하면, 해당 Future가 준비될 때까지 현재 비동기 함수가 "
|
|
"일시 중지됩니다. 그런 다음 Future가 준비가 되면, 그 값이 `.await` 구문의 값"
|
|
"이 됩니다."
|
|
|
|
#: src/async/futures.md
|
|
msgid ""
|
|
"The `Future` and `Poll` types are implemented exactly as shown; click the "
|
|
"links to show the implementations in the docs."
|
|
msgstr ""
|
|
"`Future` 와 `Poll` 타입의 실제 정의는 위에 보이는 그대로 입니다. 링크를 클릭"
|
|
"하면 Rust 문서에서 한 번 더 확인할 수 있습니다."
|
|
|
|
#: src/async/futures.md
|
|
msgid ""
|
|
"We will not get to `Pin` and `Context`, as we will focus on writing async "
|
|
"code, rather than building new async primitives. Briefly:"
|
|
msgstr ""
|
|
"본 강의의 목적은 비동기 코드를 작성하는데 있기 때문에, 새로운 비동기 프리미티"
|
|
"브를 만드는데 필요한 `Pin`과 `Context`는 다루지 않습니다. 이들에 대해 간단"
|
|
"히 설명하자면:"
|
|
|
|
#: src/async/futures.md
|
|
msgid ""
|
|
"`Context` allows a Future to schedule itself to be polled again when an "
|
|
"event occurs."
|
|
msgstr ""
|
|
"`Context`를 사용하면 Future가 이벤트가 발생할 때 다시 폴링되도록 예약할 수 있"
|
|
"습니다."
|
|
|
|
#: src/async/futures.md
|
|
msgid ""
|
|
"`Pin` ensures that the Future isn't moved in memory, so that pointers into "
|
|
"that future remain valid. This is required to allow references to remain "
|
|
"valid after an `.await`."
|
|
msgstr ""
|
|
"`Pin`을 사용하면 메모리에서 Future의 위치가 고정되기 때문에 해당 future의 포"
|
|
"인터가 항상 유효하게 유지됩니다. 이는 `.await` 후에 참조를 유효한 상태로 유지"
|
|
"하기 위해 필요합니다."
|
|
|
|
#: src/async/runtimes.md
|
|
msgid ""
|
|
"A _runtime_ provides support for performing operations asynchronously (a "
|
|
"_reactor_) and is responsible for executing futures (an _executor_). Rust "
|
|
"does not have a \"built-in\" runtime, but several options are available:"
|
|
msgstr ""
|
|
"비동기 _런타임_은 _리액터_ (비동기식 작업 실행을 지원)와 _실행자_ (futures를 "
|
|
"실행)의 두 가지 역할을 합니다. Rust 언어 자체에서 기본 제공하는 비동기 런타임"
|
|
"은 없습니다. 그러나 다음과 같은 비동기 런타임 크레잇들이 있습니다."
|
|
|
|
#: src/async/runtimes.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[Tokio](https://tokio.rs/): performant, with a well-developed ecosystem of "
|
|
"functionality like [Hyper](https://hyper.rs/) for HTTP or [Tonic](https://"
|
|
"github.com/hyperium/tonic) for gRPC."
|
|
msgstr ""
|
|
"[Tokio](https://tokio.rs/) - 성능이 우수합니다. 그리고 HTTP를 지원하는 "
|
|
"[Hyper](https://hyper.rs/) 와 gRPC를 지원하는 [Tonic](https://github.com/"
|
|
"hyperium/tonic)과 같은 잘 발달된 라이브러리 생태계가 있습니다."
|
|
|
|
#: src/async/runtimes.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[async-std](https://async.rs/): aims to be a \"std for async\", and includes "
|
|
"a basic runtime in `async::task`."
|
|
msgstr ""
|
|
"[async-std](https://async.rs/) - 비동기에서의 `std`를 목표로 하고 있습니다. "
|
|
"`async::task`에 기본 런타임이 포함되어 있습니다."
|
|
|
|
#: src/async/runtimes.md
|
|
#, fuzzy
|
|
msgid "[smol](https://docs.rs/smol/latest/smol/): simple and lightweight"
|
|
msgstr "[smol](https://docs.rs/smol/latest/smol/) - 간단하고 가볍습니다."
|
|
|
|
#: src/async/runtimes.md
|
|
msgid ""
|
|
"Several larger applications have their own runtimes. For example, [Fuchsia]"
|
|
"(https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/src/lib/fuchsia-"
|
|
"async/src/lib.rs) already has one."
|
|
msgstr ""
|
|
"여러 대규모 애플리케이션에는 자체 런타임이 있는 경우도 있습니다. 예들 들어 "
|
|
"[Fuchsia](https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/src/lib/"
|
|
"fuchsia-async/src/lib.rs)가 있습니다."
|
|
|
|
#: src/async/runtimes.md
|
|
msgid ""
|
|
"Note that of the listed runtimes, only Tokio is supported in the Rust "
|
|
"playground. The playground also does not permit any I/O, so most interesting "
|
|
"async things can't run in the playground."
|
|
msgstr ""
|
|
"Rust 플레이그라운드에서는 위에 나열된 비동기 런타임 중에서 Tokio만 사용할 수 "
|
|
"있습니다. 또한 Rust 플레이그라운드는 I/O를 허용하지 않으므로 async를 가지고 "
|
|
"할 수 있는 많은 흥미로운 작업들이 불가능 합니다."
|
|
|
|
#: src/async/runtimes.md
|
|
msgid ""
|
|
"Futures are \"inert\" in that they do not do anything (not even start an I/O "
|
|
"operation) unless there is an executor polling them. This differs from JS "
|
|
"Promises, for example, which will run to completion even if they are never "
|
|
"used."
|
|
msgstr ""
|
|
"Futures는 실행자가 폴링하지 않는 한 아무것도 하지 않는다는 점에서(I/O 작업조"
|
|
"차 시작하지 않음) \"비활성\" 상태입니다. 이는 사용되지 않는 경우에도 완료될 "
|
|
"때 까지 실행되는, 자바 스크립트의 promise와 다릅니다."
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
#, fuzzy
|
|
msgid "Tokio provides:"
|
|
msgstr "Tokio는 다음을 제공합니다. "
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
msgid "A multi-threaded runtime for executing asynchronous code."
|
|
msgstr "비동기 코드 실행을 위한 멀티스레드 런타임"
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
msgid "An asynchronous version of the standard library."
|
|
msgstr "표준 라이브러리의 비동기 버전"
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
msgid "A large ecosystem of libraries."
|
|
msgstr "대규모 라이브러리 생태계"
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
msgid "\"Count in task: {i}!\""
|
|
msgstr "\"작업 개수: {i}개!\""
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
msgid "\"Main task: {i}\""
|
|
msgstr "\"기본 작업: {i}\""
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
msgid "With the `tokio::main` macro we can now make `main` async."
|
|
msgstr ""
|
|
"이제 `tokio::main` 매크로를 사용하면 `main`을 비동기로 만들 수 있습니다."
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
msgid "The `spawn` function creates a new, concurrent \"task\"."
|
|
msgstr "`spawn` 함수는 동시 실행되는 새로운 \"작업\"을 만듭니다."
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
msgid "Note: `spawn` takes a `Future`, you don't call `.await` on `count_to`."
|
|
msgstr ""
|
|
"참고: `spawn`은 `Future`를 인자로 받습니다. 때문에 `count_to`에 `.await`를 호"
|
|
"출하지 않는 점을 주목하세요."
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
msgid "**Further exploration:**"
|
|
msgstr "**심화 학습:**"
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
msgid ""
|
|
"Why does `count_to` not (usually) get to 10? This is an example of async "
|
|
"cancellation. `tokio::spawn` returns a handle which can be awaited to wait "
|
|
"until it finishes."
|
|
msgstr ""
|
|
"`count_to`가 10에 도달하지 않는 경우가 많은데 그 이유는 무엇일까요? 이는 비동"
|
|
"기적인 취소를 보여주는 예입니다. `tokio::spawn`이 리턴하는 것은 완료될 때까"
|
|
"지 기다리도록 대기하는데 사용되는 핸들입니다."
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
msgid "Try `count_to(10).await` instead of spawning."
|
|
msgstr "`tokio::spawn` 대신 `count_to(10).await`를 사용해 보세요."
|
|
|
|
#: src/async/runtimes/tokio.md
|
|
msgid "Try awaiting the task returned from `tokio::spawn`."
|
|
msgstr "`tokio::spawn`에서 반환된 작업을 `await` 해 보세요."
|
|
|
|
#: src/async/tasks.md
|
|
msgid "Rust has a task system, which is a form of lightweight threading."
|
|
msgstr "Rust의 태스크(작업) 시스템은 경량 스레딩의 한 종류로 볼 수 있습니다."
|
|
|
|
#: src/async/tasks.md
|
|
msgid ""
|
|
"A task has a single top-level future which the executor polls to make "
|
|
"progress. That future may have one or more nested futures that its `poll` "
|
|
"method polls, corresponding loosely to a call stack. Concurrency within a "
|
|
"task is possible by polling multiple child futures, such as racing a timer "
|
|
"and an I/O operation."
|
|
msgstr ""
|
|
"하나의 작업에는, 실행자가 이 작업을 진행하기 위해 계속 폴링하는, 최상위 "
|
|
"future가 한 개 있습니다. 이 future에는 `poll` 메서드가 폴링하는 중첩된 future"
|
|
"가 한 개 이상 있을 수 있습니다. 이러한 중첩된 future는 일반적인 함수 호출 스"
|
|
"택하고 비슷한 역할을 합니다. 한 작업 안에서 여러 자식 future들을 폴링하면, 타"
|
|
"이머를 켜는 것과 어떤 I/O작업을 동시에 수행시킨 후 타이머와 I/O 중 먼저 끝나"
|
|
"는 것을 기다리는 것과 같은동시성도 구현할 수 있습니다."
|
|
|
|
#: src/async/tasks.md
|
|
msgid "\"127.0.0.1:0\""
|
|
msgstr "\"127.0.0.1:0\""
|
|
|
|
#: src/async/tasks.md
|
|
msgid "\"listening on port {}\""
|
|
msgstr "\"포트 {}에서 수신 대기\""
|
|
|
|
#: src/async/tasks.md
|
|
msgid "\"connection from {addr:?}\""
|
|
msgstr "\"{addr:?}에서 연결\""
|
|
|
|
#: src/async/tasks.md
|
|
msgid "b\"Who are you?\\n\""
|
|
msgstr "b\"누구세요?\\n\""
|
|
|
|
#: src/async/tasks.md
|
|
msgid "\"socket error\""
|
|
msgstr "\"소켓 오류\""
|
|
|
|
#: src/async/tasks.md
|
|
msgid "\"Thanks for dialing in, {name}!\\n\""
|
|
msgstr "\"{name}님, 전화해 주셔서 감사합니다.\\n\""
|
|
|
|
#: src/async/tasks.md src/async/control-flow/join.md
|
|
msgid ""
|
|
"Copy this example into your prepared `src/main.rs` and run it from there."
|
|
msgstr ""
|
|
"이 예제를, 로컬 컴퓨터에 만들어 둔 `src/main.rs`에 복사하고 거기에서 실행하세"
|
|
"요."
|
|
|
|
#: src/async/tasks.md
|
|
msgid ""
|
|
"Try connecting to it with a TCP connection tool like [nc](https://www.unix."
|
|
"com/man-page/linux/1/nc/) or [telnet](https://www.unix.com/man-page/linux/1/"
|
|
"telnet/)."
|
|
msgstr ""
|
|
"[nc](https://www.unix.com/man-page/linux/1/nc/) 또는 [telnet](https://www."
|
|
"unix.com/man-page/linux/1/telnet/)과 같은 TCP 연결 도구를 사용하여 연결해 보"
|
|
"세요."
|
|
|
|
#: src/async/tasks.md
|
|
msgid ""
|
|
"Ask students to visualize what the state of the example server would be with "
|
|
"a few connected clients. What tasks exist? What are their Futures?"
|
|
msgstr ""
|
|
"수강생들에게 이 서버에 몇 개의 클라이언트가 연결되면 이 서버의 상태가 어떻게 "
|
|
"변할지 그림을 그려보도록 하세요. 어떤 태스크들이 있는지, 이 태스크들의 Future"
|
|
"는 어떤 상태에 있는지 물어봅니다."
|
|
|
|
#: src/async/tasks.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"This is the first time we've seen an `async` block. This is similar to a "
|
|
"closure, but does not take any arguments. Its return value is a Future, "
|
|
"similar to an `async fn`."
|
|
msgstr ""
|
|
"`async` 블록을 처음 보게 되었습니다. 이것은 클로저와 비슷하지만 인자를 받지 "
|
|
"않습니다. 리턴 타입은 `async fn`과 비슷한 Future입니다. "
|
|
|
|
#: src/async/tasks.md
|
|
msgid ""
|
|
"Refactor the async block into a function, and improve the error handling "
|
|
"using `?`."
|
|
msgstr ""
|
|
"Async 블록을 함수로 리팩터링하고 `?`를 사용하여 오류 처리를 개선해 봅시다."
|
|
|
|
#: src/async/channels.md
|
|
msgid ""
|
|
"Several crates have support for asynchronous channels. For instance `tokio`:"
|
|
msgstr ""
|
|
"여러 크레이트에서 비동기 채널을 지원합니다. 예를 들어 `tokio`에서는 아래와 같"
|
|
"이합니다."
|
|
|
|
#: src/async/channels.md
|
|
msgid "\"Received {count} pings so far.\""
|
|
msgstr "\"지금까지 핑 {count}개를 받았습니다.\""
|
|
|
|
#: src/async/channels.md
|
|
msgid "\"ping_handler complete\""
|
|
msgstr "\"ping_handler 완료\""
|
|
|
|
#: src/async/channels.md
|
|
msgid "\"Failed to send ping.\""
|
|
msgstr "\"핑을 보내지 못했습니다.\""
|
|
|
|
#: src/async/channels.md
|
|
msgid "\"Sent {} pings so far.\""
|
|
msgstr "\"지금까지 핑 {}개를 전송했습니다.\""
|
|
|
|
#: src/async/channels.md
|
|
msgid "\"Something went wrong in ping handler task.\""
|
|
msgstr "\"핑 핸들러 작업에 문제가 발생했습니다.\""
|
|
|
|
#: src/async/channels.md
|
|
msgid "Change the channel size to `3` and see how it affects the execution."
|
|
msgstr "채널 크기를 `3`으로 변경하고 동작이 어떻게 바뀌는지 확인하세요."
|
|
|
|
#: src/async/channels.md
|
|
msgid ""
|
|
"Overall, the interface is similar to the `sync` channels as seen in the "
|
|
"[morning class](concurrency/channels.md)."
|
|
msgstr ""
|
|
"비동기 채널을 사용하기 위한 인터페이스는 [오전 과정](concurrency/channels.md)"
|
|
"에서 배운 `sync` 채널과 비슷합니다."
|
|
|
|
#: src/async/channels.md
|
|
msgid "Try removing the `std::mem::drop` call. What happens? Why?"
|
|
msgstr ""
|
|
"`std::mem::drop` 호출하는 줄을 삭제해 보세요. 어떤 결과가 나타나나요? 이유가 "
|
|
"무엇인가요?"
|
|
|
|
#: src/async/channels.md
|
|
msgid ""
|
|
"The [Flume](https://docs.rs/flume/latest/flume/) crate has channels that "
|
|
"implement both `sync` and `async` `send` and `recv`. This can be convenient "
|
|
"for complex applications with both IO and heavy CPU processing tasks."
|
|
msgstr ""
|
|
"[Flume](https://docs.rs/flume/latest/flume/) 크레이트에는 `sync`와 `async`, "
|
|
"`send`와 `recv`를 모두 구현하는 채널이 있습니다. 이것은 IO와 CPU 처리 작업이 "
|
|
"많은 복잡한 애플리케이션을 구현할 때 매우 유용합니다."
|
|
|
|
#: src/async/channels.md
|
|
msgid ""
|
|
"What makes working with `async` channels preferable is the ability to "
|
|
"combine them with other `future`s to combine them and create complex control "
|
|
"flow."
|
|
msgstr ""
|
|
"`async` 채널을 사용하는 것이 더 좋은 이유는 이를 다른 `future`와 결합하여 복"
|
|
"잡한 제어 흐름을 만들 수 있기 때문입니다."
|
|
|
|
#: src/async/control-flow.md
|
|
#, fuzzy
|
|
msgid "Futures Control Flow"
|
|
msgstr "흐름 제어"
|
|
|
|
#: src/async/control-flow.md
|
|
msgid ""
|
|
"Futures can be combined together to produce concurrent compute flow graphs. "
|
|
"We have already seen tasks, that function as independent threads of "
|
|
"execution."
|
|
msgstr ""
|
|
"Future들을 결합하여 계산 과정을 동시성이 있는 플로우 그래프 형태로 모델링 할 "
|
|
"수 있습니다. 앞서 배운, 각 태스크가 독립적으로 수행되도록 하는 것도 Future들"
|
|
"을 결합하는 한 방법으로 볼 수 있습니다."
|
|
|
|
#: src/async/control-flow.md
|
|
msgid "[Join](control-flow/join.md)"
|
|
msgstr "[Join](control-flow/join.md)"
|
|
|
|
#: src/async/control-flow.md
|
|
msgid "[Select](control-flow/select.md)"
|
|
msgstr "[Select](control-flow/select.md)"
|
|
|
|
#: src/async/control-flow/join.md
|
|
msgid ""
|
|
"A join operation waits until all of a set of futures are ready, and returns "
|
|
"a collection of their results. This is similar to `Promise.all` in "
|
|
"JavaScript or `asyncio.gather` in Python."
|
|
msgstr ""
|
|
"Join 연산은 모든 future가 준비될 때까지 기다린 후, 각 future의 결과값을 담은 "
|
|
"컬렉션을 리턴합니다. 이는 자바스크립트의 `Promise.all`이나 파이썬의 `asyncio."
|
|
"gather`와 유사합니다."
|
|
|
|
#: src/async/control-flow/join.md
|
|
msgid "\"https://google.com\""
|
|
msgstr "\"https://google.com\""
|
|
|
|
#: src/async/control-flow/join.md
|
|
msgid "\"https://httpbin.org/ip\""
|
|
msgstr "\"https://httpbin.org/ip\""
|
|
|
|
#: src/async/control-flow/join.md
|
|
msgid "\"https://play.rust-lang.org/\""
|
|
msgstr "\"https://play.rust-lang.org/\""
|
|
|
|
#: src/async/control-flow/join.md
|
|
msgid "\"BAD_URL\""
|
|
msgstr "\"BAD_URL\""
|
|
|
|
#: src/async/control-flow/join.md
|
|
msgid ""
|
|
"For multiple futures of disjoint types, you can use `std::future::join!` but "
|
|
"you must know how many futures you will have at compile time. This is "
|
|
"currently in the `futures` crate, soon to be stabilised in `std::future`."
|
|
msgstr ""
|
|
"서로 다른 타입을 가지는 여러 여러 futures들을 join하고자 할 경우 `std::"
|
|
"future::join!`을 사용할 수 있습니다. 이 매크로를 사용하려면 futures가 몇 개"
|
|
"나 있을지 컴파일 할 때 알아야 한다는 점을 주의하세요. 이 매크로는 지금은 "
|
|
"`futures` 크레이트에 있으며 곧 안정화 되어 `std::future`에 포함될 예정입니다."
|
|
|
|
#: src/async/control-flow/join.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The risk of `join` is that one of the futures may never resolve, this would "
|
|
"cause your program to stall."
|
|
msgstr ""
|
|
"`join`의 위험성은 futures들 중 하나가 영영 끝나지 않을 수도 있다는 것입니다. "
|
|
"그러면 프로그램이 더이상 진행을 못하고 멈춰있을(stall) 수 있습니다. "
|
|
|
|
#: src/async/control-flow/join.md
|
|
msgid ""
|
|
"You can also combine `join_all` with `join!` for instance to join all "
|
|
"requests to an http service as well as a database query. Try adding a "
|
|
"`tokio::time::sleep` to the future, using `futures::join!`. This is not a "
|
|
"timeout (that requires `select!`, explained in the next chapter), but "
|
|
"demonstrates `join!`."
|
|
msgstr ""
|
|
"`join_all`을 `join!`과 결합하여 http 서비스와 데이터베이스에 대한 모든 요청들"
|
|
"을 한꺼번에 진행시킬 수도 있습니다. `futures::join!`을 사용하여 `tokio::"
|
|
"time::sleep`을 future에 추가해 보세요. 이건 타임아웃을 구현하는 것이 아님을 "
|
|
"주의하세요. 실제로, 타임아웃은 다음 장에서 설명하는 `select!`를 사용해서 구"
|
|
"현해야 합니다. 여기서는 `tokio::time::sleep`을 사용한 것은 단순히 `join!`의 "
|
|
"동작을 설명하기 위함입니다."
|
|
|
|
#: src/async/control-flow/select.md
|
|
msgid ""
|
|
"A select operation waits until any of a set of futures is ready, and "
|
|
"responds to that future's result. In JavaScript, this is similar to `Promise."
|
|
"race`. In Python, it compares to `asyncio.wait(task_set, return_when=asyncio."
|
|
"FIRST_COMPLETED)`."
|
|
msgstr ""
|
|
"Select 연산은 여러 future들 모두에 대해서 준비될 때 까지 기다리다가, 그 중 어"
|
|
"떤 한 future가 최초로 준비 상태가 되면 해당 future의 결과값을 리턴합니다. 이"
|
|
"것은 자바스크립트에서의 `Promise.race`와 비슷합니다. 파이썬에서라면 `asyncio."
|
|
"wait(task_set, return_when=asyncio.FIRST_COMPLETED)`가 하는 동작과 비슷합니"
|
|
"다."
|
|
|
|
#: src/async/control-flow/select.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Similar to a match statement, the body of `select!` has a number of arms, "
|
|
"each of the form `pattern = future => statement`. When a `future` is ready, "
|
|
"its return value is destructured by the `pattern`. The `statement` is then "
|
|
"run with the resulting variables. The `statement` result becomes the result "
|
|
"of the `select!` macro."
|
|
msgstr ""
|
|
"`select!` 안에는, `match`문과 비슷하게, `pattern = future => statement` 형태"
|
|
"의 브랜치(arm) 들이 있습니다. 어떤 'future'가 진행 가능 상태가 되면 '그 "
|
|
"`future`의 결과값이 `pattern`으로 바인딩 되며, 그 상태에서 \\`statement'가 수"
|
|
"행됩니다."
|
|
|
|
#: src/async/control-flow/select.md
|
|
msgid "\"Felix\""
|
|
msgstr "\"펠릭스\""
|
|
|
|
#: src/async/control-flow/select.md
|
|
msgid "\"Failed to send cat.\""
|
|
msgstr "\"고양이를 보내지 못했습니다.\""
|
|
|
|
#: src/async/control-flow/select.md
|
|
msgid "\"Failed to send dog.\""
|
|
msgstr "\"개를 보내지 못했습니다.\""
|
|
|
|
#: src/async/control-flow/select.md
|
|
msgid "\"Failed to receive winner\""
|
|
msgstr "\"우승자를 수신하지 못했습니다.\""
|
|
|
|
#: src/async/control-flow/select.md
|
|
msgid "\"Winner is {winner:?}\""
|
|
msgstr "\"우승자: {winner:?}\""
|
|
|
|
#: src/async/control-flow/select.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"In this example, we have a race between a cat and a dog. "
|
|
"`first_animal_to_finish_race` listens to both channels and will pick "
|
|
"whichever arrives first. Since the dog takes 50ms, it wins against the cat "
|
|
"that take 500ms."
|
|
msgstr ""
|
|
"이 예제에서는 고양이와 개를 경주시켰습니다(동시에 시작시킨 후, 둘 중 먼저 끝"
|
|
"나는 쪽이 이김). `first_animal_to_finish_race`함수는 두 채널 모두에 귀기울이"
|
|
"고(listen하고) 있다가, 메시지가 먼저 도착한 채널을 선택합니다. 개는 50ms만에 "
|
|
"작업을 끝내고 고양이는 500ms가 걸리기 때문에, 개가 이깁니다."
|
|
|
|
#: src/async/control-flow/select.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"You can use `oneshot` channels in this example as the channels are supposed "
|
|
"to receive only one `send`."
|
|
msgstr ""
|
|
"이 예제에서는 `oneshot` 채널을 사용하는 것이 더 좋은 디자인 입니다. 각 채널"
|
|
"이 한 번의 `send`만 수신해야 하는 것이 보장되기 때문입니다."
|
|
|
|
#: src/async/control-flow/select.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Try adding a deadline to the race, demonstrating selecting different sorts "
|
|
"of futures."
|
|
msgstr ""
|
|
"이 경주에 타임아웃을 추가해서, 서로 다른 종류의 futures들을 동시에 `select`"
|
|
"할 수 있음을 확인해 보세요."
|
|
|
|
#: src/async/control-flow/select.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Note that `select!` drops unmatched branches, which cancels their futures. "
|
|
"It is easiest to use when every execution of `select!` creates new futures."
|
|
msgstr ""
|
|
"`select!`는 매칭되지 않은 다른 모든 브랜치에 대해 drop을 수행합니다. 따라서 "
|
|
"경쟁에서 진 모든 future들은 취소(cancel) 됩니다. `select!`를 실행할 때마다 "
|
|
"새로운 futures가 만들어지는 경우라면, 이러한 점이 매우 편하게 느껴질 것입니"
|
|
"다. Future가 취소되는 것을 막기 위해 future를 직접 전달하는 대신 `&mut "
|
|
"future`를 전달하는 것도 가능합니다. 하지만 이렇게 하면 문제가 발생할 수 있습"
|
|
"니다 (왜 그런지는 `Pin`설명할 때 자세히 설명하겠습니다)."
|
|
|
|
#: src/async/control-flow/select.md
|
|
msgid ""
|
|
"An alternative is to pass `&mut future` instead of the future itself, but "
|
|
"this can lead to issues, further discussed in the pinning slide."
|
|
msgstr ""
|
|
"대안은 future 자체 대신 `&mut future`를 전달하는 것입니다. 하지만 이렇게 하"
|
|
"면 문제가 발생할 수 있습니다(Pinning을 다룰 때 자세히 설명할 예정임)."
|
|
|
|
#: src/async/pitfalls.md
|
|
msgid "Pitfalls of async/await"
|
|
msgstr "async/await에서 주의해야할 함정"
|
|
|
|
#: src/async/pitfalls.md
|
|
msgid ""
|
|
"Async / await provides convenient and efficient abstraction for concurrent "
|
|
"asynchronous programming. However, the async/await model in Rust also comes "
|
|
"with its share of pitfalls and footguns. We illustrate some of them in this "
|
|
"chapter:"
|
|
msgstr ""
|
|
"Async와 await는 동시 비동기 프로그래밍을 위한 편리하고 효율적인 추상화를 제공"
|
|
"합니다. 하지만 Rust의 async/await 모델에도 문제는 있습니다. 이 장에서 몇 가"
|
|
"지 예를 살펴보겠습니다."
|
|
|
|
#: src/async/pitfalls.md
|
|
msgid "[Blocking the Executor](pitfalls/blocking-executor.md)"
|
|
msgstr "[실행자 차단](pitfalls/blocking-executor.md)"
|
|
|
|
#: src/async/pitfalls.md
|
|
msgid "[Pin](pitfalls/pin.md)"
|
|
msgstr "[Pin](pitfalls/pin.md)"
|
|
|
|
#: src/async/pitfalls.md
|
|
msgid "[Async Traits](pitfalls/async-traits.md)"
|
|
msgstr "[비동기 트레잇](pitfall/async-traits.md)"
|
|
|
|
#: src/async/pitfalls.md
|
|
msgid "[Cancellation](pitfalls/cancellation.md)"
|
|
msgstr "[취소](pitfalls/cancellation.md)"
|
|
|
|
#: src/async/pitfalls/blocking-executor.md
|
|
msgid "Blocking the executor"
|
|
msgstr "실행자(executor)를 블록시킴"
|
|
|
|
#: src/async/pitfalls/blocking-executor.md
|
|
msgid ""
|
|
"Most async runtimes only allow IO tasks to run concurrently. This means that "
|
|
"CPU blocking tasks will block the executor and prevent other tasks from "
|
|
"being executed. An easy workaround is to use async equivalent methods where "
|
|
"possible."
|
|
msgstr ""
|
|
"대부분의 비동기 런타임은 IO 작업만 동시에 실행되도록 허용합니다. 즉, CPU를 블"
|
|
"럭하는 태스크가 있는 경우, 이는 실행자(executor)를 블럭하게 되며, 그 결과로 "
|
|
"다른 태스크가 실행되지 않습니다. 이 문제를 해결하는 간단한 방법은, 항상 async"
|
|
"를 지원하는 메서드를 사용하는 것입니다."
|
|
|
|
#: src/async/pitfalls/blocking-executor.md
|
|
msgid "\"future {id} slept for {duration_ms}ms, finished after {}ms\""
|
|
msgstr ""
|
|
"\"future {id}은(는) {duration_ms}밀리초 동안 절전 모드였고 {}밀리초 후에 완료"
|
|
"됨\""
|
|
|
|
#: src/async/pitfalls/blocking-executor.md
|
|
msgid "\"current_thread\""
|
|
msgstr "\"current_thread\""
|
|
|
|
#: src/async/pitfalls/blocking-executor.md
|
|
msgid ""
|
|
"Run the code and see that the sleeps happen consecutively rather than "
|
|
"concurrently."
|
|
msgstr ""
|
|
"코드를 실행하여 sleep들이 동시에 진행되지 않고 순차적으로으로 진행되는지 확인"
|
|
"하세요."
|
|
|
|
#: src/async/pitfalls/blocking-executor.md
|
|
msgid ""
|
|
"The `\"current_thread\"` flavor puts all tasks on a single thread. This "
|
|
"makes the effect more obvious, but the bug is still present in the multi-"
|
|
"threaded flavor."
|
|
msgstr ""
|
|
"`flavor`를 `\"current_thread\"` 로 설정하면 모든 태스크가 하나의 스레드에서 "
|
|
"수행됩니다. 이렇게 하면 문제 상황이 더 분명히 드러납니다. 그러나 이 버그는 멀"
|
|
"티스레드인 경우에도 여전히 존재합니다."
|
|
|
|
#: src/async/pitfalls/blocking-executor.md
|
|
msgid ""
|
|
"Switch the `std::thread::sleep` to `tokio::time::sleep` and await its result."
|
|
msgstr ""
|
|
"`std::thread::sleep`을 `tokio::time::sleep`으로 바꾸고 그 결과를 `await`해 보"
|
|
"세요."
|
|
|
|
#: src/async/pitfalls/blocking-executor.md
|
|
msgid ""
|
|
"Another fix would be to `tokio::task::spawn_blocking` which spawns an actual "
|
|
"thread and transforms its handle into a future without blocking the executor."
|
|
msgstr ""
|
|
"또 다른 해결 방법은 `tokio::task::spawn_blocking`입니다. 이는 실제 스레드를 "
|
|
"생성하고, 그 스레드에 대한 핸들을 future로 변환함으로써 실행자가 블록되는 것"
|
|
"을 막습니다."
|
|
|
|
#: src/async/pitfalls/blocking-executor.md
|
|
msgid ""
|
|
"You should not think of tasks as OS threads. They do not map 1 to 1 and most "
|
|
"executors will allow many tasks to run on a single OS thread. This is "
|
|
"particularly problematic when interacting with other libraries via FFI, "
|
|
"where that library might depend on thread-local storage or map to specific "
|
|
"OS threads (e.g., CUDA). Prefer `tokio::task::spawn_blocking` in such "
|
|
"situations."
|
|
msgstr ""
|
|
"태스크를 OS 스레드라고 생각하면 안 됩니다. 태스크와 OS스레드는 일대일 매핑 관"
|
|
"계에 있지 않습니다. 대부분의 실행자는 하나의 OS 스레드에서 최대한 많은 태스크"
|
|
"를 수행하도록 설계되어 있습니다. 이점은 FFI를 통해 다른 라이브러리와 상호작용"
|
|
"할 때 특히 문제가 됩니다. 예를 들어, 해당 라이브러리가 스레드 로컬 저장소를 "
|
|
"이용하거나 특정 OS 스레드에 매핑될 수 있습니다(예: CUDA). 이러한 상황에서는 "
|
|
"`tokio::task::spawn_blocking`을 사용하는 것이 좋습니다."
|
|
|
|
#: src/async/pitfalls/blocking-executor.md
|
|
msgid ""
|
|
"Use sync mutexes with care. Holding a mutex over an `.await` may cause "
|
|
"another task to block, and that task may be running on the same thread."
|
|
msgstr ""
|
|
"동기화 뮤텍스를 주의해서 사용하세요. `.await` 위에 뮤텍스를 적용하면 다른 작"
|
|
"업이 차단될 수 있으며 해당 작업은 동일한 스레드에서 실행 중일 수 있습니다."
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"Async blocks and functions return types implementing the `Future` trait. The "
|
|
"type returned is the result of a compiler transformation which turns local "
|
|
"variables into data stored inside the future."
|
|
msgstr ""
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"Some of those variables can hold pointers to other local variables. Because "
|
|
"of that, the future should never be moved to a different memory location, as "
|
|
"it would invalidate those pointers."
|
|
msgstr ""
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"To prevent moving the future type in memory, it can only be polled through a "
|
|
"pinned pointer. `Pin` is a wrapper around a reference that disallows all "
|
|
"operations that would move the instance it points to into a different memory "
|
|
"location."
|
|
msgstr ""
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"// A work item. In this case, just sleep for the given time and respond\n"
|
|
"// with a message on the `respond_on` channel.\n"
|
|
msgstr ""
|
|
"// 작업 항목. 이 경우 지정된 시간 동안 절전 모드이고\n"
|
|
"// `respond_on` 채널의 메시지로 응답합니다.\n"
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid "// A worker which listens for work on a queue and performs it.\n"
|
|
msgstr "// 큐에서 작업을 수신 대기하고 실행하는 worker입니다.\n"
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid "// Pretend to work.\n"
|
|
msgstr "// 작업하는 척합니다.\n"
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid "\"failed to send response\""
|
|
msgstr "\"응답을 보내지 못했습니다.\""
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid "// TODO: report number of iterations every 100ms\n"
|
|
msgstr "// TODO: 100밀리초마다 반복 횟수를 보고합니다.\n"
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid "// A requester which requests work and waits for it to complete.\n"
|
|
msgstr "// 작업을 요청하고 작업이 완료되기를 기다리는 요청자입니다.\n"
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid "\"failed to send on work queue\""
|
|
msgstr "\"작업 큐에서 전송하지 못했습니다.\""
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid "\"failed waiting for response\""
|
|
msgstr "\"응답 대기 실패\""
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid "\"work result for iteration {i}: {resp}\""
|
|
msgstr "\"반복 작업 결과 {i}: {resp}\""
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"You may recognize this as an example of the actor pattern. Actors typically "
|
|
"call `select!` in a loop."
|
|
msgstr ""
|
|
"위에서 소개한 것은 액터(actor) 패턴의 한 예라고 봐도 무방합니다. 액터는 일반"
|
|
"적으로 루프 안에서 `select!`를 호출합니다."
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"This serves as a summation of a few of the previous lessons, so take your "
|
|
"time with it."
|
|
msgstr "이전 강의 몇 개의 내용을 요약한 것이기 때문에 천천히 살펴보세요."
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"Naively add a `_ = sleep(Duration::from_millis(100)) => { println!(..) }` to "
|
|
"the `select!`. This will never execute. Why?"
|
|
msgstr ""
|
|
"`_ = sleep(Duration::from_millis(100)) => { println!(..) }`을 `select!`에 추"
|
|
"가해 보세요. 이 작업은 실행되지 않습니다. 왜 그럴까요?"
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"Instead, add a `timeout_fut` containing that future outside of the `loop`:"
|
|
msgstr ""
|
|
"대신, 해당 future가 포함된 `timeout_fut`를 `loop` 외부에 추가해 보세요."
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"This still doesn't work. Follow the compiler errors, adding `&mut` to the "
|
|
"`timeout_fut` in the `select!` to work around the move, then using `Box::"
|
|
"pin`:"
|
|
msgstr ""
|
|
"여전히 작동하지 않습니다. 컴파일러 오류를 따라 `select!`의 `timeout_fut`에 "
|
|
"`&mut`를 추가하여 Move 시멘틱 관련한 문제를 해결하고 `Box::pin`을 사용하세요."
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"This compiles, but once the timeout expires it is `Poll::Ready` on every "
|
|
"iteration (a fused future would help with this). Update to reset "
|
|
"`timeout_fut` every time it expires."
|
|
msgstr ""
|
|
"이는 컴파일은 되지만 타임 아웃이 되면 매번 반복할 때 마다 `Poll::Ready`가 됩"
|
|
"니다(융합된 future가 도움이 될 수 있음). 타임 아웃 될 때마다 `timeout_fut`를 "
|
|
"리셋하도록 수정하세요."
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"Box allocates on the heap. In some cases, `std::pin::pin!` (only recently "
|
|
"stabilized, with older code often using `tokio::pin!`) is also an option, "
|
|
"but that is difficult to use for a future that is reassigned."
|
|
msgstr ""
|
|
"Box는 힙에 할당합니다. 경우에 따라 `std::pin::pin!`(최근에야 안정화되었으며 "
|
|
"이전 코드는 `tokio::pin!`을 사용하는 경우가 많음)도 사용할 수 있지만 이는 재"
|
|
"할당된 future에 사용하기가 어렵습니다."
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"Another alternative is to not use `pin` at all but spawn another task that "
|
|
"will send to a `oneshot` channel every 100ms."
|
|
msgstr ""
|
|
"또 다른 방법은 `pin`을 아예 사용하지 않고 100ms마다 `oneshot` 채널에 전송할 "
|
|
"다른 작업을 생성하는 것입니다."
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"Data that contains pointers to itself is called self-referential. Normally, "
|
|
"the Rust borrow checker would prevent self-referential data from being "
|
|
"moved, as the references cannot outlive the data they point to. However, the "
|
|
"code transformation for async blocks and functions is not verified by the "
|
|
"borrow checker."
|
|
msgstr ""
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"`Pin` is a wrapper around a reference. An object cannot be moved from its "
|
|
"place using a pinned pointer. However, it can still be moved through an "
|
|
"unpinned pointer."
|
|
msgstr ""
|
|
|
|
#: src/async/pitfalls/pin.md
|
|
msgid ""
|
|
"The `poll` method of the `Future` trait uses `Pin<&mut Self>` instead of "
|
|
"`&mut Self` to refer to the instance. That's why it can only be called on a "
|
|
"pinned pointer."
|
|
msgstr ""
|
|
|
|
#: src/async/pitfalls/async-traits.md
|
|
msgid ""
|
|
"Async methods in traits are were stabilized only recently, in the 1.75 "
|
|
"release. This required support for using return-position `impl Trait` (RPIT) "
|
|
"in traits, as the desugaring for `async fn` includes `-> impl Future<Output "
|
|
"= ...>`."
|
|
msgstr ""
|
|
|
|
#: src/async/pitfalls/async-traits.md
|
|
msgid ""
|
|
"However, even with the native support today there are some pitfalls around "
|
|
"`async fn` and RPIT in traits:"
|
|
msgstr ""
|
|
|
|
#: src/async/pitfalls/async-traits.md
|
|
msgid ""
|
|
"Return-position impl Trait captures all in-scope lifetimes (so some patterns "
|
|
"of borrowing cannot be expressed)"
|
|
msgstr ""
|
|
|
|
#: src/async/pitfalls/async-traits.md
|
|
msgid ""
|
|
"Traits whose methods use return-position `impl trait` or `async` are not "
|
|
"`dyn` compatible."
|
|
msgstr ""
|
|
|
|
#: src/async/pitfalls/async-traits.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"If we do need `dyn` support, the crate [async_trait](https://docs.rs/async-"
|
|
"trait/latest/async_trait/) provides a workaround through a macro, with some "
|
|
"caveats:"
|
|
msgstr ""
|
|
"크레이트 [async_trait](https://docs.rs/async-trait/latest/async_trait/)은 매"
|
|
"크로를 통한 해결 방법을 제공합니다."
|
|
|
|
#: src/async/pitfalls/async-traits.md
|
|
msgid "\"running all sleepers..\""
|
|
msgstr "\"모든 수면자를 실행\""
|
|
|
|
#: src/async/pitfalls/async-traits.md
|
|
msgid "\"slept for {}ms\""
|
|
msgstr "\"{}밀리초 동안 절전 모드\""
|
|
|
|
#: src/async/pitfalls/async-traits.md
|
|
msgid ""
|
|
"`async_trait` is easy to use, but note that it's using heap allocations to "
|
|
"achieve this. This heap allocation has performance overhead."
|
|
msgstr ""
|
|
"`async_trait`은 사용하기 쉽지만 이를 위해 힙에 메모리를 할당한다는 점에 유의"
|
|
"하세요. 이 힙 할당에는 성능 오버헤드가 있습니다."
|
|
|
|
#: src/async/pitfalls/async-traits.md
|
|
msgid ""
|
|
"The challenges in language support for `async trait` are deep Rust and "
|
|
"probably not worth describing in-depth. Niko Matsakis did a good job of "
|
|
"explaining them in [this post](https://smallcultfollowing.com/babysteps/"
|
|
"blog/2019/10/26/async-fn-in-traits-are-hard/) if you are interested in "
|
|
"digging deeper."
|
|
msgstr ""
|
|
"`async trait` 를 언어 차원에서 지원하는 것과 관련된 문제는 매우 전문적인 토픽"
|
|
"이며 따라서 이 강의에서 다룰 내용은 아닙니다. [이 게시물](https://"
|
|
"smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-"
|
|
"hard/)에 이에 관한 니코 마사키스의 좋은 설명이 있으므로 관심이 있다면 참고하"
|
|
"세요."
|
|
|
|
#: src/async/pitfalls/async-traits.md
|
|
msgid ""
|
|
"Try creating a new sleeper struct that will sleep for a random amount of "
|
|
"time and adding it to the Vec."
|
|
msgstr ""
|
|
"임의의 시간 동안 sleep 하는 새로운 sleeper 구조체를 만들어 Vec에 추가해 보세"
|
|
"요."
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid ""
|
|
"Dropping a future implies it can never be polled again. This is called "
|
|
"_cancellation_ and it can occur at any `await` point. Care is needed to "
|
|
"ensure the system works correctly even when futures are cancelled. For "
|
|
"example, it shouldn't deadlock or lose data."
|
|
msgstr ""
|
|
"future가 누락되면 다시 폴링할 수 없다는 의미입니다. 이를 _취소_라고 하며, "
|
|
"`await` 지점에서 발생할 수 있습니다. future가 취소되더라도 시스템이 올바르게 "
|
|
"작동할 수 있도록 주의를 기울여야 합니다. 예를 들어 교착 상태가 되거나 데이터"
|
|
"가 손실되면 안 됩니다."
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
#, fuzzy
|
|
msgid "\"not UTF-8\""
|
|
msgstr "UTF-8"
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid "\"hi\\nthere\\n\""
|
|
msgstr "\"hi\\nthere\\n\""
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid "\"tick!\""
|
|
msgstr "\"틱!\""
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid ""
|
|
"The compiler doesn't help with cancellation-safety. You need to read API "
|
|
"documentation and consider what state your `async fn` holds."
|
|
msgstr ""
|
|
"컴파일러는 취소 안전에 도움이 되지 않습니다. API 문서를 읽고 `async fn`의 상"
|
|
"태를 고려해야 합니다."
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid ""
|
|
"Unlike `panic` and `?`, cancellation is part of normal control flow (vs "
|
|
"error-handling)."
|
|
msgstr ""
|
|
"`panic` 및 `?`와 달리 취소는 오류 처리가 아닌 일반적인 제어 흐름의 일부입니"
|
|
"다."
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid "The example loses parts of the string."
|
|
msgstr "이 예에서는 문자열의 일부가 손실됩니다."
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid ""
|
|
"Whenever the `tick()` branch finishes first, `next()` and its `buf` are "
|
|
"dropped."
|
|
msgstr "`tick()` 브랜치가 먼저 완료될 때마다 `next()` 및 `buf`가 삭제됩니다."
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid ""
|
|
"`LinesReader` can be made cancellation-safe by making `buf` part of the "
|
|
"struct:"
|
|
msgstr ""
|
|
"다음과 같이 `buf`를 구조체의 일부로 만들어 `LinesReader`가 취소되지 않도록 "
|
|
"할 수 있습니다."
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid "// prefix buf and bytes with self.\n"
|
|
msgstr "// buf 및 bytes 접두사를 self로 지정합니다.\n"
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid ""
|
|
"[`Interval::tick`](https://docs.rs/tokio/latest/tokio/time/struct.Interval."
|
|
"html#method.tick) is cancellation-safe because it keeps track of whether a "
|
|
"tick has been 'delivered'."
|
|
msgstr ""
|
|
"[`Interval::tick`](https://docs.rs/tokio/latest/tokio/time/struct.Interval."
|
|
"html#method.tick)은 틱이 'delivered' 됐는지 추적하므로 취소에 안전합니다."
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid ""
|
|
"[`AsyncReadExt::read`](https://docs.rs/tokio/latest/tokio/io/trait."
|
|
"AsyncReadExt.html#method.read) is cancellation-safe because it either "
|
|
"returns or doesn't read data."
|
|
msgstr ""
|
|
"[`AsyncReadExt::read`](https://docs.rs/tokio/latest/tokio/io/trait."
|
|
"AsyncReadExt.html#method.read)는 데이터를 반환하거나 읽지 않으므로 취소에 안"
|
|
"전합니다."
|
|
|
|
#: src/async/pitfalls/cancellation.md
|
|
msgid ""
|
|
"[`AsyncBufReadExt::read_line`](https://docs.rs/tokio/latest/tokio/io/trait."
|
|
"AsyncBufReadExt.html#method.read_line) is similar to the example and _isn't_ "
|
|
"cancellation-safe. See its documentation for details and alternatives."
|
|
msgstr ""
|
|
"[`AsyncBufReadExt::read_line`](https://docs.rs/tokio/latest/tokio/io/trait."
|
|
"AsyncBufReadExt.html#method.read_line)은 예와 유사하며 취소에 안전하지 _않습"
|
|
"니다_. 자세한 내용과 대안은 관련 문서를 참고하세요."
|
|
|
|
#: src/exercises/concurrency/afternoon.md
|
|
msgid ""
|
|
"To practice your Async Rust skills, we have again two exercises for you:"
|
|
msgstr "Async Rust 기술을 연습할 수 있도록 두 가지 연습문제를 준비했습니다."
|
|
|
|
#: src/exercises/concurrency/afternoon.md
|
|
msgid ""
|
|
"Dining philosophers: we already saw this problem in the morning. This time "
|
|
"you are going to implement it with Async Rust."
|
|
msgstr ""
|
|
"식사하는 철학자: 이 문제는 이미 오전에 확인했습니다. 이번에는 Async Rust로 구"
|
|
"현합니다."
|
|
|
|
#: src/exercises/concurrency/afternoon.md
|
|
msgid ""
|
|
"A Broadcast Chat Application: this is a larger project that allows you "
|
|
"experiment with more advanced Async Rust features."
|
|
msgstr ""
|
|
"브로드캐스트 채팅 애플리케이션: 더 많은 고급 Async Rust 기능을 실험할 수 있"
|
|
"는 대규모 프로젝트입니다."
|
|
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
#, fuzzy
|
|
msgid "Dining Philosophers --- Async"
|
|
msgstr "식사하는 철학자들"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
msgid ""
|
|
"See [dining philosophers](dining-philosophers.md) for a description of the "
|
|
"problem."
|
|
msgstr ""
|
|
"문제에 관한 설명은 [식사하는 철학자](dining-philosophers.md)를 참고하세요."
|
|
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"As before, you will need a local [Cargo installation](../../cargo/running-"
|
|
"locally.md) for this exercise. Copy the code below to a file called `src/"
|
|
"main.rs`, fill out the blanks, and test that `cargo run` does not deadlock:"
|
|
msgstr ""
|
|
"이번 훈련에서는 [카고 설치하기](../../cargo/running-locally.md)가 필요합니"
|
|
"다. 아래 코드를 복사해서 `src/main.rs`에 붙여놓고 빈 부분을 채우고, `cargo "
|
|
"run` 커맨드로 테스트 해서 교착상태(데드락)가 발생하지 않는지 확인합니다:"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "// Keep trying until we have both forks\n"
|
|
msgstr ""
|
|
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "// Make them think and eat\n"
|
|
msgstr "// 생각하고 먹게 합니다.\n"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
msgid ""
|
|
"Since this time you are using Async Rust, you'll need a `tokio` dependency. "
|
|
"You can use the following `Cargo.toml`:"
|
|
msgstr ""
|
|
"이번에는 Async Rust를 사용하므로 `tokio` 종속 항목이 필요합니다. 다음 `Cargo."
|
|
"toml`을 사용할 수 있습니다."
|
|
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"```toml\n"
|
|
"[package]\n"
|
|
"name = \"dining-philosophers-async-dine\"\n"
|
|
"version = \"0.1.0\"\n"
|
|
"edition = \"2021\"\n"
|
|
"\n"
|
|
"[dependencies]\n"
|
|
"tokio = { version = \"1.26.0\", features = [\"sync\", \"time\", \"macros\", "
|
|
"\"rt-multi-thread\"] }\n"
|
|
"```"
|
|
msgstr ""
|
|
"```toml\n"
|
|
"[package]\n"
|
|
"name = \"dining-philosophers-async-dine\"\n"
|
|
"version = \"0.1.0\"\n"
|
|
"edition = \"2021\"\n"
|
|
"\n"
|
|
"[dependencies]\n"
|
|
"tokio = {version = \"1.26.0\", features = [\"sync\", \"time\", \"macros\", "
|
|
"\"rt-multi-thread\"]}\n"
|
|
"```"
|
|
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
msgid ""
|
|
"Also note that this time you have to use the `Mutex` and the `mpsc` module "
|
|
"from the `tokio` crate."
|
|
msgstr ""
|
|
"또한 이번에는 `tokio` 크레이트의 `Mutex`와 `mpsc` 모듈을 사용해야 합니다."
|
|
|
|
#: src/exercises/concurrency/dining-philosophers-async.md
|
|
#, fuzzy
|
|
msgid "Can you make your implementation single-threaded?"
|
|
msgstr "구현을 단일 스레드로 만들 수 있나요? "
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
msgid ""
|
|
"In this exercise, we want to use our new knowledge to implement a broadcast "
|
|
"chat application. We have a chat server that the clients connect to and "
|
|
"publish their messages. The client reads user messages from the standard "
|
|
"input, and sends them to the server. The chat server broadcasts each message "
|
|
"that it receives to all the clients."
|
|
msgstr ""
|
|
"이 연습에서는 새로운 지식을 사용하여 브로드캐스트 채팅 애플리케이션을 구현해 "
|
|
"보겠습니다. 클라이언트가 연결하고 메시지를 게시하는 채팅 서버가 있습니다. 클"
|
|
"라이언트는 표준 입력에서 사용자 메시지를 읽고 서버로 전송합니다. 채팅 서버는 "
|
|
"수신하는 각 메시지를 모든 클라이언트에 브로드캐스트합니다."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"For this, we use [a broadcast channel](https://docs.rs/tokio/latest/tokio/"
|
|
"sync/broadcast/fn.channel.html) on the server, and [`tokio_websockets`]"
|
|
"(https://docs.rs/tokio-websockets/) for the communication between the client "
|
|
"and the server."
|
|
msgstr ""
|
|
"이를 위해 서버에서 [브로드캐스트 채널](https://docs.rs/tokio/latest/tokio/"
|
|
"sync/broadcast/fn.channel.html)을 사용하고 클라이언트와 서버 간의 통신을 위"
|
|
"해 [`tokio_websockets`](https://docs.rs/tokio-websockets/0.4.0/"
|
|
"tokio_websockets/)를 사용합니다."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
msgid "Create a new Cargo project and add the following dependencies:"
|
|
msgstr "새 Cargo 프로젝트를 만들고 다음 종속 항목을 추가합니다."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#, fuzzy
|
|
msgid "_Cargo.toml_:"
|
|
msgstr "_Cargo.toml_:"
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"```toml\n"
|
|
"[package]\n"
|
|
"name = \"chat-async\"\n"
|
|
"version = \"0.1.0\"\n"
|
|
"edition = \"2021\"\n"
|
|
"\n"
|
|
"[dependencies]\n"
|
|
"futures-util = { version = \"0.3.30\", features = [\"sink\"] }\n"
|
|
"http = \"1.1.0\"\n"
|
|
"tokio = { version = \"1.36.0\", features = [\"full\"] }\n"
|
|
"tokio-websockets = { version = \"0.7.0\", features = [\"client\", "
|
|
"\"fastrand\", \"server\", \"sha1_smol\"] }\n"
|
|
"```"
|
|
msgstr ""
|
|
"```toml\n"
|
|
"[package]\n"
|
|
"name = \"chat-async\"\n"
|
|
"version = \"0.1.0\"\n"
|
|
"edition = \"2021\"\n"
|
|
"\n"
|
|
"[dependencies]\n"
|
|
"futures-util = { version = \"0.3.28\", features = [\"sink\"] }\n"
|
|
"http = \"0.2.9\"\n"
|
|
"tokio = { version = \"1.28.1\", features = [\"full\"] }\n"
|
|
"tokio-websockets = { version = \"0.4.0\", features = [\"client\", "
|
|
"\"fastrand\", \"server\", \"sha1_smol\"] }\n"
|
|
"```"
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
msgid "The required APIs"
|
|
msgstr "필수 API"
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"You are going to need the following functions from `tokio` and "
|
|
"[`tokio_websockets`](https://docs.rs/tokio-websockets/). Spend a few minutes "
|
|
"to familiarize yourself with the API."
|
|
msgstr ""
|
|
"`tokio` 및 [`tokio_websockets`](https://docs.rs/tokio-websockets/0.4.0/"
|
|
"tokio_websockets/)의 다음 함수가 필요합니다. 잠시 시간을 내어 API를 숙지합니"
|
|
"다. "
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[StreamExt::next()](https://docs.rs/futures-util/0.3.28/futures_util/stream/"
|
|
"trait.StreamExt.html#method.next) implemented by `WebSocketStream`: for "
|
|
"asynchronously reading messages from a Websocket Stream."
|
|
msgstr ""
|
|
"`WebsocketStream`에 의해 구현되는 [StreamExt::next()](https://docs.rs/"
|
|
"futures-util/0.3.28/futures_util/stream/trait.StreamExt.html#method.next)는 "
|
|
"Websocket 스트림에서 비동기식으로 메시지를 읽는 데 사용됩니다."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"[SinkExt::send()](https://docs.rs/futures-util/0.3.28/futures_util/sink/"
|
|
"trait.SinkExt.html#method.send) implemented by `WebSocketStream`: for "
|
|
"asynchronously sending messages on a Websocket Stream."
|
|
msgstr ""
|
|
"`WebsocketStream`에 의해 구현되는 [SinkExt::send()](https://docs.rs/futures-"
|
|
"util/0.3.28/futures_util/sink/trait.SinkExt.html#method.send)는 Websocket 스"
|
|
"트림에서 비동기식으로 메시지를 보내는 데 사용됩니다."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
msgid ""
|
|
"[Lines::next_line()](https://docs.rs/tokio/latest/tokio/io/struct.Lines."
|
|
"html#method.next_line): for asynchronously reading user messages from the "
|
|
"standard input."
|
|
msgstr ""
|
|
"[Lines::next_line()](https://docs.rs/tokio/latest/tokio/io/struct.Lines."
|
|
"html#method.next_line)은 표준 입력에서 사용자 메시지를 비동기식으로 읽는 데 "
|
|
"사용됩니다."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
msgid ""
|
|
"[Sender::subscribe()](https://docs.rs/tokio/latest/tokio/sync/broadcast/"
|
|
"struct.Sender.html#method.subscribe): for subscribing to a broadcast channel."
|
|
msgstr ""
|
|
"[Sender::subscribe()](https://docs.rs/tokio/latest/tokio/sync/broadcast/"
|
|
"struct.Sender.html#method.subscribe)는 브로드캐스트 채널 구독에 사용됩니다."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#, fuzzy
|
|
msgid "Two binaries"
|
|
msgstr "러스트 바이너리"
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Normally in a Cargo project, you can have only one binary, and one `src/main."
|
|
"rs` file. In this project, we need two binaries. One for the client, and one "
|
|
"for the server. You could potentially make them two separate Cargo projects, "
|
|
"but we are going to put them in a single Cargo project with two binaries. "
|
|
"For this to work, the client and the server code should go under `src/bin` "
|
|
"(see the [documentation](https://doc.rust-lang.org/cargo/reference/cargo-"
|
|
"targets.html#binaries))."
|
|
msgstr ""
|
|
"일반적으로 Cargo 프로젝트에서는 바이너리 하나와 `src/main.rs` 파일을 하나만 "
|
|
"보유할 수 있습니다. 이 프로젝트에는 두 개의 바이너리가 필요합니다. 하나는 클"
|
|
"라이언트용, 하나는 서버용입니다. 잠재적으로 이를 두 개의 개별 Cargo 프로젝트"
|
|
"로 만들 수 있지만 여기서는 바이너리 2개를 사용하는 단일 Cargo 프로젝트에 넣습"
|
|
"니다. 이렇게 하려면 클라이언트와 서버 코드가 `src/bin`에 있어야 합니다([문서]"
|
|
"(https://doc.rust-lang.org/cargo/reference/cargo-targets.html#binaries) 참"
|
|
"고). "
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Copy the following server and client code into `src/bin/server.rs` and `src/"
|
|
"bin/client.rs`, respectively. Your task is to complete these files as "
|
|
"described below."
|
|
msgstr ""
|
|
"다음 서버 및 클라이언트 코드를 각각 `src/bin/server.rs`와 `src/bin/client.rs`"
|
|
"에 복사합니다. 아래에 설명된 대로 이러한 파일을 완료해야 합니다. "
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
#, fuzzy
|
|
msgid "_src/bin/server.rs_:"
|
|
msgstr "_birthday_service/src/server.rs_:"
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
msgid "// TODO: For a hint, see the description of the task below.\n"
|
|
msgstr "// TODO: 힌트는 아래의 작업 설명을 참고하세요.\n"
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"127.0.0.1:2000\""
|
|
msgstr "\"127.0.0.1:2000\""
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"listening on port 2000\""
|
|
msgstr "\"포트 2000에서 수신 대기\""
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"New connection from {addr:?}\""
|
|
msgstr "\"{addr:?}의 새 연결\""
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "// Wrap the raw TCP stream into a websocket.\n"
|
|
msgstr "// 원시 TCP 스트림을 websocket에 래핑합니다.\n"
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
#, fuzzy
|
|
msgid "_src/bin/client.rs_:"
|
|
msgstr "_birthday_service/src/client.rs_:"
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"ws://127.0.0.1:2000\""
|
|
msgstr "\"ws://127.0.0.1:2000\""
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#, fuzzy
|
|
msgid "Running the binaries"
|
|
msgstr "강의 진행 방식"
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#, fuzzy
|
|
msgid "Run the server with:"
|
|
msgstr "아래 명령어로 예제 코드를 실행하세요."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
#, fuzzy
|
|
msgid "and the client with:"
|
|
msgstr "아래 명령어로 예제 코드를 실행하세요."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
msgid "Implement the `handle_connection` function in `src/bin/server.rs`."
|
|
msgstr "`src/bin/server.rs`에서 `handle_connection` 함수를 구현합니다."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
msgid ""
|
|
"Hint: Use `tokio::select!` for concurrently performing two tasks in a "
|
|
"continuous loop. One task receives messages from the client and broadcasts "
|
|
"them. The other sends messages received by the server to the client."
|
|
msgstr ""
|
|
"힌트: 연속 루프에서 두 작업을 동시에 실행하는 경우 `tokio::select!`를 사용하"
|
|
"세요. 한 작업은 클라이언트에서 메시지를 수신하여 브로드캐스트합니다. 다른 하"
|
|
"나는 서버가 수신한 메시지를 클라이언트로 보냅니다."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
msgid "Complete the main function in `src/bin/client.rs`."
|
|
msgstr "`src/bin/client.rs`에서 main 함수를 완료합니다."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
msgid ""
|
|
"Hint: As before, use `tokio::select!` in a continuous loop for concurrently "
|
|
"performing two tasks: (1) reading user messages from standard input and "
|
|
"sending them to the server, and (2) receiving messages from the server, and "
|
|
"displaying them for the user."
|
|
msgstr ""
|
|
"힌트: 이전과 마찬가지로 연속 루프에서 두 작업을 동시에 실행하는 경우 `tokio::"
|
|
"select!`를 사용하세요. (1) 표준 입력에서 사용자 메시지를 읽고 서버로 보냅니"
|
|
"다. (2) 서버에서 메시지를 수신하고 사용자에게 표시합니다."
|
|
|
|
#: src/exercises/concurrency/chat-app.md
|
|
msgid ""
|
|
"Optional: Once you are done, change the code to broadcast messages to all "
|
|
"clients, but the sender of the message."
|
|
msgstr ""
|
|
"선택사항: 작업을 완료하면 메시지 발신자를 제외한 모든 클라이언트에게 메시지"
|
|
"를 브로드캐스트하도록 코드를 변경합니다."
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
#, fuzzy
|
|
msgid "Concurrency Afternoon Exercise"
|
|
msgstr "1일차 오후 연습문제"
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "([back to exercise](dining-philosophers-async.md))"
|
|
msgstr "([연습문제로 돌아가기](dining-philosophers-async.md)"
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid ""
|
|
"// If we didn't get the left fork, drop the right fork if we\n"
|
|
" // have it and let other tasks make progress.\n"
|
|
msgstr ""
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid ""
|
|
"// If we didn't get the right fork, drop the left fork and let\n"
|
|
" // other tasks make progress.\n"
|
|
msgstr ""
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "// The locks are dropped here\n"
|
|
msgstr "// 여기에 잠금이 해제됩니다.\n"
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "// tx is dropped here, so we don't need to explicitly drop it later\n"
|
|
msgstr ""
|
|
"// tx가 여기에서 삭제되므로 나중에 명시적으로 삭제할 필요가 없습니다.\n"
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"Here is a thought: {thought}\""
|
|
msgstr "\"의견 보내기: {thought}\""
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "([back to exercise](chat-app.md))"
|
|
msgstr "([연습문제로 돌아가기](chat-app.md))"
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"Welcome to chat! Type a message\""
|
|
msgstr "\"채팅에 오신 것을 환영합니다. 메시지를 입력하세요.\""
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid ""
|
|
"// A continuous loop for concurrently performing two tasks: (1) receiving\n"
|
|
" // messages from `ws_stream` and broadcasting them, and (2) receiving\n"
|
|
" // messages on `bcast_rx` and sending them to the client.\n"
|
|
msgstr ""
|
|
"// 동시에 두 작업을 실행하는 연속 루프: (1) `ws_stream`에서 메시지를 수신하"
|
|
"여\n"
|
|
" // 브로드캐스팅하고 (2) `bcast_rx`에서 메시지를 수신하여\n"
|
|
" // 클라이언트로 전송합니다.\n"
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"From client {addr:?} {text:?}\""
|
|
msgstr "\"클라이언트에서: {addr:?} {text:?}\""
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "// Continuous loop for concurrently sending and receiving messages.\n"
|
|
msgstr "// 동시에 메시지를 보내고 받는 연속 루프\n"
|
|
|
|
#: src/exercises/concurrency/solutions-afternoon.md
|
|
msgid "\"From server: {}\""
|
|
msgstr "\"서버에서: {}\""
|
|
|
|
#: src/thanks.md
|
|
msgid ""
|
|
"_Thank you for taking Comprehensive Rust 🦀!_ We hope you enjoyed it and "
|
|
"that it was useful."
|
|
msgstr ""
|
|
"Comprehensive Rust 🦀를 이용해 주셔서 감사합니다. 즐겁고 유익한 시간이었기를 "
|
|
"바랍니다."
|
|
|
|
#: src/thanks.md
|
|
msgid ""
|
|
"We've had a lot of fun putting the course together. The course is not "
|
|
"perfect, so if you spotted any mistakes or have ideas for improvements, "
|
|
"please get in [contact with us on GitHub](https://github.com/google/"
|
|
"comprehensive-rust/discussions). We would love to hear from you."
|
|
msgstr ""
|
|
"강의가 완벽하진 않으니 실수나 개선점이 있다면 언제든지 [깃허브](https://"
|
|
"github.com/google/comprehensive-rust/discussions)로 연락주세요."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"The following is a glossary which aims to give a short definition of many "
|
|
"Rust terms. For translations, this also serves to connect the term back to "
|
|
"the English original."
|
|
msgstr ""
|
|
"다음은 여러 Rust 용어의 간단한 정의를 제공하는 용어집입니다. 번역의 경우 용어"
|
|
"를 다시 영어 원본에 연결하는 역할도 합니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"allocate: \n"
|
|
"Dynamic memory allocation on [the heap](memory-management/stack-vs-heap.md)."
|
|
msgstr ""
|
|
"할당: \n"
|
|
"[힙](memory-management/stack-vs-heap.md)에 대한 동적 메모리 할당입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"argument: \n"
|
|
"Information that is passed into a function or method."
|
|
msgstr ""
|
|
"인수: \n"
|
|
"함수나 메서드에 전달되는 정보입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"Bare-metal Rust: \n"
|
|
"Low-level Rust development, often deployed to a system without an operating "
|
|
"system. See [Bare-metal Rust](bare-metal.md)."
|
|
msgstr ""
|
|
"Bare-metal Rust: \n"
|
|
"낮은 수준의 Rust 개발로, 운영체제가 없는 시스템에 배포되는 경우가 많습니다. "
|
|
"[Bare-metal Rust](bare-metal.md)를 참고하세요."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"block: \n"
|
|
"See [Blocks](control-flow/blocks.md) and _scope_."
|
|
msgstr ""
|
|
"블록: \n"
|
|
"[블록](control-flow/blocks.md) 및 _범위_를 참고하세요."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"borrow: \n"
|
|
"See [Borrowing](ownership/borrowing.md)."
|
|
msgstr ""
|
|
"빌림: \n"
|
|
"[빌림](ownership/borrowing.md)을 참고하세요."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"borrow checker: \n"
|
|
"The part of the Rust compiler which checks that all borrows are valid."
|
|
msgstr ""
|
|
"빌림 검사기: \n"
|
|
"모든 빌림이 유효한지 확인하는 Rust 컴파일러의 부분입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"brace: \n"
|
|
"`{` and `}`. Also called _curly brace_, they delimit _blocks_."
|
|
msgstr ""
|
|
"괄호: \n"
|
|
"`{` and `}`. _중괄호_라고도 하며 _블록_을 구분합니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"build: \n"
|
|
"The process of converting source code into executable code or a usable "
|
|
"program."
|
|
msgstr ""
|
|
"빌드: \n"
|
|
"소스 코드를 실행 가능한 코드 또는 사용 가능한 프로그램으로 변환하는 프로세스"
|
|
"입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"call: \n"
|
|
"To invoke or execute a function or method."
|
|
msgstr ""
|
|
"호출: \n"
|
|
"함수 또는 메서드를 호출하거나 실행합니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"channel: \n"
|
|
"Used to safely pass messages [between threads](concurrency/channels.md)."
|
|
msgstr ""
|
|
"채널: \n"
|
|
"[스레드 간](concurrency/channels.md)에 메시지를 안전하게 전달하는 데 사용됩니"
|
|
"다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"Comprehensive Rust 🦀: \n"
|
|
"The courses here are jointly called Comprehensive Rust 🦀."
|
|
msgstr ""
|
|
"Comprehensive Rust 🦀: \n"
|
|
"이 과정은 Comprehensive Rust 🦀로 통칭됩니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"concurrency: \n"
|
|
"The execution of multiple tasks or processes at the same time."
|
|
msgstr ""
|
|
"동시 실행: \n"
|
|
"여러 작업 또는 프로세스를 동시에 실행합니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"Concurrency in Rust: \n"
|
|
"See [Concurrency in Rust](concurrency.md)."
|
|
msgstr ""
|
|
"Rust의 동시 실행: \n"
|
|
"[Rust의 동시 실행](concurrency.md)을 참고하세요."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"constant: \n"
|
|
"A value that does not change during the execution of a program."
|
|
msgstr ""
|
|
"상수: \n"
|
|
"프로그램 실행 중에 변경되지 않는 값입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"control flow: \n"
|
|
"The order in which the individual statements or instructions are executed in "
|
|
"a program."
|
|
msgstr ""
|
|
"제어 흐름: \n"
|
|
"프로그램에서 개별 문 또는 명령이 실행되는 순서입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"crash: \n"
|
|
"An unexpected and unhandled failure or termination of a program."
|
|
msgstr ""
|
|
"비정상 종료: \n"
|
|
"프로그램의 예기치 않거나 처리되지 않은 오류 또는 종료입니다."
|
|
|
|
#: src/glossary.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"enumeration: \n"
|
|
"A data type that holds one of several named constants, possibly with an "
|
|
"associated tuple or struct."
|
|
msgstr ""
|
|
"열거형: \n"
|
|
"이름이 지정된 상수 값으로 구성된 데이터 타입입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"error: \n"
|
|
"An unexpected condition or result that deviates from the expected behavior."
|
|
msgstr ""
|
|
"오류: \n"
|
|
"예상 동작을 벗어나는 예기치 못한 상태나 결과입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"error handling: \n"
|
|
"The process of managing and responding to errors that occur during program "
|
|
"execution."
|
|
msgstr ""
|
|
"오류 처리: \n"
|
|
"프로그램 실행 중에 발생하는 오류를 관리하고 이에 대응하는 프로세스입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"exercise: \n"
|
|
"A task or problem designed to practice and test programming skills."
|
|
msgstr ""
|
|
"연습: \n"
|
|
"프로그래밍 기술을 연습하고 테스트하기 위한 과제 또는 문제입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"function: \n"
|
|
"A reusable block of code that performs a specific task."
|
|
msgstr ""
|
|
"함수: \n"
|
|
"특정 작업을 실행하는 재사용 가능한 코드 블록입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"garbage collector: \n"
|
|
"A mechanism that automatically frees up memory occupied by objects that are "
|
|
"no longer in use."
|
|
msgstr ""
|
|
"가비지 컬렉터: \n"
|
|
"더 이상 사용되지 않는 객체가 차지하는 메모리를 자동으로 해제하는 메커니즘입니"
|
|
"다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"generics: \n"
|
|
"A feature that allows writing code with placeholders for types, enabling "
|
|
"code reuse with different data types."
|
|
msgstr ""
|
|
"제네릭: \n"
|
|
"타입에 관한 자리표시자를 사용하여 코드를 작성할 수 있는 기능으로, 다양한 데이"
|
|
"터 타입으로 코드를 재사용할 수 있습니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"immutable: \n"
|
|
"Unable to be changed after creation."
|
|
msgstr ""
|
|
"변경 불가능: \n"
|
|
"생성 후에는 변경할 수 없습니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"integration test: \n"
|
|
"A type of test that verifies the interactions between different parts or "
|
|
"components of a system."
|
|
msgstr ""
|
|
"통합 테스트: \n"
|
|
"시스템의 여러 부분 또는 구성요소 간의 상호작용을 확인하는 테스트 타입입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"keyword: \n"
|
|
"A reserved word in a programming language that has a specific meaning and "
|
|
"cannot be used as an identifier."
|
|
msgstr ""
|
|
"키워드: \n"
|
|
"프로그래밍 언어에서 특정 의미를 가지며 식별자로 사용될 수 없는 예약어입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"library: \n"
|
|
"A collection of precompiled routines or code that can be used by programs."
|
|
msgstr ""
|
|
"라이브러리: \n"
|
|
"프로그램에서 사용할 수 있는 사전 컴파일된 루틴 또는 코드 모음입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"macro: \n"
|
|
"Rust macros can be recognized by a `!` in the name. Macros are used when "
|
|
"normal functions are not enough. A typical example is `format!`, which takes "
|
|
"a variable number of arguments, which isn't supported by Rust functions."
|
|
msgstr ""
|
|
"매크로: \n"
|
|
"Rust 매크로는 이름의 `!`로 인식될 수 있습니다. 매크로는 일반 함수가 충분하지 "
|
|
"않을 때 사용됩니다. 일반적인 예로는 가변적인 인수 수를 사용하는 `format!`이 "
|
|
"있는데, 이는 Rust 함수에서 지원되지 않습니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"`main` function: \n"
|
|
"Rust programs start executing with the `main` function."
|
|
msgstr ""
|
|
"`main` 함수: \n"
|
|
"Rust 프로그램은 `main` 함수로 실행을 시작합니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"match: \n"
|
|
"A control flow construct in Rust that allows for pattern matching on the "
|
|
"value of an expression."
|
|
msgstr ""
|
|
"일치: \n"
|
|
"표현식 값에 대한 패턴 일치를 허용하는 Rust의 제어 흐름 구성입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"memory leak: \n"
|
|
"A situation where a program fails to release memory that is no longer "
|
|
"needed, leading to a gradual increase in memory usage."
|
|
msgstr ""
|
|
"메모리 누수: \n"
|
|
"프로그램이 더 이상 필요하지 않은 메모리를 해제하지 못해 메모리 사용량이 점차 "
|
|
"늘어나는 상황입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"method: \n"
|
|
"A function associated with an object or a type in Rust."
|
|
msgstr ""
|
|
"메서드: \n"
|
|
"Rust의 객체나 타입과 관련된 함수입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"module: \n"
|
|
"A namespace that contains definitions, such as functions, types, or traits, "
|
|
"to organize code in Rust."
|
|
msgstr ""
|
|
"모듈: \n"
|
|
"Rust에서 코드를 구성하기 위해 함수, 타입 또는 트레잇과 같은 정의가 포함된 네"
|
|
"임스페이스입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"move: \n"
|
|
"The transfer of ownership of a value from one variable to another in Rust."
|
|
msgstr ""
|
|
"이동: \n"
|
|
"Rust에서 한 변수에서 다른 변수로 값의 소유권을 이전하는 것입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"mutable: \n"
|
|
"A property in Rust that allows variables to be modified after they have been "
|
|
"declared."
|
|
msgstr ""
|
|
"mutable: \n"
|
|
"선언된 후 변수를 수정할 수 있는 Rust의 속성입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"ownership: \n"
|
|
"The concept in Rust that defines which part of the code is responsible for "
|
|
"managing the memory associated with a value."
|
|
msgstr ""
|
|
"소유권: \n"
|
|
"값과 관련된 메모리를 관리하는 코드의 부분을 정의하는 Rust의 개념입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"panic: \n"
|
|
"An unrecoverable error condition in Rust that results in the termination of "
|
|
"the program."
|
|
msgstr ""
|
|
"패닉: \n"
|
|
"Rust에서 복구할 수 없는 오류 상태로, 프로그램이 종료됩니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"parameter: \n"
|
|
"A value that is passed into a function or method when it is called."
|
|
msgstr ""
|
|
"매개변수: \n"
|
|
"호출 시 함수나 메서드로 전달되는 값입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"pattern: \n"
|
|
"A combination of values, literals, or structures that can be matched against "
|
|
"an expression in Rust."
|
|
msgstr ""
|
|
"패턴: \n"
|
|
"Rust의 표현식과 일치시킬 수 있는 값, 리터럴 또는 구조의 조합입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"payload: \n"
|
|
"The data or information carried by a message, event, or data structure."
|
|
msgstr ""
|
|
"페이로드: \n"
|
|
"메시지, 이벤트 또는 데이터 구조에 의해 전달되는 데이터 또는 정보입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"program: \n"
|
|
"A set of instructions that a computer can execute to perform a specific task "
|
|
"or solve a particular problem."
|
|
msgstr ""
|
|
"프로그램: \n"
|
|
"컴퓨터가 특정 작업을 수행하거나 특정 문제를 해결하기 위해 실행할 수 있는 일련"
|
|
"의 명령입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"programming language: \n"
|
|
"A formal system used to communicate instructions to a computer, such as Rust."
|
|
msgstr ""
|
|
"프로그래밍 언어: \n"
|
|
"컴퓨터에 명령을 전달하는 데 사용되는 공식 시스템입니다(예: Rust)."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"receiver: \n"
|
|
"The first parameter in a Rust method that represents the instance on which "
|
|
"the method is called."
|
|
msgstr ""
|
|
"수신자: \n"
|
|
"메서드가 호출되는 인스턴스를 나타내는 Rust 메서드의 첫 번째 매개변수입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"reference counting: \n"
|
|
"A memory management technique in which the number of references to an object "
|
|
"is tracked, and the object is deallocated when the count reaches zero."
|
|
msgstr ""
|
|
"참조 계산: \n"
|
|
"객체에 대한 참조 수를 추적하고 개수가 0에 도달하면 객체의 할당을 해제하는 메"
|
|
"모리 관리 기법입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"return: \n"
|
|
"A keyword in Rust used to indicate the value to be returned from a function."
|
|
msgstr ""
|
|
"return: \n"
|
|
"함수에서 반환될 값을 나타내는 데 사용되는 Rust의 키워드입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"Rust: \n"
|
|
"A systems programming language that focuses on safety, performance, and "
|
|
"concurrency."
|
|
msgstr ""
|
|
"Rust: \n"
|
|
"안전, 성능, 동시 실행에 중점을 둔 시스템 프로그래밍 언어입니다."
|
|
|
|
#: src/glossary.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"Rust Fundamentals: \n"
|
|
"Days 1 to 4 of this course."
|
|
msgstr ""
|
|
"Rust 기초: \n"
|
|
"1~3일 차 과정입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"Rust in Android: \n"
|
|
"See [Rust in Android](android.md)."
|
|
msgstr ""
|
|
"Android의 Rust: \n"
|
|
"[Android의 Rust](android.md)를 참고하세요."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"Rust in Chromium: \n"
|
|
"See [Rust in Chromium](chromium.md)."
|
|
msgstr ""
|
|
"Chromium의 Rust: \n"
|
|
"[Chromium의 Rust](chromium.md)를 참고하세요."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"safe: \n"
|
|
"Refers to code that adheres to Rust's ownership and borrowing rules, "
|
|
"preventing memory-related errors."
|
|
msgstr ""
|
|
"안전: \n"
|
|
"Rust의 소유권 및 빌림 규칙을 준수하여 메모리 관련 오류를 방지하는 코드를 나타"
|
|
"냅니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"scope: \n"
|
|
"The region of a program where a variable is valid and can be used."
|
|
msgstr ""
|
|
"범위: \n"
|
|
"변수가 유효하여 사용할 수 있는 프로그램의 영역입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"standard library: \n"
|
|
"A collection of modules providing essential functionality in Rust."
|
|
msgstr ""
|
|
"표준 라이브러리: \n"
|
|
"Rust에서 필수 기능을 제공하는 모듈 모음입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"static: \n"
|
|
"A keyword in Rust used to define static variables or items with a `'static` "
|
|
"lifetime."
|
|
msgstr ""
|
|
"static: \n"
|
|
"Rust에서 `'static` 전체 기간으로 정적 변수 또는 항목을 정의하는 데 사용되는 "
|
|
"키워드입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"string: \n"
|
|
"A data type storing textual data. See [`String` vs `str`](basic-syntax/"
|
|
"string-slices.html) for more."
|
|
msgstr ""
|
|
"문자열: \n"
|
|
"텍스트 데이터를 저장하는 데이터 타입입니다. 자세한 내용은 [`String` 및 `str`]"
|
|
"(basic-syntax/string-slices.html)을 참고하세요."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"struct: \n"
|
|
"A composite data type in Rust that groups together variables of different "
|
|
"types under a single name."
|
|
msgstr ""
|
|
"구조체: \n"
|
|
"다양한 타입의 변수를 단일 이름으로 그룹화하는 Rust의 복합 데이터 타입입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"test: \n"
|
|
"A Rust module containing functions that test the correctness of other "
|
|
"functions."
|
|
msgstr ""
|
|
"test: \n"
|
|
"다른 함수의 정확성을 테스트하는 함수가 포함된 Rust 모듈입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"thread: \n"
|
|
"A separate sequence of execution in a program, allowing concurrent execution."
|
|
msgstr ""
|
|
"스레드: \n"
|
|
"프로그램의 별도 실행 시퀀스로, 동시 실행을 허용합니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"thread safety: \n"
|
|
"The property of a program that ensures correct behavior in a multithreaded "
|
|
"environment."
|
|
msgstr ""
|
|
"스레드 안전: \n"
|
|
"다중 스레드 환경에서 올바른 동작을 보장하는 프로그램의 속성입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"trait: \n"
|
|
"A collection of methods defined for an unknown type, providing a way to "
|
|
"achieve polymorphism in Rust."
|
|
msgstr ""
|
|
"트레잇: \n"
|
|
"알 수 없는 타입에 관해 정의된 메서드 모음으로, Rust에서 다형성을 달성하는 방"
|
|
"법을 제공합니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"trait bound: \n"
|
|
"An abstraction where you can require types to implement some traits of your "
|
|
"interest."
|
|
msgstr ""
|
|
|
|
#: src/glossary.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"tuple: \n"
|
|
"A composite data type that contains variables of different types. Tuple "
|
|
"fields have no names, and are accessed by their ordinal numbers."
|
|
msgstr ""
|
|
"구조체: \n"
|
|
"다양한 타입의 변수를 단일 이름으로 그룹화하는 Rust의 복합 데이터 타입입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"type: \n"
|
|
"A classification that specifies which operations can be performed on values "
|
|
"of a particular kind in Rust."
|
|
msgstr ""
|
|
"타입: \n"
|
|
"Rust에서 특정 종류의 값에 대해 어떤 작업을 실행할 수 있는지 지정하는 분류입니"
|
|
"다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"type inference: \n"
|
|
"The ability of the Rust compiler to deduce the type of a variable or "
|
|
"expression."
|
|
msgstr ""
|
|
"타입 추론: \n"
|
|
"변수나 표현식의 타입을 추론하는 Rust 컴파일러의 기능입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"undefined behavior: \n"
|
|
"Actions or conditions in Rust that have no specified result, often leading "
|
|
"to unpredictable program behavior."
|
|
msgstr ""
|
|
"정의되지 않은 동작: \n"
|
|
"지정된 결과가 없는 Rust의 작업 또는 조건으로, 종종 예측할 수 없는 프로그램 동"
|
|
"작을 초래합니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"union: \n"
|
|
"A data type that can hold values of different types but only one at a time."
|
|
msgstr ""
|
|
"union: \n"
|
|
"한 번에 하나씩만 여러 타입의 값을 보유할 수 있는 데이터 타입입니다."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"unit test: \n"
|
|
"Rust comes with built-in support for running small unit tests and larger "
|
|
"integration tests. See [Unit Tests](testing/unit-tests.html)."
|
|
msgstr ""
|
|
"단위 테스트: \n"
|
|
"Rust에는 작은 단위 테스트와 대규모 통합 테스트를 실행할 수 있는 지원 기능이 "
|
|
"내장되어 있습니다. [단위 테스트](testing/unit-tests.html)를 참고하세요."
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"unit type: \n"
|
|
"Type that holds no data, written as a tuple with no members."
|
|
msgstr ""
|
|
|
|
#: src/glossary.md
|
|
msgid ""
|
|
"unsafe: \n"
|
|
"The subset of Rust which allows you to trigger _undefined behavior_. See "
|
|
"[Unsafe Rust](unsafe.html)."
|
|
msgstr ""
|
|
"안전하지 않음: \n"
|
|
"_정의되지 않은 동작_을 트리거할 수 있는 Rust의 하위 집합입니다. [안전하지 않"
|
|
"은 Rust](unsafe.html)를 참고하세요."
|
|
|
|
#: src/glossary.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"variable: \n"
|
|
"A memory location storing data. Variables are valid in a _scope_."
|
|
msgstr ""
|
|
"변수: \n"
|
|
"데이터를 저장하는 메모리 위치입니다. 변수는 _범위_에서 유효합니다. "
|
|
|
|
#: src/other-resources.md
|
|
msgid "Other Rust Resources"
|
|
msgstr "러스트 참고 자료"
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"The Rust community has created a wealth of high-quality and free resources "
|
|
"online."
|
|
msgstr "러스트 커뮤니티는 온라인에서 고품질의 무료 소스를 만들었습니다."
|
|
|
|
#: src/other-resources.md
|
|
msgid "Official Documentation"
|
|
msgstr "공식 문서들"
|
|
|
|
#: src/other-resources.md
|
|
msgid "The Rust project hosts many resources. These cover Rust in general:"
|
|
msgstr ""
|
|
"러스트 프로젝트에는 참조할 만한 자료가 많습니다. 일반적인 내용을 다루는 몇가"
|
|
"지 참고 문서들입니다:"
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[The Rust Programming Language](https://doc.rust-lang.org/book/): the "
|
|
"canonical free book about Rust. Covers the language in detail and includes a "
|
|
"few projects for people to build."
|
|
msgstr ""
|
|
"[The Rust Programming Language](https://doc.rust-lang.org/book/): 러스트에 대"
|
|
"한 무료 표준 서적입니다. 언어에 대한 자세한 설명과 사람들이 빌드 할수 있는 몇"
|
|
"가지 프로젝트를 포함합니다."
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[Rust By Example](https://doc.rust-lang.org/rust-by-example/): covers the "
|
|
"Rust syntax via a series of examples which showcase different constructs. "
|
|
"Sometimes includes small exercises where you are asked to expand on the code "
|
|
"in the examples."
|
|
msgstr ""
|
|
"[Rust By Example](https://doc.rust-lang.org/rust-by-example/): 여러 예제를 통"
|
|
"해 러스트의 문법을 보여주며 때때로 코드를 확장하는 약간의 연습문제들이 포함되"
|
|
"어 있습니다."
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[Rust Standard Library](https://doc.rust-lang.org/std/): full documentation "
|
|
"of the standard library for Rust."
|
|
msgstr ""
|
|
"[Rust Standard Library](https://doc.rust-lang.org/std/): 러스트 표준 라이브러"
|
|
"리 전체 문서입니다."
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[The Rust Reference](https://doc.rust-lang.org/reference/): an incomplete "
|
|
"book which describes the Rust grammar and memory model."
|
|
msgstr ""
|
|
"[The Rust Reference](https://doc.rust-lang.org/reference/): 메모리 모델링과 "
|
|
"러스트 문법을 설명하는 문서입니다.(아직 불완전하다함)"
|
|
|
|
#: src/other-resources.md
|
|
msgid "More specialized guides hosted on the official Rust site:"
|
|
msgstr "좀 더 전문적인 공식 가이드입니다:"
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[The Rustonomicon](https://doc.rust-lang.org/nomicon/): covers unsafe Rust, "
|
|
"including working with raw pointers and interfacing with other languages "
|
|
"(FFI)."
|
|
msgstr ""
|
|
"[The Rustonomicon](https://doc.rust-lang.org/nomicon/): 안전하지 않은 러스"
|
|
"트, FFI, raw포인터 작업을 다룹니다."
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[Asynchronous Programming in Rust](https://rust-lang.github.io/async-book/): "
|
|
"covers the new asynchronous programming model which was introduced after the "
|
|
"Rust Book was written."
|
|
msgstr ""
|
|
"[Asynchronous Programming in Rust](https://rust-lang.github.io/async-book/): "
|
|
"러스트 북이 작성 된 이후 도입된 새로운 비동기 프로그래밍 모델을 다룹니다."
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[The Embedded Rust Book](https://doc.rust-lang.org/stable/embedded-book/): "
|
|
"an introduction to using Rust on embedded devices without an operating "
|
|
"system."
|
|
msgstr ""
|
|
"[The Embedded Rust Book](https://doc.rust-lang.org/stable/embedded-book/): 운"
|
|
"영체제가 없는 임베디드 장치에서의 러스트 사용법을 소개합니다."
|
|
|
|
#: src/other-resources.md
|
|
msgid "Unofficial Learning Material"
|
|
msgstr "비공식적 학습 자료"
|
|
|
|
#: src/other-resources.md
|
|
msgid "A small selection of other guides and tutorial for Rust:"
|
|
msgstr "러스트에 대한 기타 안내서와 튜토리얼의 일부입니다:"
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[Learn Rust the Dangerous Way](http://cliffle.com/p/dangerust/): covers Rust "
|
|
"from the perspective of low-level C programmers."
|
|
msgstr ""
|
|
"[Learn Rust the Dangerous Way](http://cliffle.com/p/dangerust/): C언어 프로그"
|
|
"래머 관점에서 러스트를 다룹니다."
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[Rust for Embedded C Programmers](https://docs.opentitan.org/doc/ug/"
|
|
"rust_for_c/): covers Rust from the perspective of developers who write "
|
|
"firmware in C."
|
|
msgstr ""
|
|
"[Rust for Embedded C Programmers](https://docs.opentitan.org/doc/ug/"
|
|
"rust_for_c/): 임베디드 C개발자(펌웨어 개발자)를 위한 러스트 가이드입니다."
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[Rust for professionals](https://overexact.com/rust-for-professionals/): "
|
|
"covers the syntax of Rust using side-by-side comparisons with other "
|
|
"languages such as C, C++, Java, JavaScript, and Python."
|
|
msgstr ""
|
|
"[Rust for professionals](https://overexact.com/rust-for-professionals/): 다"
|
|
"른 언어(C/C++, Java, Python, Javascript)와의 병렬비교를 사용하여 러스트 문법"
|
|
"을 다룹니다."
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[Rust on Exercism](https://exercism.org/tracks/rust): 100+ exercises to help "
|
|
"you learn Rust."
|
|
msgstr ""
|
|
"[Rust on Exercism](https://exercism.org/tracks/rust): 러스트를 배우는데 도움"
|
|
"이 되는 100개 이상의 연습문제"
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[Ferrous Teaching Material](https://ferrous-systems.github.io/teaching-"
|
|
"material/index.html): a series of small presentations covering both basic "
|
|
"and advanced part of the Rust language. Other topics such as WebAssembly, "
|
|
"and async/await are also covered."
|
|
msgstr ""
|
|
"[Ferrous Teaching Material](https://ferrous-systems.github.io/teaching-"
|
|
"material/index.html): 러스트 언어의 기본부터 고급을 전부 다루는 일련의 작은 "
|
|
"프레젠테이션, 웹 어셈블리, async/await 같은 부분도 함께 다룹니다."
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"[Beginner's Series to Rust](https://docs.microsoft.com/en-us/shows/beginners-"
|
|
"series-to-rust/) and [Take your first steps with Rust](https://docs."
|
|
"microsoft.com/en-us/learn/paths/rust-first-steps/): two Rust guides aimed at "
|
|
"new developers. The first is a set of 35 videos and the second is a set of "
|
|
"11 modules which covers Rust syntax and basic constructs."
|
|
msgstr ""
|
|
"[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
|
|
msgid ""
|
|
"[Learn Rust With Entirely Too Many Linked Lists](https://rust-unofficial."
|
|
"github.io/too-many-lists/): in-depth exploration of Rust's memory management "
|
|
"rules, through implementing a few different types of list structures."
|
|
msgstr ""
|
|
"[Learn Rust With Entirely Too Many Linked Lists](https://rust-unofficial."
|
|
"github.io/too-many-lists/): 몇가지 유형의 리스트 자료구조를 구현해보면서 러스"
|
|
"트의 메모리 관리 규칙들을 깊이있게 탐색합니다."
|
|
|
|
#: src/other-resources.md
|
|
msgid ""
|
|
"Please see the [Little Book of Rust Books](https://lborb.github.io/book/) "
|
|
"for even more Rust books."
|
|
msgstr ""
|
|
"[Little Book of Rust Books](https://lborb.github.io/book/)에서 더 많은 러스"
|
|
"트 북을 확인해보세요."
|
|
|
|
#: src/credits.md
|
|
msgid ""
|
|
"The material here builds on top of the many great sources of Rust "
|
|
"documentation. See the page on [other resources](other-resources.md) for a "
|
|
"full list of useful resources."
|
|
msgstr ""
|
|
"이 자료는 많은 훌륭한 러스트 문서들의 도움을 받아 작성되었습니다. 유용한 자료"
|
|
"의 전체 목록은 [other resources](other-resources.md)에서 살펴보시기 바랍니다."
|
|
|
|
#: src/credits.md
|
|
#, fuzzy
|
|
msgid ""
|
|
"The material of Comprehensive Rust is licensed under the terms of the Apache "
|
|
"2.0 license, please see [`LICENSE`](https://github.com/google/comprehensive-"
|
|
"rust/blob/main/LICENSE) for details."
|
|
msgstr ""
|
|
"Comprehensive Rust의 자료는 Apache 2.0 라이선스를 따릅니다. 자세한건 "
|
|
"[`LICENSE`](../LICENSE) 확인해 보시기 바랍니다."
|
|
|
|
#: src/credits.md
|
|
msgid "Rust by Example"
|
|
msgstr "Rust by Example"
|
|
|
|
#: src/credits.md
|
|
msgid ""
|
|
"Some examples and exercises have been copied and adapted from [Rust by "
|
|
"Example](https://doc.rust-lang.org/rust-by-example/). Please see the "
|
|
"`third_party/rust-by-example/` directory for details, including the license "
|
|
"terms."
|
|
msgstr ""
|
|
"일부 예제와 연습문제는 [Rust by Example](https://doc.rust-lang.org/rust-by-"
|
|
"example/)을 참조하였습니다. 라이선스 조항을 포함하여 저장소의 `third_party/"
|
|
"rust-by-example/` 폴더를 참조하시기 바랍니다."
|
|
|
|
#: src/credits.md
|
|
msgid "Rust on Exercism"
|
|
msgstr "Rust on Exercism"
|
|
|
|
#: src/credits.md
|
|
msgid ""
|
|
"Some exercises have been copied and adapted from [Rust on Exercism](https://"
|
|
"exercism.org/tracks/rust). Please see the `third_party/rust-on-exercism/` "
|
|
"directory for details, including the license terms."
|
|
msgstr ""
|
|
"일부 연습문제는 [Rust on Exercism](https://exercism.org/tracks/rust)을 참조하"
|
|
"였습니다. 라이선스 조항을 포함하여 저장소의 `third_party/rust-on-exercism/`폴"
|
|
"더를 참조하시기 바랍니다."
|
|
|
|
#: src/credits.md
|
|
msgid "CXX"
|
|
msgstr "CXX"
|
|
|
|
#: src/credits.md
|
|
msgid ""
|
|
"The [Interoperability with C++](android/interoperability/cpp.md) section "
|
|
"uses an image from [CXX](https://cxx.rs/). Please see the `third_party/cxx/` "
|
|
"directory for details, including the license terms."
|
|
msgstr ""
|
|
"4일차 오후 강의 중 [Interoperability with C++](android/interoperability/cpp."
|
|
"md)에서는 [CXX](https://cxx.rs/)의 이미지를 사용하였습니다. 라이선스 조항을 "
|
|
"포함하여 저장소의 `third_party/cxx/`폴더를 참조하시기 바랍니다."
|
|
|
|
#~ msgid "Conditionals"
|
|
#~ msgstr "조건문"
|
|
|
|
#, fuzzy
|
|
#~ msgid "Exercise: GUI Library"
|
|
#~ msgstr "연습문제: GUI 라이브러리 모듈"
|
|
|
|
#, fuzzy
|
|
#~ msgid "With C++)"
|
|
#~ msgstr "C++와의 상호운용성"
|
|
|
|
#, fuzzy
|
|
#~ msgid "{{%course outline Fundamentals}}"
|
|
#~ msgstr "{{%course outline Fundamentals}}"
|
|
|
|
#~ msgid "{{%session outline}}"
|
|
#~ msgstr "{{%session outline}}"
|
|
|
|
#~ msgid "{{%segment outline}}"
|
|
#~ msgstr "{{%segment outline}}"
|
|
|
|
#~ msgid "Much of the Rust syntax will be familiar to you from C, C++ or Java:"
|
|
#~ msgstr "대부분의 러스트 문법은 C/C++/Java 와 유사합니다:"
|
|
|
|
#, fuzzy
|
|
#~ msgid "Blocks are delimited by curly braces."
|
|
#~ msgstr "블록과 범위는 중괄호`{}`로 표현합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Line comments are started with `//`, block comments are delimited by `/"
|
|
#~ "* ... */`."
|
|
#~ msgstr "인라인 주석은 `//`, 블록 주석은 `/* ... */`로 사용합니다."
|
|
|
|
#~ msgid "Keywords like `if` and `while` work the same."
|
|
#~ msgstr "`if`나 `while`같은 키워드도 동일합니다."
|
|
|
|
#~ msgid "Variable assignment is done with `=`, comparison is done with `==`."
|
|
#~ msgstr "변수 할당은 `=`, 비교는 `==`를 사용합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "We will discuss iteration later; for now, just stick to range expressions."
|
|
#~ msgstr ""
|
|
#~ "반복(iteration)에 관해서는 나중에 설명하겠습니다. 지금은 범위 표현식에 집"
|
|
#~ "중합니다."
|
|
|
|
#~ msgid "\"{result}\""
|
|
#~ msgstr "\"{result}\""
|
|
|
|
#~ msgid "\"x: {x}, i: {i}\""
|
|
#~ msgstr "\"x: {x}, i: {i}\""
|
|
|
|
#~ msgid ""
|
|
#~ "In this case we break the outer loop after 3 iterations of the inner loop."
|
|
#~ msgstr ""
|
|
#~ "위 예제는 내부의 `while` 루프를 3회 반복한 후 바깥 루프를 빠져나갑니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Tuples and arrays are the first \"compound\" types we have seen. All "
|
|
#~ "elements of an array have the same type, while tuples can accommodate "
|
|
#~ "different types. Both types have a size fixed at compile time."
|
|
#~ msgstr ""
|
|
#~ "튜플과 배열은 처음으로 접하는 '복합' 타입입니다. 배열의 모든 요소는 동일"
|
|
#~ "한 타입 가지지만 튜플은 서로 다른 타입을 수용할 수 있습니다. 두 타입 모두 "
|
|
#~ "컴파일 시간에 고정된 크기를 갖습니다."
|
|
|
|
#~ msgid "`[T; N]`"
|
|
#~ msgstr "`[T; N]`"
|
|
|
|
#~ msgid "`[20, 30, 40]`, `[0; 3]`"
|
|
#~ msgstr "`[20, 30, 40]`, `[0; 3]`"
|
|
|
|
#~ msgid "`()`, `(T,)`, `(T1, T2)`, ..."
|
|
#~ msgstr "`()`, `(T,)`, `(T1, T2)`, ..."
|
|
|
|
#~ msgid "`()`, `('x',)`, `('x', 1.2)`, ..."
|
|
#~ msgstr "`()`, `('x',)`, `('x', 1.2)`, ..."
|
|
|
|
#~ msgid "Array assignment and access:"
|
|
#~ msgstr "배열 선언과 접근:"
|
|
|
|
#~ msgid "Tuple assignment and access:"
|
|
#~ msgstr "튜플 선언과 접근:"
|
|
|
|
#~ msgid "Arrays:"
|
|
#~ msgstr "배열:"
|
|
|
|
#~ msgid "Tuples:"
|
|
#~ msgstr "튜플:"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "The empty tuple `()` is also known as the \"unit type\". It is both a "
|
|
#~ "type, and the only valid value of that type --- that is to say both the "
|
|
#~ "type and its value are expressed as `()`. It is used to indicate, for "
|
|
#~ "example, that a function or expression has no return value, as we'll see "
|
|
#~ "in a future slide."
|
|
#~ msgstr ""
|
|
#~ "비어있는 튜플`()`은 단위 타입(unit type)이라고도 합니다. 이는 타입이면서 "
|
|
#~ "해당 타입의 유일하며 유효한 값입니다. 즉 타입과 값이 모두 `()`입니다. 예"
|
|
#~ "를 들어 함수나 식에서 반환 값이 없음을 나타낼 때 사용합니다. "
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "You can think of it as `void` that can be familiar to you from other "
|
|
#~ "programming languages."
|
|
#~ msgstr "다른 언어에서 익숙한 `void` 개념으로 생각할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Destructuring is a way of extracting data from a data structure by "
|
|
#~ "writing a pattern that is matched up to the data structure, binding "
|
|
#~ "variables to subcomponents of the data structure."
|
|
#~ msgstr ""
|
|
#~ "디스트럭처링은 데이터 구조와 일치하는 패턴을 작성하여 데이터 구조의 하위 "
|
|
#~ "구성요소에 변수를 결합함으로써 데이터 구조에서 데이터를 추출하는 방법입니"
|
|
#~ "다."
|
|
|
|
#, fuzzy
|
|
#~ msgid "You can destructure tuples and arrays by matching on their elements:"
|
|
#~ msgstr ""
|
|
#~ "배열이나 튜플, 슬라이스도 그 요소들에 대해 패턴 매칭으로 분해할 수 있습니"
|
|
#~ "다:"
|
|
|
|
#~ msgid "\"on Y axis\""
|
|
#~ msgstr "\"Y축\""
|
|
|
|
#~ msgid "\"on X axis\""
|
|
#~ msgstr "\"X축\""
|
|
|
|
#~ msgid "\"left of Y axis\""
|
|
#~ msgstr "\"Y축 왼쪽\""
|
|
|
|
#~ msgid "\"below X axis\""
|
|
#~ msgstr "\"X축 아래\""
|
|
|
|
#~ msgid "\"first quadrant\""
|
|
#~ msgstr "\"1사분면\""
|
|
|
|
#~ msgid "\"Tell me about {triple:?}\""
|
|
#~ msgstr "\"{triple:?}에 관해 말해 주세요.\""
|
|
|
|
#~ msgid "\"First is 0, y = {y}, and z = {z}\""
|
|
#~ msgstr "\"첫 번째는 0, y = {y}, z = {z}입니다.\""
|
|
|
|
#~ msgid "\"First is 1 and the rest were ignored\""
|
|
#~ msgstr "\"첫 번째는 1이고 나머지는 무시되었습니다.\""
|
|
|
|
#~ msgid "\"All elements were ignored\""
|
|
#~ msgstr "\"모든 요소가 무시되었습니다.\""
|
|
|
|
#, fuzzy
|
|
#~ msgid "Create a new array pattern using `_` to represent an element."
|
|
#~ msgstr "`_`를 사용하여 요소를 매칭하는 패턴을 추가해보세요. "
|
|
|
|
#~ msgid "Add more values to the array."
|
|
#~ msgstr "배열에 값을 더 추가해보세요."
|
|
|
|
#~ msgid ""
|
|
#~ "Point out that how `..` will expand to account for different number of "
|
|
#~ "elements."
|
|
#~ msgstr "`..`가 요소 개수에 상관없이 매치될 수 있음을 알려주세요."
|
|
|
|
#~ msgid ""
|
|
#~ "Show matching against the tail with patterns `[.., b]` and `[a@..,b]`"
|
|
#~ msgstr ""
|
|
#~ "`[.., b]`나 `[a@.., b]`와 같은 패턴으로 꼬리 부분을 매칭하는 것을 보여주세"
|
|
#~ "요"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "Let us design a classical GUI library using our new knowledge of traits "
|
|
#~ "and trait objects. We'll only implement the drawing of it (as text) for "
|
|
#~ "simplicity."
|
|
#~ msgstr ""
|
|
#~ "이번 연습문제에서는 트레잇와 트레잇 객체에 대해 배운것을 활용하여 고전적"
|
|
#~ "인 GUI 라이브러리를 설계할 것입니다."
|
|
|
|
#~ msgid "We will have a number of widgets in our library:"
|
|
#~ msgstr "라이브러리에는 몇 가지 위젯이 있습니다:"
|
|
|
|
#~ msgid "`Window`: has a `title` and contains other widgets."
|
|
#~ msgstr ""
|
|
#~ "`Window`: `title` 속성을 가지고 있으며, 다른 위젯들을 포함할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "`Button`: has a `label`. In reality, it would also take a callback "
|
|
#~ "function to allow the program to do something when the button is clicked "
|
|
#~ "but we won't include that since we're only drawing the GUI."
|
|
#~ msgstr ""
|
|
#~ "`Button`:에는 `label`이 있습니다. 실제로는 버튼을 클릭할 때 프로그램이 어"
|
|
#~ "떤 작업을 할 수 있도록 콜백 함수도 사용하지만 여기서는 GUI만 그리므로 포함"
|
|
#~ "하지 않습니다."
|
|
|
|
#~ msgid "`Label`: has a `label`."
|
|
#~ msgstr "`Label`: `label` 속성을 가지고 있습니다."
|
|
|
|
#~ msgid "The widgets will implement a `Widget` trait, see below."
|
|
#~ msgstr "위젯들은 모두 `Widget` 트레잇을 구현합니다. 아래 코드를 참조하세요."
|
|
|
|
#~ msgid ""
|
|
#~ "Copy the code below to <https://play.rust-lang.org/>, fill in the missing "
|
|
#~ "`draw_into` methods so that you implement the `Widget` trait:"
|
|
#~ msgstr ""
|
|
#~ "아래 코드를 <https://play.rust-lang.org/>에 복사하고 누락된 `draw_into`메"
|
|
#~ "서드를 채워 넣어 `Widget` 트레잇을 완성해봅시다:"
|
|
|
|
#~ msgid "// TODO: Implement `Widget` for `Label`.\n"
|
|
#~ msgstr "// TODO: `Label`의 `Widget`을 구현합니다.\n"
|
|
|
|
#~ msgid "// TODO: Implement `Widget` for `Button`.\n"
|
|
#~ msgstr "// TODO: `Button`의 `Widget`을 구현합니다.\n"
|
|
|
|
#~ msgid "// TODO: Implement `Widget` for `Window`.\n"
|
|
#~ msgstr "// TODO: `Window`의 `Widget`을 구현합니다.\n"
|
|
|
|
#~ msgid "The output of the above program can be something simple like this:"
|
|
#~ msgstr "위 프로그램의 출력은 아래와 같습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "If you want to draw aligned text, you can use the [fill/alignment]"
|
|
#~ "(https://doc.rust-lang.org/std/fmt/index.html#fillalignment) formatting "
|
|
#~ "operators. In particular, notice how you can pad with different "
|
|
#~ "characters (here a `'/'`) and how you can control alignment:"
|
|
#~ msgstr ""
|
|
#~ "텍스트를 줄맞춤 해서 그리려면 [fill/alignment](https://doc.rust-lang.org/"
|
|
#~ "std/fmt/index.html#fillalignment)를 참조하시기 바랍니다. 특수 문자(여기서"
|
|
#~ "는 `'/'`)로 패딩을 주는 방법과 정렬을 제어하는 방법을 확인하시기 바랍니다:"
|
|
|
|
#~ msgid "\"left aligned: |{:/<width$}|\""
|
|
#~ msgstr "\"왼쪽 정렬: |{:/<width$}|\""
|
|
|
|
#~ msgid "\"centered: |{:/^width$}|\""
|
|
#~ msgstr "\"가운데 정렬: |{:/^width$}|\""
|
|
|
|
#~ msgid "\"right aligned: |{:/>width$}|\""
|
|
#~ msgstr "\"오른쪽 정렬: |{:/>width$}|\""
|
|
|
|
#~ msgid ""
|
|
#~ "Using such alignment tricks, you can for example produce output like this:"
|
|
#~ msgstr "위의 정렬 트릭을 사용하여 다음과 같은 출력을 생성할 수 있습니다:"
|
|
|
|
#~ msgid "/// Return true if self is less than other.\n"
|
|
#~ msgstr "/// self가 other보다 작으면 true를 반환합니다.\n"
|
|
|
|
#~ msgid "\"Shapiro\""
|
|
#~ msgstr "\"Shapiro\""
|
|
|
|
#~ msgid "\"Baumann\""
|
|
#~ msgstr "\"Baumann\""
|
|
|
|
#~ msgid "\"there\""
|
|
#~ msgstr "\"there\""
|
|
|
|
#~ msgid "\"ptr = {ptr:#x}, len = {len}, capacity = {capacity}\""
|
|
#~ msgstr "\"ptr = {ptr:#x}, len = {len}, capacity = {capacity}\""
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "Rust provides a few safe means of modifying a value given only a shared "
|
|
#~ "reference to that value. All of these replace compile-time checks with "
|
|
#~ "runtime checks."
|
|
#~ msgstr ""
|
|
#~ "Rust는 해당 값에 대한 공유 참조만 주어지면 값을 수정하는 몇 가지 안전한 방"
|
|
#~ "법을 제공합니다. 이 모든 것이 컴파일 시간 검사를 런타임 검사로 대체합니다."
|
|
|
|
#~ msgid "`Cell` and `RefCell`"
|
|
#~ msgstr "`Cell`과 `RefCell`"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "[`Cell`](https://doc.rust-lang.org/std/cell/struct.Cell.html) and "
|
|
#~ "[`RefCell`](https://doc.rust-lang.org/std/cell/struct.RefCell.html) "
|
|
#~ "implement what Rust calls _interior mutability:_ mutation of values in an "
|
|
#~ "immutable context."
|
|
#~ msgstr ""
|
|
#~ "[`Cell`](https://doc.rust-lang.org/std/cell/struct.Cell.html 과 "
|
|
#~ "[`RefCell`](https://doc.rust-lang.org/std/cell/struct.RefCell.html)은 러스"
|
|
#~ "트에서 _내적 가변성(interior mutability)_이라고 부르는 것을 구현합니다. 이"
|
|
#~ "를 이용하면 불변인 객체의 값을 수정할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "`Cell` is typically used for simple types, as it requires copying or "
|
|
#~ "moving values. More complex interior types typically use `RefCell`, which "
|
|
#~ "tracks shared and exclusive references at runtime and panics if they are "
|
|
#~ "misused."
|
|
#~ msgstr ""
|
|
#~ "`Cell`은 간단한 타입에 대해서 주로 사용됩니다. 왜냐하면 `Cell`에 있는 값"
|
|
#~ "을 읽거나 쓸때에는 복사 혹은 이동을 해야만 하기 때문입니다. 복잡한 타입이"
|
|
#~ "라면 `RefCell`이 더 보편적입니다. 이를 이용하면 참조를 통해 값을 읽거나 쓰"
|
|
#~ "게 해 주는 대신, 그 참조들이 올바른지를 런타임에 체크하고, 제대로 사용되"
|
|
#~ "지 않을 경우 패닉을 발생시킵니다."
|
|
|
|
#~ msgid ""
|
|
#~ "If we were using `Cell` instead of `RefCell` in this example, we would "
|
|
#~ "have to move the `Node` out of the `Rc` to push children, then move it "
|
|
#~ "back in. This is safe because there's always one, un-referenced value in "
|
|
#~ "the cell, but it's not ergonomic."
|
|
#~ msgstr ""
|
|
#~ "이 예제에서 `RefCell`대신 `Cell`을 썼었다면, `Node`에 자식 노느를 추가하"
|
|
#~ "기 위해서, `Node`를 `Rc`밖으로 이동시킨 다음, 자식 노드를 추가하고, 다시 "
|
|
#~ "`Rc`안으로 이동시켜야 했을 겁니다. 이렇게 해야만 하는 이유는 안전 때문입니"
|
|
#~ "다. Cell 내부의 그 값이 오직 하나 존재하며, 그 값에 대한 참조가 없다는 것"
|
|
#~ "이 보장되기 때문입니다. 물론 편리하지는 않습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "To do anything with a Node, you must call a `RefCell` method, usually "
|
|
#~ "`borrow` or `borrow_mut`."
|
|
#~ msgstr ""
|
|
#~ "노드를 이동하거나 복사하지 않고 그대로 사용하기 위해서는 `RefCell`로 감싼"
|
|
#~ "다음 `borrow`나 `borrow_mut`메서드를 이용해야 합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "If you no longer have your version, that's fine - refer back to the "
|
|
#~ "[provided solution](../methods-and-traits/solution.html)."
|
|
#~ msgstr ""
|
|
#~ "예전에 작업했던 버전이 없어도 괜찮습니다. [제공된 솔루션](../methods-and-"
|
|
#~ "traits/solution.html)을 다시 참고하세요."
|
|
|
|
#~ msgid "Rust comes with only basic support for writing tests."
|
|
#~ msgstr "러스트는 테스트 작성과 관련해서는 기본적인 기능만 지원합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Here are some additional crates which we recommend for writing tests:"
|
|
#~ msgstr "다음은 테스트를 작성할 때 권장되는 추가 크레이트입니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "[googletest](https://docs.rs/googletest): Comprehensive test assertion "
|
|
#~ "library in the tradition of GoogleTest for C++."
|
|
#~ msgstr ""
|
|
#~ "[googletest](https://docs.rs/googletest): C++용 GoogleTest의 방식을 따르"
|
|
#~ "는 테스트 라이브러리 입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "[proptest](https://docs.rs/proptest): Property-based testing for Rust."
|
|
#~ msgstr ""
|
|
#~ "[proptest](https://docs.rs/proptest): Rust용 속성 기반 테스트입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "[rstest](https://docs.rs/rstest): Support for fixtures and parameterised "
|
|
#~ "tests."
|
|
#~ msgstr ""
|
|
#~ "[rstest](https://docs.rs/rstest): 픽스처 및 매개변수화된 테스트를 지원합니"
|
|
#~ "다."
|
|
|
|
#~ msgid "GoogleTest is available for use in AOSP."
|
|
#~ msgstr "GoogleTest는 AOSP에서 사용할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Add `vendor_available: true` if your AIDL file is used by a binary in the "
|
|
#~ "vendor partition."
|
|
#~ msgstr ""
|
|
#~ "AIDL 파일이 벤더 파티션에 있는 바이너리에서 사용될 경우 "
|
|
#~ "`vendor_available: true`를 추가합니다."
|
|
|
|
#~ msgid "/// Connect to the BirthdayService.\n"
|
|
#~ msgstr "/// BirthdayService에 연결합니다.\n"
|
|
|
|
#~ msgid ""
|
|
#~ "// Set up the I2C controller and Inertial Measurement Unit.\n"
|
|
#~ " // TODO\n"
|
|
#~ msgstr ""
|
|
#~ "// I2C 컨트롤러 및 관성 측정 장치를 설정합니다.\n"
|
|
#~ " // TODO\n"
|
|
|
|
#~ msgid ""
|
|
#~ "// Read compass data and log it to the serial port.\n"
|
|
#~ " // TODO\n"
|
|
#~ msgstr ""
|
|
#~ "// 나침반 데이터를 읽고 직렬 포트에 기록합니다.\n"
|
|
#~ " // TODO\n"
|
|
|
|
#~ msgid "// TODO: Create instance of RTC driver and print current time.\n"
|
|
#~ msgstr "// TODO: RTC 드라이버의 인스턴스를 만들고 현재 시간을 출력합니다.\n"
|
|
|
|
#~ msgid "// TODO: Wait for 3 seconds.\n"
|
|
#~ msgstr "// TODO: 3초 동안 기다립니다.\n"
|
|
|
|
#~ msgid ""
|
|
#~ "// Copyright 2023 Google LLC\n"
|
|
#~ "//\n"
|
|
#~ "// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
|
|
#~ "// you may not use this file except in compliance with the License.\n"
|
|
#~ "// You may obtain a copy of the License at\n"
|
|
#~ "//\n"
|
|
#~ "// http://www.apache.org/licenses/LICENSE-2.0\n"
|
|
#~ "//\n"
|
|
#~ "// Unless required by applicable law or agreed to in writing, software\n"
|
|
#~ "// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
|
#~ "// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
|
|
#~ "implied.\n"
|
|
#~ "// See the License for the specific language governing permissions and\n"
|
|
#~ "// limitations under the License.\n"
|
|
#~ msgstr ""
|
|
#~ "// Copyright 2023 Google LLC\n"
|
|
#~ "//\n"
|
|
#~ "// Apache 라이선스 버전 2.0('라이선스')에 따라 라이선스가 부여되었습니"
|
|
#~ "다.\n"
|
|
#~ "// 라이선스를 준수하지 않으면 이 파일을 사용할 수 없습니다.\n"
|
|
#~ "// 다음 주소에서 라이선스 사본을 가져올 수 있습니다.\n"
|
|
#~ "//\n"
|
|
#~ "// http://www.apache.org/licenses/LICENSE-2.0\n"
|
|
#~ "//\n"
|
|
#~ "// 관련법에서 요구하거나 서면으로 동의한 경우를 제외하고\n"
|
|
#~ "// 본 라이선스에 따라 배포되는 소프트웨어는 어떠한 종류의 명시적 또는 묵시"
|
|
#~ "적 보증 또는 조건도 없이\n"
|
|
#~ "// '있는 그대로' 배포됩니다.\n"
|
|
#~ "// 라이선스에 따른 권한과 제한사항에 관한\n"
|
|
#~ "// 특정 언어의 라이선스를 확인하세요.\n"
|
|
|
|
#~ msgid "\"sync_exception_current\""
|
|
#~ msgstr "\"sync_exception_current\""
|
|
|
|
#, fuzzy
|
|
#~ msgid "\"irq_current\""
|
|
#~ msgstr "\"irq_current\""
|
|
|
|
#~ msgid "\"No pending interrupt\""
|
|
#~ msgstr "\"대기 중인 인터럽트 없음\""
|
|
|
|
#~ msgid "\"IRQ {intid:?}\""
|
|
#~ msgstr "\"IRQ {intid:?}\""
|
|
|
|
#~ msgid "\"fiq_current\""
|
|
#~ msgstr "\"fiq_current\""
|
|
|
|
#~ msgid "\"serr_current\""
|
|
#~ msgstr "\"serr_current\""
|
|
|
|
#~ msgid "\"sync_lower\""
|
|
#~ msgstr "\"sync_lower\""
|
|
|
|
#~ msgid "\"irq_lower\""
|
|
#~ msgstr "\"irq_lower\""
|
|
|
|
#~ msgid "\"fiq_lower\""
|
|
#~ msgstr "\"fiq_lower\""
|
|
|
|
#~ msgid "\"serr_lower\""
|
|
#~ msgstr "\"serr_lower\""
|
|
|
|
#~ msgid "// ANCHOR: main\n"
|
|
#~ msgstr "// ANCHOR: main\n"
|
|
|
|
#~ msgid "// ANCHOR: Flags\n"
|
|
#~ msgstr "// ANCHOR: 플래그\n"
|
|
|
|
#~ msgid "// ANCHOR_END: Flags\n"
|
|
#~ msgstr "// ANCHOR_END: 플래그\n"
|
|
|
|
#~ msgid ""
|
|
#~ "/// Flags from the UART Receive Status Register / Error Clear Register.\n"
|
|
#~ msgstr "/// UART 수신 상태 레지스터 / 오류 정리 레지스터의 플래그\n"
|
|
|
|
#~ msgid "/// Framing error.\n"
|
|
#~ msgstr "/// 프레임 오류\n"
|
|
|
|
#~ msgid "/// Parity error.\n"
|
|
#~ msgstr "/// 패리티 오류\n"
|
|
|
|
#~ msgid "/// Break error.\n"
|
|
#~ msgstr "/// 중단 오류\n"
|
|
|
|
#~ msgid "/// Overrun error.\n"
|
|
#~ msgstr "/// 오버런 오류\n"
|
|
|
|
#~ msgid "// ANCHOR: Registers\n"
|
|
#~ msgstr "// ANCHOR: 레지스터\n"
|
|
|
|
#~ msgid "// ANCHOR_END: Registers\n"
|
|
#~ msgstr "// ANCHOR_END: 레지스터\n"
|
|
|
|
#~ msgid ""
|
|
#~ "// ANCHOR: Uart\n"
|
|
#~ "/// Driver for a PL011 UART.\n"
|
|
#~ msgstr ""
|
|
#~ "// ANCHOR: Uart\n"
|
|
#~ "/// PL011 UART의 드라이버입니다.\n"
|
|
|
|
#~ msgid ""
|
|
#~ "/// Constructs a new instance of the UART driver for a PL011 device at "
|
|
#~ "the\n"
|
|
#~ " /// given base address.\n"
|
|
#~ " ///\n"
|
|
#~ " /// # Safety\n"
|
|
#~ " ///\n"
|
|
#~ " /// The given base address must point to the MMIO control registers "
|
|
#~ "of a\n"
|
|
#~ " /// PL011 device, which must be mapped into the address space of the "
|
|
#~ "process\n"
|
|
#~ " /// as device memory and not have any other aliases.\n"
|
|
#~ msgstr ""
|
|
#~ "/// 지정된 기본 주소에 PL011 기기에 대한 UART 드라이버의 새 인스턴스를\n"
|
|
#~ " /// 생성합니다.\n"
|
|
#~ " ///\n"
|
|
#~ " /// # 안전\n"
|
|
#~ " ///\n"
|
|
#~ " /// 지정된 기본 주소는 PL011 기기의\n"
|
|
#~ " /// MMIO 제어 레지스터를 가리켜야 하며,\n"
|
|
#~ " /// 이는 프로세스의 주소 공간에 기기 메모리로\n"
|
|
#~ " /// 매핑되어야 하며 다른 별칭은 없어야 합니다.\n"
|
|
|
|
#~ msgid "// ANCHOR_END: Uart\n"
|
|
#~ msgstr "// ANCHOR_END: Uart\n"
|
|
|
|
#~ msgid "\"linux\""
|
|
#~ msgstr "\"linux\""
|
|
|
|
#~ msgid "\"CROSS_COMPILE\""
|
|
#~ msgstr "\"CROSS_COMPILE\""
|
|
|
|
#~ msgid "\"aarch64-linux-gnu\""
|
|
#~ msgstr "\"aarch64-linux-gnu\""
|
|
|
|
#~ msgid "\"aarch64-none-elf\""
|
|
#~ msgstr "\"aarch64-none-elf\""
|
|
|
|
#~ msgid "\"entry.S\""
|
|
#~ msgstr "\"entry.S\""
|
|
|
|
#~ msgid "\"exceptions.S\""
|
|
#~ msgstr "\"exceptions.S\""
|
|
|
|
#~ msgid "\"idmap.S\""
|
|
#~ msgstr "\"idmap.S\""
|
|
|
|
#~ msgid "\"empty\""
|
|
#~ msgstr "\"비어 있음\""
|
|
|
|
#~ msgid ""
|
|
#~ "```armasm\n"
|
|
#~ "/*\n"
|
|
#~ " * Copyright 2023 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"
|
|
#~ " * https://www.apache.org/licenses/LICENSE-2.0\n"
|
|
#~ " *\n"
|
|
#~ " * Unless required by applicable law or agreed to in writing, software\n"
|
|
#~ " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
|
#~ " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
|
|
#~ "implied.\n"
|
|
#~ " * See the License for the specific language governing permissions and\n"
|
|
#~ " * limitations under the License.\n"
|
|
#~ " */\n"
|
|
#~ "\n"
|
|
#~ ".macro adr_l, reg:req, sym:req\n"
|
|
#~ "\tadrp \\reg, \\sym\n"
|
|
#~ "\tadd \\reg, \\reg, :lo12:\\sym\n"
|
|
#~ ".endm\n"
|
|
#~ "\n"
|
|
#~ ".macro mov_i, reg:req, imm:req\n"
|
|
#~ "\tmovz \\reg, :abs_g3:\\imm\n"
|
|
#~ "\tmovk \\reg, :abs_g2_nc:\\imm\n"
|
|
#~ "\tmovk \\reg, :abs_g1_nc:\\imm\n"
|
|
#~ "\tmovk \\reg, :abs_g0_nc:\\imm\n"
|
|
#~ ".endm\n"
|
|
#~ "\n"
|
|
#~ ".set .L_MAIR_DEV_nGnRE,\t0x04\n"
|
|
#~ ".set .L_MAIR_MEM_WBWA,\t0xff\n"
|
|
#~ ".set .Lmairval, .L_MAIR_DEV_nGnRE | (.L_MAIR_MEM_WBWA << 8)\n"
|
|
#~ "\n"
|
|
#~ "/* 4 KiB granule size for TTBR0_EL1. */\n"
|
|
#~ ".set .L_TCR_TG0_4KB, 0x0 << 14\n"
|
|
#~ "/* 4 KiB granule size for TTBR1_EL1. */\n"
|
|
#~ ".set .L_TCR_TG1_4KB, 0x2 << 30\n"
|
|
#~ "/* Disable translation table walk for TTBR1_EL1, generating a translation "
|
|
#~ "fault instead. */\n"
|
|
#~ ".set .L_TCR_EPD1, 0x1 << 23\n"
|
|
#~ "/* Translation table walks for TTBR0_EL1 are inner sharable. */\n"
|
|
#~ ".set .L_TCR_SH_INNER, 0x3 << 12\n"
|
|
#~ "/*\n"
|
|
#~ " * Translation table walks for TTBR0_EL1 are outer write-back read-"
|
|
#~ "allocate write-allocate\n"
|
|
#~ " * cacheable.\n"
|
|
#~ " */\n"
|
|
#~ ".set .L_TCR_RGN_OWB, 0x1 << 10\n"
|
|
#~ "/*\n"
|
|
#~ " * Translation table walks for TTBR0_EL1 are inner write-back read-"
|
|
#~ "allocate write-allocate\n"
|
|
#~ " * cacheable.\n"
|
|
#~ " */\n"
|
|
#~ ".set .L_TCR_RGN_IWB, 0x1 << 8\n"
|
|
#~ "/* Size offset for TTBR0_EL1 is 2**39 bytes (512 GiB). */\n"
|
|
#~ ".set .L_TCR_T0SZ_512, 64 - 39\n"
|
|
#~ ".set .Ltcrval, .L_TCR_TG0_4KB | .L_TCR_TG1_4KB | .L_TCR_EPD1 | ."
|
|
#~ "L_TCR_RGN_OWB\n"
|
|
#~ ".set .Ltcrval, .Ltcrval | .L_TCR_RGN_IWB | .L_TCR_SH_INNER | ."
|
|
#~ "L_TCR_T0SZ_512\n"
|
|
#~ "\n"
|
|
#~ "/* Stage 1 instruction access cacheability is unaffected. */\n"
|
|
#~ ".set .L_SCTLR_ELx_I, 0x1 << 12\n"
|
|
#~ "/* SP alignment fault if SP is not aligned to a 16 byte boundary. */\n"
|
|
#~ ".set .L_SCTLR_ELx_SA, 0x1 << 3\n"
|
|
#~ "/* Stage 1 data access cacheability is unaffected. */\n"
|
|
#~ ".set .L_SCTLR_ELx_C, 0x1 << 2\n"
|
|
#~ "/* EL0 and EL1 stage 1 MMU enabled. */\n"
|
|
#~ ".set .L_SCTLR_ELx_M, 0x1 << 0\n"
|
|
#~ "/* Privileged Access Never is unchanged on taking an exception to EL1. "
|
|
#~ "*/\n"
|
|
#~ ".set .L_SCTLR_EL1_SPAN, 0x1 << 23\n"
|
|
#~ "/* SETEND instruction disabled at EL0 in aarch32 mode. */\n"
|
|
#~ ".set .L_SCTLR_EL1_SED, 0x1 << 8\n"
|
|
#~ "/* Various IT instructions are disabled at EL0 in aarch32 mode. */\n"
|
|
#~ ".set .L_SCTLR_EL1_ITD, 0x1 << 7\n"
|
|
#~ ".set .L_SCTLR_EL1_RES1, (0x1 << 11) | (0x1 << 20) | (0x1 << 22) | (0x1 << "
|
|
#~ "28) | (0x1 << 29)\n"
|
|
#~ ".set .Lsctlrval, .L_SCTLR_ELx_M | .L_SCTLR_ELx_C | .L_SCTLR_ELx_SA | ."
|
|
#~ "L_SCTLR_EL1_ITD | .L_SCTLR_EL1_SED\n"
|
|
#~ ".set .Lsctlrval, .Lsctlrval | .L_SCTLR_ELx_I | .L_SCTLR_EL1_SPAN | ."
|
|
#~ "L_SCTLR_EL1_RES1\n"
|
|
#~ "\n"
|
|
#~ "/**\n"
|
|
#~ " * This is a generic entry point for an image. It carries out the "
|
|
#~ "operations required to prepare the\n"
|
|
#~ " * loaded image to be run. Specifically, it zeroes the bss section using "
|
|
#~ "registers x25 and above,\n"
|
|
#~ " * prepares the stack, enables floating point, and sets up the exception "
|
|
#~ "vector. It preserves x0-x3\n"
|
|
#~ " * for the Rust entry point, as these may contain boot parameters.\n"
|
|
#~ " */\n"
|
|
#~ ".section .init.entry, \"ax\"\n"
|
|
#~ ".global entry\n"
|
|
#~ "entry:\n"
|
|
#~ "\t/* Load and apply the memory management configuration, ready to enable "
|
|
#~ "MMU and caches. */\n"
|
|
#~ "\tadrp x30, idmap\n"
|
|
#~ "\tmsr ttbr0_el1, x30\n"
|
|
#~ "\n"
|
|
#~ "\tmov_i x30, .Lmairval\n"
|
|
#~ "\tmsr mair_el1, x30\n"
|
|
#~ "\n"
|
|
#~ "\tmov_i x30, .Ltcrval\n"
|
|
#~ "\t/* Copy the supported PA range into TCR_EL1.IPS. */\n"
|
|
#~ "\tmrs x29, id_aa64mmfr0_el1\n"
|
|
#~ "\tbfi x30, x29, #32, #4\n"
|
|
#~ "\n"
|
|
#~ "\tmsr tcr_el1, x30\n"
|
|
#~ "\n"
|
|
#~ "\tmov_i x30, .Lsctlrval\n"
|
|
#~ "\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * Ensure everything before this point has completed, then invalidate "
|
|
#~ "any potentially stale\n"
|
|
#~ "\t * local TLB entries before they start being used.\n"
|
|
#~ "\t */\n"
|
|
#~ "\tisb\n"
|
|
#~ "\ttlbi vmalle1\n"
|
|
#~ "\tic iallu\n"
|
|
#~ "\tdsb nsh\n"
|
|
#~ "\tisb\n"
|
|
#~ "\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * Configure sctlr_el1 to enable MMU and cache and don't proceed until "
|
|
#~ "this has completed.\n"
|
|
#~ "\t */\n"
|
|
#~ "\tmsr sctlr_el1, x30\n"
|
|
#~ "\tisb\n"
|
|
#~ "\n"
|
|
#~ "\t/* Disable trapping floating point access in EL1. */\n"
|
|
#~ "\tmrs x30, cpacr_el1\n"
|
|
#~ "\torr x30, x30, #(0x3 << 20)\n"
|
|
#~ "\tmsr cpacr_el1, x30\n"
|
|
#~ "\tisb\n"
|
|
#~ "\n"
|
|
#~ "\t/* Zero out the bss section. */\n"
|
|
#~ "\tadr_l x29, bss_begin\n"
|
|
#~ "\tadr_l x30, bss_end\n"
|
|
#~ "0:\tcmp x29, x30\n"
|
|
#~ "\tb.hs 1f\n"
|
|
#~ "\tstp xzr, xzr, [x29], #16\n"
|
|
#~ "\tb 0b\n"
|
|
#~ "\n"
|
|
#~ "1:\t/* Prepare the stack. */\n"
|
|
#~ "\tadr_l x30, boot_stack_end\n"
|
|
#~ "\tmov sp, x30\n"
|
|
#~ "\n"
|
|
#~ "\t/* Set up exception vector. */\n"
|
|
#~ "\tadr x30, vector_table_el1\n"
|
|
#~ "\tmsr vbar_el1, x30\n"
|
|
#~ "\n"
|
|
#~ "\t/* Call into Rust code. */\n"
|
|
#~ "\tbl main\n"
|
|
#~ "\n"
|
|
#~ "\t/* Loop forever waiting for interrupts. */\n"
|
|
#~ "2:\twfi\n"
|
|
#~ "\tb 2b\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```armasm\n"
|
|
#~ "/*\n"
|
|
#~ " * Copyright 2023 Google LLC\n"
|
|
#~ " *\n"
|
|
#~ " * Apache 라이선스 버전 2.0(\"라이선스\")에 따라 라이선스가 부여되었습니"
|
|
#~ "다.\n"
|
|
#~ " * 라이선스를 준수하지 않으면 이 파일을 사용할 수 없습니다.\n"
|
|
#~ " * 다음 주소에서 라이선스 사본을 가져올 수 있습니다.\n"
|
|
#~ " *\n"
|
|
#~ " * https://www.apache.org/licenses/LICENSE-2.0\n"
|
|
#~ " *\n"
|
|
#~ " * 관련법에서 요구하거나 서면으로 동의한 경우를 제외하고\n"
|
|
#~ " * 본 라이선스에 따라 배포되는 소프트웨어는 어떠한 종류의 명시적 또는 묵시"
|
|
#~ "적 보증 또는 조건도 없이\n"
|
|
#~ " * \"있는 그대로\" 배포됩니다.\n"
|
|
#~ " * 라이선스에 따른 권한과 제한사항에 관한\n"
|
|
#~ " * 특정 언어의 라이선스를 확인하세요.\n"
|
|
#~ " */\n"
|
|
#~ "\n"
|
|
#~ ".macro adr_l, reg:req, sym:req\n"
|
|
#~ "\tadrp \\reg, \\sym\n"
|
|
#~ "\tadd \\reg, \\reg, :lo12:\\sym\n"
|
|
#~ ".endm\n"
|
|
#~ "\n"
|
|
#~ ".macro mov_i, reg:req, imm:req\n"
|
|
#~ "\tmovz \\reg, :abs_g3:\\imm\n"
|
|
#~ "\tmovk \\reg, :abs_g2_nc:\\imm\n"
|
|
#~ "\tmovk \\reg, :abs_g1_nc:\\imm\n"
|
|
#~ "\tmovk \\reg, :abs_g0_nc:\\imm\n"
|
|
#~ ".endm\n"
|
|
#~ "\n"
|
|
#~ ".set .L_MAIR_DEV_nGnRE,\t0x04\n"
|
|
#~ ".set .L_MAIR_MEM_WBWA,\t0xff\n"
|
|
#~ ".set .Lmairval, .L_MAIR_DEV_nGnRE | (.L_MAIR_MEM_WBWA << 8)\n"
|
|
#~ "\n"
|
|
#~ "/* TTBR0_EL1의 경우 4KiB 그래뉼 크기 */\n"
|
|
#~ ".set .L_TCR_TG0_4KB, 0x0 << 14\n"
|
|
#~ "/* TTBR1_EL1의 경우 4KiB 그래뉼 크기 */\n"
|
|
#~ ".set .L_TCR_TG1_4KB, 0x2 << 30\n"
|
|
#~ "/* TTBR1_EL1의 변환 테이블 워크를 사용 중지하여 변환 오류를 대신 발생시킵"
|
|
#~ "니다. */\n"
|
|
#~ ".set .L_TCR_EPD1, 0x1 << 23\n"
|
|
#~ "/* TTBR0_EL1의 변환 테이블 워크는 내부 공유가 가능합니다. */\n"
|
|
#~ ".set .L_TCR_SH_INNER, 0x3 << 12\n"
|
|
#~ "/*\n"
|
|
#~ " * TTBR0_EL1의 변환 테이블 워크는 외부 write-back read-allocate write-"
|
|
#~ "allocate\n"
|
|
#~ " * cacheable입니다.\n"
|
|
#~ " */\n"
|
|
#~ ".set .L_TCR_RGN_OWB, 0x1 << 10\n"
|
|
#~ "/*\n"
|
|
#~ " * TTBR0_EL1의 변환 테이블은 내부 write-back read-allocate write-"
|
|
#~ "allocate\n"
|
|
#~ " * cacheable 입니다.\n"
|
|
#~ " */\n"
|
|
#~ ".set .L_TCR_RGN_IWB, 0x1 << 8\n"
|
|
#~ "/* TTBR0_EL1의 크기 오프셋은 2**39바이트(512GiB)입니다. */\n"
|
|
#~ ".set .L_TCR_T0SZ_512, 64 - 39\n"
|
|
#~ ".set .Ltcrval, .L_TCR_TG0_4KB | .L_TCR_TG1_4KB | .L_TCR_EPD1 | ."
|
|
#~ "L_TCR_RGN_OWB\n"
|
|
#~ ".set .Ltcrval, .Ltcrval | .L_TCR_RGN_IWB | .L_TCR_SH_INNER | ."
|
|
#~ "L_TCR_T0SZ_512\n"
|
|
#~ "\n"
|
|
#~ "/* 1단계 명령 액세스 캐시 가능성은 영향을 받지 않습니다. */\n"
|
|
#~ ".set .L_SCTLR_ELx_I, 0x1 << 12\n"
|
|
#~ "/* SP가 16바이트 경계에 맞게 정렬되지 않으면 SP 정렬 오류가 발생합니다. "
|
|
#~ "*/\n"
|
|
#~ ".set .L_SCTLR_ELx_SA, 0x1 << 3\n"
|
|
#~ "/* 1단계 데이터 액세스 캐시 가능성은 영향을 받지 않습니다. */\n"
|
|
#~ ".set .L_SCTLR_ELx_C, 0x1 << 2\n"
|
|
#~ "/* EL0 및 EL1 1단계 MMU가 사용 설정됩니다. */\n"
|
|
#~ ".set .L_SCTLR_ELx_M, 0x1 << 0\n"
|
|
#~ "/* Privileged Access Never는 EL1에 예외를 적용할 때 변경되지 않습니다. "
|
|
#~ "*/\n"
|
|
#~ ".set .L_SCTLR_EL1_SPAN, 0x1 << 23\n"
|
|
#~ "/* SETEND 명령이 aarch32 모드의 EL0에서 사용 중지됩니다. */\n"
|
|
#~ ".set .L_SCTLR_EL1_SED, 0x1 << 8\n"
|
|
#~ "/* aarch32 모드에서는 EL0에서 다양한 IT 명령이 사용 중지됩니다. */\n"
|
|
#~ ".set .L_SCTLR_EL1_ITD, 0x1 << 7\n"
|
|
#~ ".set .L_SCTLR_EL1_RES1, (0x1 << 11) | (0x1 << 20) | (0x1 << 22) | (0x1 << "
|
|
#~ "28) | (0x1 << 29)\n"
|
|
#~ ".set .Lsctlrval, .L_SCTLR_ELx_M | .L_SCTLR_ELx_C | .L_SCTLR_ELx_SA | ."
|
|
#~ "L_SCTLR_EL1_ITD | .L_SCTLR_EL1_SED\n"
|
|
#~ ".set .Lsctlrval, .Lsctlrval | .L_SCTLR_ELx_I | .L_SCTLR_EL1_SPAN | ."
|
|
#~ "L_SCTLR_EL1_RES1\n"
|
|
#~ "\n"
|
|
#~ "/**\n"
|
|
#~ " * 이는 이미지의 일반 진입점입니다. 로드된 이미지를\n"
|
|
#~ "실행하기 위해 준비하는 데 필요한 작업을 실행합니다. 특히 x25 이상의 레지스"
|
|
#~ "터를 사용하여 bss 섹션을 0으로 설정하고\n"
|
|
#~ " * 스택을 준비하고 부동 소수점을 사용 설정하며 예외 벡터를 설정합니다. "
|
|
#~ "Rust 진입점\n"
|
|
#~ " * x0-x3을 보존합니다. 부팅 매개변수가 포함될 수 있기 때문입니다.\n"
|
|
#~ " */\n"
|
|
#~ ".section .init.entry, \"ax\"\n"
|
|
#~ ".global entry\n"
|
|
#~ "entry:\n"
|
|
#~ "\t/* MMU 및 캐시를 사용 설정할 준비가 된 메모리 관리 구성을 로드 및 적용합"
|
|
#~ "니다. */\n"
|
|
#~ "\tadrp x30, idmap\n"
|
|
#~ "\tmsr ttbr0_el1, x30\n"
|
|
#~ "\n"
|
|
#~ "\tmov_i x30, .Lmairval\n"
|
|
#~ "\tmsr mair_el1, x30\n"
|
|
#~ "\n"
|
|
#~ "\tmov_i x30, .Ltcrval\n"
|
|
#~ "\t/* 지원되는 PA 범위를 TCR_EL1.IPS로 복사합니다. */\n"
|
|
#~ "\tmrs x29, id_aa64mmfr0_el1\n"
|
|
#~ "\tbfi x30, x29, #32, #4\n"
|
|
#~ "\n"
|
|
#~ "\tmsr tcr_el1, x30\n"
|
|
#~ "\n"
|
|
#~ "\tmov_i x30, .Lsctlrval\n"
|
|
#~ "\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t 이 시점 전의 모든 내용이 완료되었는지 확인한 후 사용하기 전에 잠재적으"
|
|
#~ "로 오래된\n"
|
|
#~ "\t * 로컬 TLB 항목을 무효화합니다.\n"
|
|
#~ "\t */\n"
|
|
#~ "\tisb\n"
|
|
#~ "\ttlbi vmalle1\n"
|
|
#~ "\tic iallu\n"
|
|
#~ "\tdsb nsh\n"
|
|
#~ "\tisb\n"
|
|
#~ "\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * sctlr_el1을 구성하여 MMU와 캐시를 사용 설정하고 이 과정이 완료될 때까"
|
|
#~ "지 진행하지 않습니다.\n"
|
|
#~ "\t */\n"
|
|
#~ "\tmsr sctlr_el1, x30\n"
|
|
#~ "\tisb\n"
|
|
#~ "\n"
|
|
#~ "\t/* EL1에서 부동 소수점 액세스 트래핑을 사용 중지합니다. */\n"
|
|
#~ "\tmrs x30, cpacr_el1\n"
|
|
#~ "\torr x30, x30, #(0x3 << 20)\n"
|
|
#~ "\tmsr cpacr_el1, x30\n"
|
|
#~ "\tisb\n"
|
|
#~ "\n"
|
|
#~ "\t/* bss 섹션을 0으로 만듭니다. */\n"
|
|
#~ "\tadr_l x29, bss_begin\n"
|
|
#~ "\tadr_l x30, bss_end\n"
|
|
#~ "0:\tcmp x29, x30\n"
|
|
#~ "\tb.hs 1f\n"
|
|
#~ "\tstp xzr, xzr, [x29], #16\n"
|
|
#~ "\tb 0b\n"
|
|
#~ "\n"
|
|
#~ "1:\t/* 스택을 준비합니다. */\n"
|
|
#~ "\tadr_l x30, boot_stack_end\n"
|
|
#~ "\tmov sp, x30\n"
|
|
#~ "\n"
|
|
#~ "\t/* 예외 벡터를 설정합니다. */\n"
|
|
#~ "\tadr x30, vector_table_el1\n"
|
|
#~ "\tmsr vbar_el1, x30\n"
|
|
#~ "\n"
|
|
#~ "\t/* Rust 코드를 호출합니다. */\n"
|
|
#~ "\tbl main\n"
|
|
#~ "\n"
|
|
#~ "\t/* 루프가 인터럽트를 기다리고 있습니다. */\n"
|
|
#~ "2:\twfi\n"
|
|
#~ "\tb 2b\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```armasm\n"
|
|
#~ "/*\n"
|
|
#~ " * Copyright 2023 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"
|
|
#~ " * https://www.apache.org/licenses/LICENSE-2.0\n"
|
|
#~ " *\n"
|
|
#~ " * Unless required by applicable law or agreed to in writing, software\n"
|
|
#~ " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
|
#~ " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
|
|
#~ "implied.\n"
|
|
#~ " * See the License for the specific language governing permissions and\n"
|
|
#~ " * limitations under the License.\n"
|
|
#~ " */\n"
|
|
#~ "\n"
|
|
#~ "/**\n"
|
|
#~ " * Saves the volatile registers onto the stack. This currently takes 14\n"
|
|
#~ " * instructions, so it can be used in exception handlers with 18 "
|
|
#~ "instructions\n"
|
|
#~ " * left.\n"
|
|
#~ " *\n"
|
|
#~ " * On return, x0 and x1 are initialised to elr_el2 and spsr_el2 "
|
|
#~ "respectively,\n"
|
|
#~ " * which can be used as the first and second arguments of a subsequent "
|
|
#~ "call.\n"
|
|
#~ " */\n"
|
|
#~ ".macro save_volatile_to_stack\n"
|
|
#~ "\t/* Reserve stack space and save registers x0-x18, x29 & x30. */\n"
|
|
#~ "\tstp x0, x1, [sp, #-(8 * 24)]!\n"
|
|
#~ "\tstp x2, x3, [sp, #8 * 2]\n"
|
|
#~ "\tstp x4, x5, [sp, #8 * 4]\n"
|
|
#~ "\tstp x6, x7, [sp, #8 * 6]\n"
|
|
#~ "\tstp x8, x9, [sp, #8 * 8]\n"
|
|
#~ "\tstp x10, x11, [sp, #8 * 10]\n"
|
|
#~ "\tstp x12, x13, [sp, #8 * 12]\n"
|
|
#~ "\tstp x14, x15, [sp, #8 * 14]\n"
|
|
#~ "\tstp x16, x17, [sp, #8 * 16]\n"
|
|
#~ "\tstr x18, [sp, #8 * 18]\n"
|
|
#~ "\tstp x29, x30, [sp, #8 * 20]\n"
|
|
#~ "\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * Save elr_el1 & spsr_el1. This such that we can take nested "
|
|
#~ "exception\n"
|
|
#~ "\t * and still be able to unwind.\n"
|
|
#~ "\t */\n"
|
|
#~ "\tmrs x0, elr_el1\n"
|
|
#~ "\tmrs x1, spsr_el1\n"
|
|
#~ "\tstp x0, x1, [sp, #8 * 22]\n"
|
|
#~ ".endm\n"
|
|
#~ "\n"
|
|
#~ "/**\n"
|
|
#~ " * Restores the volatile registers from the stack. This currently takes "
|
|
#~ "14\n"
|
|
#~ " * instructions, so it can be used in exception handlers while still "
|
|
#~ "leaving 18\n"
|
|
#~ " * instructions left; if paired with save_volatile_to_stack, there are 4\n"
|
|
#~ " * instructions to spare.\n"
|
|
#~ " */\n"
|
|
#~ ".macro restore_volatile_from_stack\n"
|
|
#~ "\t/* Restore registers x2-x18, x29 & x30. */\n"
|
|
#~ "\tldp x2, x3, [sp, #8 * 2]\n"
|
|
#~ "\tldp x4, x5, [sp, #8 * 4]\n"
|
|
#~ "\tldp x6, x7, [sp, #8 * 6]\n"
|
|
#~ "\tldp x8, x9, [sp, #8 * 8]\n"
|
|
#~ "\tldp x10, x11, [sp, #8 * 10]\n"
|
|
#~ "\tldp x12, x13, [sp, #8 * 12]\n"
|
|
#~ "\tldp x14, x15, [sp, #8 * 14]\n"
|
|
#~ "\tldp x16, x17, [sp, #8 * 16]\n"
|
|
#~ "\tldr x18, [sp, #8 * 18]\n"
|
|
#~ "\tldp x29, x30, [sp, #8 * 20]\n"
|
|
#~ "\n"
|
|
#~ "\t/* Restore registers elr_el1 & spsr_el1, using x0 & x1 as scratch. */\n"
|
|
#~ "\tldp x0, x1, [sp, #8 * 22]\n"
|
|
#~ "\tmsr elr_el1, x0\n"
|
|
#~ "\tmsr spsr_el1, x1\n"
|
|
#~ "\n"
|
|
#~ "\t/* Restore x0 & x1, and release stack space. */\n"
|
|
#~ "\tldp x0, x1, [sp], #8 * 24\n"
|
|
#~ ".endm\n"
|
|
#~ "\n"
|
|
#~ "/**\n"
|
|
#~ " * This is a generic handler for exceptions taken at the current EL while "
|
|
#~ "using\n"
|
|
#~ " * SP0. It behaves similarly to the SPx case by first switching to SPx, "
|
|
#~ "doing\n"
|
|
#~ " * the work, then switching back to SP0 before returning.\n"
|
|
#~ " *\n"
|
|
#~ " * Switching to SPx and calling the Rust handler takes 16 instructions. "
|
|
#~ "To\n"
|
|
#~ " * restore and return we need an additional 16 instructions, so we can "
|
|
#~ "implement\n"
|
|
#~ " * the whole handler within the allotted 32 instructions.\n"
|
|
#~ " */\n"
|
|
#~ ".macro current_exception_sp0 handler:req\n"
|
|
#~ "\tmsr spsel, #1\n"
|
|
#~ "\tsave_volatile_to_stack\n"
|
|
#~ "\tbl \\handler\n"
|
|
#~ "\trestore_volatile_from_stack\n"
|
|
#~ "\tmsr spsel, #0\n"
|
|
#~ "\teret\n"
|
|
#~ ".endm\n"
|
|
#~ "\n"
|
|
#~ "/**\n"
|
|
#~ " * This is a generic handler for exceptions taken at the current EL while "
|
|
#~ "using\n"
|
|
#~ " * SPx. It saves volatile registers, calls the Rust handler, restores "
|
|
#~ "volatile\n"
|
|
#~ " * registers, then returns.\n"
|
|
#~ " *\n"
|
|
#~ " * This also works for exceptions taken from EL0, if we don't care about\n"
|
|
#~ " * non-volatile registers.\n"
|
|
#~ " *\n"
|
|
#~ " * Saving state and jumping to the Rust handler takes 15 instructions, "
|
|
#~ "and\n"
|
|
#~ " * restoring and returning also takes 15 instructions, so we can fit the "
|
|
#~ "whole\n"
|
|
#~ " * handler in 30 instructions, under the limit of 32.\n"
|
|
#~ " */\n"
|
|
#~ ".macro current_exception_spx handler:req\n"
|
|
#~ "\tsave_volatile_to_stack\n"
|
|
#~ "\tbl \\handler\n"
|
|
#~ "\trestore_volatile_from_stack\n"
|
|
#~ "\teret\n"
|
|
#~ ".endm\n"
|
|
#~ "\n"
|
|
#~ ".section .text.vector_table_el1, \"ax\"\n"
|
|
#~ ".global vector_table_el1\n"
|
|
#~ ".balign 0x800\n"
|
|
#~ "vector_table_el1:\n"
|
|
#~ "sync_cur_sp0:\n"
|
|
#~ "\tcurrent_exception_sp0 sync_exception_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "irq_cur_sp0:\n"
|
|
#~ "\tcurrent_exception_sp0 irq_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "fiq_cur_sp0:\n"
|
|
#~ "\tcurrent_exception_sp0 fiq_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "serr_cur_sp0:\n"
|
|
#~ "\tcurrent_exception_sp0 serr_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "sync_cur_spx:\n"
|
|
#~ "\tcurrent_exception_spx sync_exception_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "irq_cur_spx:\n"
|
|
#~ "\tcurrent_exception_spx irq_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "fiq_cur_spx:\n"
|
|
#~ "\tcurrent_exception_spx fiq_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "serr_cur_spx:\n"
|
|
#~ "\tcurrent_exception_spx serr_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "sync_lower_64:\n"
|
|
#~ "\tcurrent_exception_spx sync_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "irq_lower_64:\n"
|
|
#~ "\tcurrent_exception_spx irq_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "fiq_lower_64:\n"
|
|
#~ "\tcurrent_exception_spx fiq_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "serr_lower_64:\n"
|
|
#~ "\tcurrent_exception_spx serr_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "sync_lower_32:\n"
|
|
#~ "\tcurrent_exception_spx sync_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "irq_lower_32:\n"
|
|
#~ "\tcurrent_exception_spx irq_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "fiq_lower_32:\n"
|
|
#~ "\tcurrent_exception_spx fiq_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "serr_lower_32:\n"
|
|
#~ "\tcurrent_exception_spx serr_lower\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```armasm\n"
|
|
#~ "/*\n"
|
|
#~ " * Copyright 2023 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"
|
|
#~ " * https://www.apache.org/licenses/LICENSE-2.0\n"
|
|
#~ " *\n"
|
|
#~ " * Unless required by applicable law or agreed to in writing, software\n"
|
|
#~ " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
|
#~ " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
|
|
#~ "implied.\n"
|
|
#~ " * See the License for the specific language governing permissions and\n"
|
|
#~ " * limitations under the License.\n"
|
|
#~ " */\n"
|
|
#~ "\n"
|
|
#~ "/**\n"
|
|
#~ " * Saves the volatile registers onto the stack. This currently takes 14\n"
|
|
#~ " * instructions, so it can be used in exception handlers with 18 "
|
|
#~ "instructions\n"
|
|
#~ " * left.\n"
|
|
#~ " *\n"
|
|
#~ " * On return, x0 and x1 are initialised to elr_el2 and spsr_el2 "
|
|
#~ "respectively,\n"
|
|
#~ " * which can be used as the first and second arguments of a subsequent "
|
|
#~ "call.\n"
|
|
#~ " */\n"
|
|
#~ ".macro save_volatile_to_stack\n"
|
|
#~ "\t/* Reserve stack space and save registers x0-x18, x29 & x30. */\n"
|
|
#~ "\tstp x0, x1, [sp, #-(8 * 24)]!\n"
|
|
#~ "\tstp x2, x3, [sp, #8 * 2]\n"
|
|
#~ "\tstp x4, x5, [sp, #8 * 4]\n"
|
|
#~ "\tstp x6, x7, [sp, #8 * 6]\n"
|
|
#~ "\tstp x8, x9, [sp, #8 * 8]\n"
|
|
#~ "\tstp x10, x11, [sp, #8 * 10]\n"
|
|
#~ "\tstp x12, x13, [sp, #8 * 12]\n"
|
|
#~ "\tstp x14, x15, [sp, #8 * 14]\n"
|
|
#~ "\tstp x16, x17, [sp, #8 * 16]\n"
|
|
#~ "\tstr x18, [sp, #8 * 18]\n"
|
|
#~ "\tstp x29, x30, [sp, #8 * 20]\n"
|
|
#~ "\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * Save elr_el1 & spsr_el1. This such that we can take nested "
|
|
#~ "exception\n"
|
|
#~ "\t * and still be able to unwind.\n"
|
|
#~ "\t */\n"
|
|
#~ "\tmrs x0, elr_el1\n"
|
|
#~ "\tmrs x1, spsr_el1\n"
|
|
#~ "\tstp x0, x1, [sp, #8 * 22]\n"
|
|
#~ ".endm\n"
|
|
#~ "\n"
|
|
#~ "/**\n"
|
|
#~ " * Restores the volatile registers from the stack. This currently takes "
|
|
#~ "14\n"
|
|
#~ " * instructions, so it can be used in exception handlers while still "
|
|
#~ "leaving 18\n"
|
|
#~ " * instructions left; if paired with save_volatile_to_stack, there are 4\n"
|
|
#~ " * instructions to spare.\n"
|
|
#~ " */\n"
|
|
#~ ".macro restore_volatile_from_stack\n"
|
|
#~ "\t/* Restore registers x2-x18, x29 & x30. */\n"
|
|
#~ "\tldp x2, x3, [sp, #8 * 2]\n"
|
|
#~ "\tldp x4, x5, [sp, #8 * 4]\n"
|
|
#~ "\tldp x6, x7, [sp, #8 * 6]\n"
|
|
#~ "\tldp x8, x9, [sp, #8 * 8]\n"
|
|
#~ "\tldp x10, x11, [sp, #8 * 10]\n"
|
|
#~ "\tldp x12, x13, [sp, #8 * 12]\n"
|
|
#~ "\tldp x14, x15, [sp, #8 * 14]\n"
|
|
#~ "\tldp x16, x17, [sp, #8 * 16]\n"
|
|
#~ "\tldr x18, [sp, #8 * 18]\n"
|
|
#~ "\tldp x29, x30, [sp, #8 * 20]\n"
|
|
#~ "\n"
|
|
#~ "\t/* Restore registers elr_el1 & spsr_el1, using x0 & x1 as scratch. */\n"
|
|
#~ "\tldp x0, x1, [sp, #8 * 22]\n"
|
|
#~ "\tmsr elr_el1, x0\n"
|
|
#~ "\tmsr spsr_el1, x1\n"
|
|
#~ "\n"
|
|
#~ "\t/* Restore x0 & x1, and release stack space. */\n"
|
|
#~ "\tldp x0, x1, [sp], #8 * 24\n"
|
|
#~ ".endm\n"
|
|
#~ "\n"
|
|
#~ "/**\n"
|
|
#~ " * This is a generic handler for exceptions taken at the current EL while "
|
|
#~ "using\n"
|
|
#~ " * SP0. It behaves similarly to the SPx case by first switching to SPx, "
|
|
#~ "doing\n"
|
|
#~ " * the work, then switching back to SP0 before returning.\n"
|
|
#~ " *\n"
|
|
#~ " * Switching to SPx and calling the Rust handler takes 16 instructions. "
|
|
#~ "To\n"
|
|
#~ " * restore and return we need an additional 16 instructions, so we can "
|
|
#~ "implement\n"
|
|
#~ " * the whole handler within the allotted 32 instructions.\n"
|
|
#~ " */\n"
|
|
#~ ".macro current_exception_sp0 handler:req\n"
|
|
#~ "\tmsr spsel, #1\n"
|
|
#~ "\tsave_volatile_to_stack\n"
|
|
#~ "\tbl \\handler\n"
|
|
#~ "\trestore_volatile_from_stack\n"
|
|
#~ "\tmsr spsel, #0\n"
|
|
#~ "\teret\n"
|
|
#~ ".endm\n"
|
|
#~ "\n"
|
|
#~ "/**\n"
|
|
#~ " * This is a generic handler for exceptions taken at the current EL while "
|
|
#~ "using\n"
|
|
#~ " * SPx. It saves volatile registers, calls the Rust handler, restores "
|
|
#~ "volatile\n"
|
|
#~ " * registers, then returns.\n"
|
|
#~ " *\n"
|
|
#~ " * This also works for exceptions taken from EL0, if we don't care about\n"
|
|
#~ " * non-volatile registers.\n"
|
|
#~ " *\n"
|
|
#~ " * Saving state and jumping to the Rust handler takes 15 instructions, "
|
|
#~ "and\n"
|
|
#~ " * restoring and returning also takes 15 instructions, so we can fit the "
|
|
#~ "whole\n"
|
|
#~ " * handler in 30 instructions, under the limit of 32.\n"
|
|
#~ " */\n"
|
|
#~ ".macro current_exception_spx handler:req\n"
|
|
#~ "\tsave_volatile_to_stack\n"
|
|
#~ "\tbl \\handler\n"
|
|
#~ "\trestore_volatile_from_stack\n"
|
|
#~ "\teret\n"
|
|
#~ ".endm\n"
|
|
#~ "\n"
|
|
#~ ".section .text.vector_table_el1, \"ax\"\n"
|
|
#~ ".global vector_table_el1\n"
|
|
#~ ".balign 0x800\n"
|
|
#~ "vector_table_el1:\n"
|
|
#~ "sync_cur_sp0:\n"
|
|
#~ "\tcurrent_exception_sp0 sync_exception_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "irq_cur_sp0:\n"
|
|
#~ "\tcurrent_exception_sp0 irq_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "fiq_cur_sp0:\n"
|
|
#~ "\tcurrent_exception_sp0 fiq_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "serr_cur_sp0:\n"
|
|
#~ "\tcurrent_exception_sp0 serr_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "sync_cur_spx:\n"
|
|
#~ "\tcurrent_exception_spx sync_exception_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "irq_cur_spx:\n"
|
|
#~ "\tcurrent_exception_spx irq_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "fiq_cur_spx:\n"
|
|
#~ "\tcurrent_exception_spx fiq_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "serr_cur_spx:\n"
|
|
#~ "\tcurrent_exception_spx serr_current\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "sync_lower_64:\n"
|
|
#~ "\tcurrent_exception_spx sync_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "irq_lower_64:\n"
|
|
#~ "\tcurrent_exception_spx irq_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "fiq_lower_64:\n"
|
|
#~ "\tcurrent_exception_spx fiq_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "serr_lower_64:\n"
|
|
#~ "\tcurrent_exception_spx serr_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "sync_lower_32:\n"
|
|
#~ "\tcurrent_exception_spx sync_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "irq_lower_32:\n"
|
|
#~ "\tcurrent_exception_spx irq_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "fiq_lower_32:\n"
|
|
#~ "\tcurrent_exception_spx fiq_lower\n"
|
|
#~ "\n"
|
|
#~ ".balign 0x80\n"
|
|
#~ "serr_lower_32:\n"
|
|
#~ "\tcurrent_exception_spx serr_lower\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```armasm\n"
|
|
#~ "/*\n"
|
|
#~ " * Copyright 2023 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"
|
|
#~ " * https://www.apache.org/licenses/LICENSE-2.0\n"
|
|
#~ " *\n"
|
|
#~ " * Unless required by applicable law or agreed to in writing, software\n"
|
|
#~ " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
|
#~ " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
|
|
#~ "implied.\n"
|
|
#~ " * See the License for the specific language governing permissions and\n"
|
|
#~ " * limitations under the License.\n"
|
|
#~ " */\n"
|
|
#~ "\n"
|
|
#~ ".set .L_TT_TYPE_BLOCK, 0x1\n"
|
|
#~ ".set .L_TT_TYPE_PAGE, 0x3\n"
|
|
#~ ".set .L_TT_TYPE_TABLE, 0x3\n"
|
|
#~ "\n"
|
|
#~ "/* Access flag. */\n"
|
|
#~ ".set .L_TT_AF, 0x1 << 10\n"
|
|
#~ "/* Not global. */\n"
|
|
#~ ".set .L_TT_NG, 0x1 << 11\n"
|
|
#~ ".set .L_TT_XN, 0x3 << 53\n"
|
|
#~ "\n"
|
|
#~ ".set .L_TT_MT_DEV, 0x0 << 2\t\t\t// MAIR #0 (DEV_nGnRE)\n"
|
|
#~ ".set .L_TT_MT_MEM, (0x1 << 2) | (0x3 << 8)\t// MAIR #1 (MEM_WBWA), inner "
|
|
#~ "shareable\n"
|
|
#~ "\n"
|
|
#~ ".set .L_BLOCK_DEV, .L_TT_TYPE_BLOCK | .L_TT_MT_DEV | .L_TT_AF | .L_TT_XN\n"
|
|
#~ ".set .L_BLOCK_MEM, .L_TT_TYPE_BLOCK | .L_TT_MT_MEM | .L_TT_AF | .L_TT_NG\n"
|
|
#~ "\n"
|
|
#~ ".section \".rodata.idmap\", \"a\", %progbits\n"
|
|
#~ ".global idmap\n"
|
|
#~ ".align 12\n"
|
|
#~ "idmap:\n"
|
|
#~ "\t/* level 1 */\n"
|
|
#~ "\t.quad\t\t.L_BLOCK_DEV | 0x0\t\t // 1 GiB of device mappings\n"
|
|
#~ "\t.quad\t\t.L_BLOCK_MEM | 0x40000000\t// 1 GiB of DRAM\n"
|
|
#~ "\t.fill\t\t254, 8, 0x0\t\t\t// 254 GiB of unmapped VA space\n"
|
|
#~ "\t.quad\t\t.L_BLOCK_DEV | 0x4000000000 // 1 GiB of device mappings\n"
|
|
#~ "\t.fill\t\t255, 8, 0x0\t\t\t// 255 GiB of remaining VA space\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```armasm\n"
|
|
#~ "/*\n"
|
|
#~ " * Copyright 2023 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"
|
|
#~ " * https://www.apache.org/licenses/LICENSE-2.0\n"
|
|
#~ " *\n"
|
|
#~ " * Unless required by applicable law or agreed to in writing, software\n"
|
|
#~ " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
|
#~ " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
|
|
#~ "implied.\n"
|
|
#~ " * See the License for the specific language governing permissions and\n"
|
|
#~ " * limitations under the License.\n"
|
|
#~ " */\n"
|
|
#~ "\n"
|
|
#~ ".set .L_TT_TYPE_BLOCK, 0x1\n"
|
|
#~ ".set .L_TT_TYPE_PAGE, 0x3\n"
|
|
#~ ".set .L_TT_TYPE_TABLE, 0x3\n"
|
|
#~ "\n"
|
|
#~ "/* Access flag. */\n"
|
|
#~ ".set .L_TT_AF, 0x1 << 10\n"
|
|
#~ "/* Not global. */\n"
|
|
#~ ".set .L_TT_NG, 0x1 << 11\n"
|
|
#~ ".set .L_TT_XN, 0x3 << 53\n"
|
|
#~ "\n"
|
|
#~ ".set .L_TT_MT_DEV, 0x0 << 2\t\t\t// MAIR #0 (DEV_nGnRE)\n"
|
|
#~ ".set .L_TT_MT_MEM, (0x1 << 2) | (0x3 << 8)\t// MAIR #1 (MEM_WBWA), inner "
|
|
#~ "shareable\n"
|
|
#~ "\n"
|
|
#~ ".set .L_BLOCK_DEV, .L_TT_TYPE_BLOCK | .L_TT_MT_DEV | .L_TT_AF | .L_TT_XN\n"
|
|
#~ ".set .L_BLOCK_MEM, .L_TT_TYPE_BLOCK | .L_TT_MT_MEM | .L_TT_AF | .L_TT_NG\n"
|
|
#~ "\n"
|
|
#~ ".section \".rodata.idmap\", \"a\", %progbits\n"
|
|
#~ ".global idmap\n"
|
|
#~ ".align 12\n"
|
|
#~ "idmap:\n"
|
|
#~ "\t/* level 1 */\n"
|
|
#~ "\t.quad\t\t.L_BLOCK_DEV | 0x0\t\t // 1 GiB of device mappings\n"
|
|
#~ "\t.quad\t\t.L_BLOCK_MEM | 0x40000000\t// 1 GiB of DRAM\n"
|
|
#~ "\t.fill\t\t254, 8, 0x0\t\t\t// 254 GiB of unmapped VA space\n"
|
|
#~ "\t.quad\t\t.L_BLOCK_DEV | 0x4000000000 // 1 GiB of device mappings\n"
|
|
#~ "\t.fill\t\t255, 8, 0x0\t\t\t// 255 GiB of remaining VA space\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```ld\n"
|
|
#~ "/*\n"
|
|
#~ " * Copyright 2023 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"
|
|
#~ " * https://www.apache.org/licenses/LICENSE-2.0\n"
|
|
#~ " *\n"
|
|
#~ " * Unless required by applicable law or agreed to in writing, software\n"
|
|
#~ " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
|
#~ " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
|
|
#~ "implied.\n"
|
|
#~ " * See the License for the specific language governing permissions and\n"
|
|
#~ " * limitations under the License.\n"
|
|
#~ " */\n"
|
|
#~ "\n"
|
|
#~ "/*\n"
|
|
#~ " * Code will start running at this symbol which is placed at the start of "
|
|
#~ "the\n"
|
|
#~ " * image.\n"
|
|
#~ " */\n"
|
|
#~ "ENTRY(entry)\n"
|
|
#~ "\n"
|
|
#~ "MEMORY\n"
|
|
#~ "{\n"
|
|
#~ "\timage : ORIGIN = 0x40080000, LENGTH = 2M\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "SECTIONS\n"
|
|
#~ "{\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * Collect together the code.\n"
|
|
#~ "\t */\n"
|
|
#~ "\t.init : ALIGN(4096) {\n"
|
|
#~ "\t\ttext_begin = .;\n"
|
|
#~ "\t\t*(.init.entry)\n"
|
|
#~ "\t\t*(.init.*)\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\t.text : {\n"
|
|
#~ "\t\t*(.text.*)\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\ttext_end = .;\n"
|
|
#~ "\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * Collect together read-only data.\n"
|
|
#~ "\t */\n"
|
|
#~ "\t.rodata : ALIGN(4096) {\n"
|
|
#~ "\t\trodata_begin = .;\n"
|
|
#~ "\t\t*(.rodata.*)\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\t.got : {\n"
|
|
#~ "\t\t*(.got)\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\trodata_end = .;\n"
|
|
#~ "\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * Collect together the read-write data including .bss at the end "
|
|
#~ "which\n"
|
|
#~ "\t * will be zero'd by the entry code.\n"
|
|
#~ "\t */\n"
|
|
#~ "\t.data : ALIGN(4096) {\n"
|
|
#~ "\t\tdata_begin = .;\n"
|
|
#~ "\t\t*(.data.*)\n"
|
|
#~ "\t\t/*\n"
|
|
#~ "\t\t * The entry point code assumes that .data is a multiple of 32\n"
|
|
#~ "\t\t * bytes long.\n"
|
|
#~ "\t\t */\n"
|
|
#~ "\t\t. = ALIGN(32);\n"
|
|
#~ "\t\tdata_end = .;\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\n"
|
|
#~ "\t/* Everything beyond this point will not be included in the binary. */\n"
|
|
#~ "\tbin_end = .;\n"
|
|
#~ "\n"
|
|
#~ "\t/* The entry point code assumes that .bss is 16-byte aligned. */\n"
|
|
#~ "\t.bss : ALIGN(16) {\n"
|
|
#~ "\t\tbss_begin = .;\n"
|
|
#~ "\t\t*(.bss.*)\n"
|
|
#~ "\t\t*(COMMON)\n"
|
|
#~ "\t\t. = ALIGN(16);\n"
|
|
#~ "\t\tbss_end = .;\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\n"
|
|
#~ "\t.stack (NOLOAD) : ALIGN(4096) {\n"
|
|
#~ "\t\tboot_stack_begin = .;\n"
|
|
#~ "\t\t. += 40 * 4096;\n"
|
|
#~ "\t\t. = ALIGN(4096);\n"
|
|
#~ "\t\tboot_stack_end = .;\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\n"
|
|
#~ "\t. = ALIGN(4K);\n"
|
|
#~ "\tPROVIDE(dma_region = .);\n"
|
|
#~ "\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * Remove unused sections from the image.\n"
|
|
#~ "\t */\n"
|
|
#~ "\t/DISCARD/ : {\n"
|
|
#~ "\t\t/* The image loads itself so doesn't need these sections. */\n"
|
|
#~ "\t\t*(.gnu.hash)\n"
|
|
#~ "\t\t*(.hash)\n"
|
|
#~ "\t\t*(.interp)\n"
|
|
#~ "\t\t*(.eh_frame_hdr)\n"
|
|
#~ "\t\t*(.eh_frame)\n"
|
|
#~ "\t\t*(.note.gnu.build-id)\n"
|
|
#~ "\t}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```ld\n"
|
|
#~ "/*\n"
|
|
#~ " * Copyright 2023 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"
|
|
#~ " * https://www.apache.org/licenses/LICENSE-2.0\n"
|
|
#~ " *\n"
|
|
#~ " * Unless required by applicable law or agreed to in writing, software\n"
|
|
#~ " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
|
#~ " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
|
|
#~ "implied.\n"
|
|
#~ " * See the License for the specific language governing permissions and\n"
|
|
#~ " * limitations under the License.\n"
|
|
#~ " */\n"
|
|
#~ "\n"
|
|
#~ "/*\n"
|
|
#~ " * Code will start running at this symbol which is placed at the start of "
|
|
#~ "the\n"
|
|
#~ " * image.\n"
|
|
#~ " */\n"
|
|
#~ "ENTRY(entry)\n"
|
|
#~ "\n"
|
|
#~ "MEMORY\n"
|
|
#~ "{\n"
|
|
#~ "\timage : ORIGIN = 0x40080000, LENGTH = 2M\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "SECTIONS\n"
|
|
#~ "{\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * Collect together the code.\n"
|
|
#~ "\t */\n"
|
|
#~ "\t.init : ALIGN(4096) {\n"
|
|
#~ "\t\ttext_begin = .;\n"
|
|
#~ "\t\t*(.init.entry)\n"
|
|
#~ "\t\t*(.init.*)\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\t.text : {\n"
|
|
#~ "\t\t*(.text.*)\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\ttext_end = .;\n"
|
|
#~ "\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * Collect together read-only data.\n"
|
|
#~ "\t */\n"
|
|
#~ "\t.rodata : ALIGN(4096) {\n"
|
|
#~ "\t\trodata_begin = .;\n"
|
|
#~ "\t\t*(.rodata.*)\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\t.got : {\n"
|
|
#~ "\t\t*(.got)\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\trodata_end = .;\n"
|
|
#~ "\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * Collect together the read-write data including .bss at the end "
|
|
#~ "which\n"
|
|
#~ "\t * will be zero'd by the entry code.\n"
|
|
#~ "\t */\n"
|
|
#~ "\t.data : ALIGN(4096) {\n"
|
|
#~ "\t\tdata_begin = .;\n"
|
|
#~ "\t\t*(.data.*)\n"
|
|
#~ "\t\t/*\n"
|
|
#~ "\t\t * The entry point code assumes that .data is a multiple of 32\n"
|
|
#~ "\t\t * bytes long.\n"
|
|
#~ "\t\t */\n"
|
|
#~ "\t\t. = ALIGN(32);\n"
|
|
#~ "\t\tdata_end = .;\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\n"
|
|
#~ "\t/* Everything beyond this point will not be included in the binary. */\n"
|
|
#~ "\tbin_end = .;\n"
|
|
#~ "\n"
|
|
#~ "\t/* The entry point code assumes that .bss is 16-byte aligned. */\n"
|
|
#~ "\t.bss : ALIGN(16) {\n"
|
|
#~ "\t\tbss_begin = .;\n"
|
|
#~ "\t\t*(.bss.*)\n"
|
|
#~ "\t\t*(COMMON)\n"
|
|
#~ "\t\t. = ALIGN(16);\n"
|
|
#~ "\t\tbss_end = .;\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\n"
|
|
#~ "\t.stack (NOLOAD) : ALIGN(4096) {\n"
|
|
#~ "\t\tboot_stack_begin = .;\n"
|
|
#~ "\t\t. += 40 * 4096;\n"
|
|
#~ "\t\t. = ALIGN(4096);\n"
|
|
#~ "\t\tboot_stack_end = .;\n"
|
|
#~ "\t} >image\n"
|
|
#~ "\n"
|
|
#~ "\t. = ALIGN(4K);\n"
|
|
#~ "\tPROVIDE(dma_region = .);\n"
|
|
#~ "\n"
|
|
#~ "\t/*\n"
|
|
#~ "\t * Remove unused sections from the image.\n"
|
|
#~ "\t */\n"
|
|
#~ "\t/DISCARD/ : {\n"
|
|
#~ "\t\t/* The image loads itself so doesn't need these sections. */\n"
|
|
#~ "\t\t*(.gnu.hash)\n"
|
|
#~ "\t\t*(.hash)\n"
|
|
#~ "\t\t*(.interp)\n"
|
|
#~ "\t\t*(.eh_frame_hdr)\n"
|
|
#~ "\t\t*(.eh_frame)\n"
|
|
#~ "\t\t*(.note.gnu.build-id)\n"
|
|
#~ "\t}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "# Copyright 2023 Google LLC"
|
|
#~ msgstr "# Copyright 2023 Google LLC"
|
|
|
|
#~ msgid "$(shell uname -s)"
|
|
#~ msgstr "$(shell uname -s)"
|
|
|
|
#, fuzzy
|
|
#~ msgid "aarch64-linux-gnu"
|
|
#~ msgstr "aarch64-paging"
|
|
|
|
#~ msgid "stdio -display none -kernel $< -s"
|
|
#~ msgstr "stdio -display none -kernel $< -s"
|
|
|
|
#~ msgid "cargo clean"
|
|
#~ msgstr "cargo clean"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "Notice that the thread is stopped before it reaches 10 --- the main "
|
|
#~ "thread is not waiting."
|
|
#~ msgstr ""
|
|
#~ "메인 스레드가 자식 스레드를 기다리지 않기 때문에 자식 스레드의 for문은 10"
|
|
#~ "까지 가지 않습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "When you await a future, all local variables (that would ordinarily be "
|
|
#~ "stored on a stack frame) are instead stored in the Future for the current "
|
|
#~ "async block. If your future has pointers to data on the stack, those "
|
|
#~ "pointers might get invalidated. This is unsafe."
|
|
#~ msgstr ""
|
|
#~ "Future에 대해 `await`를 호출하여 그 future가 준비되기를 기다릴 때, 모든 로"
|
|
#~ "컬 변수(일반적으로 스택 프레임에 저장됨)는 그 future객체 안에 저장됩니"
|
|
#~ "다. 만약 그 future에 스택에 있는 어떤 데이터로의 포인터가 있으면 이러한 "
|
|
#~ "포인터는 올바르지 않을 수 있습니다. 안전하지 않습니다."
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "Therefore, you must guarantee that the addresses your future points to "
|
|
#~ "don't change. That is why we need to \"pin\" futures. Using the same "
|
|
#~ "future repeatedly in a `select!` often leads to issues with pinned values."
|
|
#~ msgstr ""
|
|
#~ "따라서 future가 가리키는 주소가 변경되지 않도록 해야 합니다. 이것이 future"
|
|
#~ "를 `pin`(고정)해야 하는 이유입니다. `select!`에서 동일한 future를 반복적으"
|
|
#~ "로 사용하면 고정 값 문제가 발생하는 경우가 많습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Async methods in traits are not yet supported in the stable channel ([An "
|
|
#~ "experimental feature exists in nightly and should be stabilized in the "
|
|
#~ "mid term.](https://blog.rust-lang.org/inside-rust/2022/11/17/async-fn-in-"
|
|
#~ "trait-nightly.html))"
|
|
#~ msgstr ""
|
|
#~ "트레잇에 async 메소드를 추가하는 것은 아직 안정화 버전 채널에서 지원되지 "
|
|
#~ "않습니다([실험용 기능은 nightly에 존재하며 조만간 안정화 될 것입니다]"
|
|
#~ "(https://blog.rust-lang.org/inside-rust/2022/11/17/async-fn-in-trait-"
|
|
#~ "nightly.html))."
|
|
|
|
#~ msgid ""
|
|
#~ "// Add a delay before picking the second fork to allow the execution\n"
|
|
#~ " // to transfer to another task\n"
|
|
#~ msgstr ""
|
|
#~ "// 두 번째 포크를 선택하기 전에 다른 작업으로 전송하는 실행을 허용하도록\n"
|
|
#~ " // 지연을 추가합니다.\n"
|
|
|
|
#~ 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"
|
|
#~ msgstr ""
|
|
#~ "// 교착 상태를 방지하려면 어딘가에서\n"
|
|
#~ " // 대칭을 중단시켜야 합니다. 이렇게 하면 둘 중 어느 하나라도 초기"
|
|
#~ "화하지 않고\n"
|
|
#~ " // 포크가 교체됩니다.\n"
|
|
|
|
#~ msgid "Small Example"
|
|
#~ msgstr "작은 예제"
|
|
|
|
#~ msgid "Why Rust?"
|
|
#~ msgstr "러스트를 써야하는 이유"
|
|
|
|
#~ msgid "Compile Time Guarantees"
|
|
#~ msgstr "컴파일 시 보장되는 것들"
|
|
|
|
#~ msgid "Runtime Guarantees"
|
|
#~ msgstr "런타임 시 보장되는 것들"
|
|
|
|
#~ msgid "Modern Features"
|
|
#~ msgstr "현대적인 특징"
|
|
|
|
#~ msgid "Basic Syntax"
|
|
#~ msgstr "기본 문법"
|
|
|
|
#~ msgid "String vs str"
|
|
#~ msgstr "String과 str"
|
|
|
|
#~ msgid "Overloading"
|
|
#~ msgstr "오버로딩"
|
|
|
|
#~ msgid "Arrays and for Loops"
|
|
#~ msgstr "배열과 for 반복문"
|
|
|
|
#~ msgid "Stack vs Heap"
|
|
#~ msgstr "스택(Stack)과 힙(Heap)"
|
|
|
|
#~ msgid "Stack Memory"
|
|
#~ msgstr "스택 메모리"
|
|
|
|
#~ msgid "Manual Memory Management"
|
|
#~ msgstr "수동 메모리 관리"
|
|
|
|
#~ msgid "Scope-Based Memory Management"
|
|
#~ msgstr "범위기반 메모리 관리"
|
|
|
|
#~ msgid "Garbage Collection"
|
|
#~ msgstr "가비지 컬렉션"
|
|
|
|
#~ msgid "Rust Memory Management"
|
|
#~ msgstr "러스트의 메모리 관리"
|
|
|
|
#~ msgid "Comparison"
|
|
#~ msgstr "비교"
|
|
|
|
#~ msgid "Moved Strings in Rust"
|
|
#~ msgstr "러스트에서의 문자열 이동"
|
|
|
|
#~ msgid "Moves in Function Calls"
|
|
#~ msgstr "함수 호출에서의 이동(Move)"
|
|
|
|
#~ msgid "Copying and Cloning"
|
|
#~ msgstr "복사와 복제"
|
|
|
|
#~ msgid "Shared and Unique Borrows"
|
|
#~ msgstr "공유와 고유 빌림"
|
|
|
|
#~ msgid "Storing Books"
|
|
#~ msgstr "책 저장하기"
|
|
|
|
#~ msgid "Iterators and Ownership"
|
|
#~ msgstr "반복자와 소유권"
|
|
|
|
#~ msgid "Field Shorthand Syntax"
|
|
#~ msgstr "필드 할당 단축 문법"
|
|
|
|
#~ msgid "Variant Payloads"
|
|
#~ msgstr "데이터를 포함하는 열거형(Variant Payloads)"
|
|
|
|
#~ msgid "Enum Sizes"
|
|
#~ msgstr "열거형의 크기"
|
|
|
|
#~ msgid "Method Receiver"
|
|
#~ msgstr "메서드 리시버(Receiver)"
|
|
|
|
#~ msgid "Destructuring Structs"
|
|
#~ msgstr "구조체 분해(역구조화)"
|
|
|
|
#~ msgid "Destructuring Arrays"
|
|
#~ msgstr "배열 분해(역구조화)"
|
|
|
|
#~ msgid "Match Guards"
|
|
#~ msgstr "매치 가드"
|
|
|
|
#~ msgid "Points and Polygons"
|
|
#~ msgstr "점과 다각형"
|
|
|
|
#~ msgid "if expressions"
|
|
#~ msgstr "if 표현식"
|
|
|
|
#~ msgid "if let expressions"
|
|
#~ msgstr "if let 표현식"
|
|
|
|
#~ msgid "while expressions"
|
|
#~ msgstr "while 표현식"
|
|
|
|
#~ msgid "for expressions"
|
|
#~ msgstr "for 표현식"
|
|
|
|
#~ msgid "loop expressions"
|
|
#~ msgstr "loop 표현식"
|
|
|
|
#~ msgid "match expressions"
|
|
#~ msgstr "match 표현식"
|
|
|
|
#~ msgid "break & continue"
|
|
#~ msgstr "break와 continue"
|
|
|
|
#~ msgid "Option and Result"
|
|
#~ msgstr "Option과 Result"
|
|
|
|
#~ msgid "Vec"
|
|
#~ msgstr "Vec"
|
|
|
|
#~ msgid "HashMap"
|
|
#~ msgstr "HashMap"
|
|
|
|
#~ msgid "Box"
|
|
#~ msgstr "Box"
|
|
|
|
#~ msgid "Recursive Data Types"
|
|
#~ msgstr "재귀적 자료구조"
|
|
|
|
#~ msgid "Rc"
|
|
#~ msgstr "Rc"
|
|
|
|
#~ msgid "Cell/RefCell"
|
|
#~ msgstr "Cell과 RefCell"
|
|
|
|
#~ msgid "Strings and Iterators"
|
|
#~ msgstr "문자열과 반복자"
|
|
|
|
#~ msgid "Generic Methods"
|
|
#~ msgstr "제네릭 메서드"
|
|
|
|
#~ msgid "Monomorphization"
|
|
#~ msgstr "단형화"
|
|
|
|
#~ msgid "Default Methods"
|
|
#~ msgstr "기본 메서드"
|
|
|
|
#~ msgid "impl Trait"
|
|
#~ msgstr "트레잇 구현하기"
|
|
|
|
#~ msgid "Important Traits"
|
|
#~ msgstr "중요한 트레잇"
|
|
|
|
#~ msgid "From and Into"
|
|
#~ msgstr "From과 Into"
|
|
|
|
#~ msgid "Default"
|
|
#~ msgstr "Default"
|
|
|
|
#~ msgid "Operators: Add, Mul, ..."
|
|
#~ msgstr "연산자: Add, Mul, ..."
|
|
|
|
#~ msgid "Closures: Fn, FnMut, FnOnce"
|
|
#~ msgstr "클로저: Fn, FnMut, FnOnce"
|
|
|
|
#~ msgid "Catching Stack Unwinding"
|
|
#~ msgstr "스택 되감기"
|
|
|
|
#~ msgid "Structured Error Handling"
|
|
#~ msgstr "구조화된 오류처리"
|
|
|
|
#~ msgid "Propagating Errors with ?"
|
|
#~ msgstr "\"?'를 이용한 오류 전파"
|
|
|
|
#~ msgid "Converting Error Types"
|
|
#~ msgstr "오류타입 변환"
|
|
|
|
#~ msgid "Deriving Error Enums"
|
|
#~ msgstr "또다른 오류 열거형"
|
|
|
|
#~ msgid "Adding Context to Errors"
|
|
#~ msgstr "오류에 상황정보 추가"
|
|
|
|
#~ msgid "no_std"
|
|
#~ msgstr "no_std"
|
|
|
|
#~ msgid "alloc"
|
|
#~ msgstr "alloc"
|
|
|
|
#~ msgid "embedded-hal"
|
|
#~ msgstr "embedded-hal"
|
|
|
|
#~ msgid "probe-rs, cargo-embed"
|
|
#~ msgstr "progo-rs, cargo-embed"
|
|
|
|
#~ msgid "zerocopy"
|
|
#~ msgstr "zerocopy"
|
|
|
|
#~ msgid "buddy_system_allocator"
|
|
#~ msgstr "buddy_system_allocator"
|
|
|
|
#~ msgid "tinyvec"
|
|
#~ msgstr "tinyvec"
|
|
|
|
#~ msgid "spin"
|
|
#~ msgstr "회전"
|
|
|
|
#~ msgid "Send and Sync"
|
|
#~ msgstr "Send와 Sync"
|
|
|
|
#~ msgid "Send"
|
|
#~ msgstr "Send"
|
|
|
|
#~ msgid "Sync"
|
|
#~ msgstr "Sync"
|
|
|
|
#~ msgid "Arc"
|
|
#~ msgstr "Arc"
|
|
|
|
#~ msgid "Mutex"
|
|
#~ msgstr "Mutex"
|
|
|
|
#~ msgid "async/await"
|
|
#~ msgstr "async/await"
|
|
|
|
#~ msgid "Pin"
|
|
#~ msgstr "Pin"
|
|
|
|
#~ msgid "Day 1 Morning"
|
|
#~ msgstr "1일차 오전"
|
|
|
|
#~ msgid "Day 1 Afternoon"
|
|
#~ msgstr "1일차 오후"
|
|
|
|
#~ msgid "Day 2 Morning"
|
|
#~ msgstr "2일차 오전"
|
|
|
|
#~ msgid "Day 2 Afternoon"
|
|
#~ msgstr "2일차 오후"
|
|
|
|
#~ msgid "Day 3 Morning"
|
|
#~ msgstr "3일차 오전"
|
|
|
|
#~ msgid "Day 3 Afternoon"
|
|
#~ msgstr "3일차 오후"
|
|
|
|
#~ msgid "Bare Metal Rust Morning"
|
|
#~ msgstr "Bare Metal 오전"
|
|
|
|
#~ msgid "Concurrency Morning"
|
|
#~ msgstr "동시성 오전"
|
|
|
|
#~ msgid "Concurrency Afternoon"
|
|
#~ msgstr "동시성 오후"
|
|
|
|
#~ msgid ""
|
|
#~ "[![Build workflow](https://img.shields.io/github/actions/workflow/status/"
|
|
#~ "google/comprehensive-rust/build.yml?style=flat-square)](https://github."
|
|
#~ "com/google/comprehensive-rust/actions/workflows/build.yml?"
|
|
#~ "query=branch%3Amain)"
|
|
#~ msgstr ""
|
|
#~ "[![Build workflow](https://img.shields.io/github/actions/workflow/status/"
|
|
#~ "google/comprehensive-rust/build.yml?style=flat-square)](https://github."
|
|
#~ "com/google/comprehensive-rust/actions/workflows/build.yml?"
|
|
#~ "query=branch%3Amain)"
|
|
|
|
#~ msgid "Build workflow"
|
|
#~ msgstr "빌드 워크플로"
|
|
|
|
#~ msgid "GitHub contributors"
|
|
#~ msgstr "GitHub 참여자"
|
|
|
|
#~ msgid ""
|
|
#~ "[![GitHub contributors](https://img.shields.io/github/contributors/google/"
|
|
#~ "comprehensive-rust?style=flat-square)](https://github.com/google/"
|
|
#~ "comprehensive-rust/graphs/contributors) [![GitHub stars](https://img."
|
|
#~ "shields.io/github/stars/google/comprehensive-rust?style=flat-square)]"
|
|
#~ "(https://github.com/google/comprehensive-rust/stargazers)"
|
|
#~ msgstr ""
|
|
#~ "[![GitHub contributors](https://img.shields.io/github/contributors/google/"
|
|
#~ "comprehensive-rust?style=flat-square)](https://github.com/google/"
|
|
#~ "comprehensive-rust/graphs/contributors) [![GitHub stars](https://img."
|
|
#~ "shields.io/github/stars/google/comprehensive-rust?style=flat-square)]"
|
|
#~ "(https://github.com/google/comprehensive-rust/stargazers)"
|
|
|
|
#~ msgid "GitHub stars"
|
|
#~ msgstr "GitHub stars"
|
|
|
|
#~ msgid ""
|
|
#~ "[![GitHub stars](https://img.shields.io/github/stars/google/comprehensive-"
|
|
#~ "rust?style=flat-square)](https://github.com/google/comprehensive-rust/"
|
|
#~ "stargazers)"
|
|
#~ msgstr ""
|
|
#~ "[![GitHub stars](https://img.shields.io/github/stars/google/comprehensive-"
|
|
#~ "rust?style=flat-square)](https://github.com/google/comprehensive-rust/"
|
|
#~ "stargazers)"
|
|
|
|
#~ msgid "The course is fast paced and covers a lot of ground:"
|
|
#~ msgstr "강의는 빠른 속도로 진행되며, 아래 내용들을 다룹니다:"
|
|
|
|
#~ msgid "Day 1: Basic Rust, ownership and the borrow checker."
|
|
#~ msgstr "1일차: 러스트 기본, 소유권(ownership)과 빌림(borrow) 체크."
|
|
|
|
#~ msgid "Day 2: Compound data types, pattern matching, the standard library."
|
|
#~ msgstr "2일차: 복합 데이터 유형, 패턴 매칭, 표준 라이브러리."
|
|
|
|
#~ msgid "Day 3: Traits and generics, error handling, testing, unsafe Rust."
|
|
#~ msgstr ""
|
|
#~ "3일차: 트레잇(trait)와 제네릭(generic), 오류 처리, 테스트, 안전하지 않은 "
|
|
#~ "러스트."
|
|
|
|
#~ msgid "Concurrency"
|
|
#~ msgstr "동시성"
|
|
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "cargo init concurrency\n"
|
|
#~ "cd concurrency\n"
|
|
#~ "cargo add tokio --features full\n"
|
|
#~ "cargo run\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```shell\n"
|
|
#~ "cargo init concurrency\n"
|
|
#~ "cd concurrency\n"
|
|
#~ "cargo add tokio --features full\n"
|
|
#~ "cargo run\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ " sudo apt install cargo rust-src rustfmt\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```shell\n"
|
|
#~ "$ sudo apt install cargo rust-src rustfmt\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "We suggest using [VS Code](https://code.visualstudio.com/) to edit the "
|
|
#~ "code (but any LSP compatible editor works with rust-analyzer[3](https://"
|
|
#~ "rust-analyzer.github.io/))."
|
|
#~ msgstr ""
|
|
#~ "우리는 코드 에디터로 [VS Code](https://code.visualstudio.com/)를 추천합니"
|
|
#~ "다. 그러나 LSP를 지원하는 (그래서 rust-analyzer[3](https://rust-analyzer."
|
|
#~ "github.io/)와 연동이 가능한) 에디터라면 어떤 것이라도 괜찮습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Some folks also like to use the [JetBrains](https://www.jetbrains.com/"
|
|
#~ "clion/) family of IDEs, which do their own analysis but have their own "
|
|
#~ "tradeoffs. If you prefer them, you can install the [Rust Plugin](https://"
|
|
#~ "www.jetbrains.com/rust/). Please take note that as of January 2023 "
|
|
#~ "debugging only works on the CLion version of the JetBrains IDEA suite."
|
|
#~ msgstr ""
|
|
#~ "어떤 사람들은 [JetBrains](https://www.jetbrains.com/clion/) 제품군을 선호"
|
|
#~ "하기도 합니다. 이 제품들은 rust-analyzer 를 활용하지 않고 IDE 자체적으로 "
|
|
#~ "구문분석을 합니다. 만약 이 IDE를 설치하셨다면 [Rust Plugin](https://www."
|
|
#~ "jetbrains.com/rust/)를 설치하시기 바랍니다. 다만 2023년 1월 기준, 디버깅"
|
|
#~ "은 JetBrains IDEA suite의 CLion 버전에서만 작동한다는 점에 유의하시기 바랍"
|
|
#~ "니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"Edit me!\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"Edit me!\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "% rustc --version\n"
|
|
#~ "rustc 1.69.0 (84c898d65 2023-04-16)\n"
|
|
#~ "% cargo --version\n"
|
|
#~ "cargo 1.69.0 (6e9a83356 2023-04-12)\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```shell\n"
|
|
#~ "% rustc --version\n"
|
|
#~ "rustc 1.69.0 (84c898d65 2023-04-16)\n"
|
|
#~ "% cargo --version\n"
|
|
#~ "cargo 1.69.0 (6e9a83356 2023-04-12)\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "$ cargo new exercise\n"
|
|
#~ " Created binary (application) `exercise` package\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```shell\n"
|
|
#~ "$ cargo new exercise\n"
|
|
#~ " Created binary (application) `exercise` package\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"Edit me!\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"Edit me!\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Memory management: stack vs heap, manual memory management, scope-based "
|
|
#~ "memory management, and garbage collection."
|
|
#~ msgstr ""
|
|
#~ "메모리 관리: 스택과 힙, 수동 메모리 관리, 스코프(범위)기반 메모리 관리, 가"
|
|
#~ "비지 컬렉션(GC)"
|
|
|
|
#~ msgid ""
|
|
#~ "Ownership: move semantics, copying and cloning, borrowing, and lifetimes."
|
|
#~ msgstr "소유권: Move 문법, 복사와 복제, 빌림, 수명."
|
|
|
|
#~ msgid ""
|
|
#~ "The idea for the first day is to show _just enough_ of Rust to be able to "
|
|
#~ "speak about the famous borrow checker. The way Rust handles memory is a "
|
|
#~ "major feature and we should show students this right away."
|
|
#~ msgstr ""
|
|
#~ "첫 날 강의의 목표는, 러스트에서 그 유명한 빌림 확인에 대해서 이야기 할 수 "
|
|
#~ "있을 정도 까지만 러스트를 소개하는 것입니다. 러스트의 가장 독특한 특징이 "
|
|
#~ "메모리를 다루는 방식이기 때문에, 학생들에게 이 부분 을 우선적으로 보여주"
|
|
#~ "려 합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "If you're teaching this in a classroom, this is a good place to go over "
|
|
#~ "the schedule. We suggest splitting the day into two parts (following the "
|
|
#~ "slides):"
|
|
#~ msgstr ""
|
|
#~ "만약 당신이 강의실에서 가르치고 있다면, 이 슬라이드는 일정을 검토하기에 적"
|
|
#~ "합한 곳입니다. 하루치 강의를 아래처럼 오전 오후로 나누어 진행하는 것을 추"
|
|
#~ "천합니다. (슬라이드가 그런식으로 나뉘어 있습니다.)"
|
|
|
|
#~ msgid "Morning: 9:00 to 12:00,"
|
|
#~ msgstr "오전: 9:00 ~ 12:00,"
|
|
|
|
#~ msgid "Afternoon: 13:00 to 16:00."
|
|
#~ msgstr "오후: 13:00 ~ 16:00."
|
|
|
|
#~ msgid ""
|
|
#~ "You can of course adjust this as necessary. Please make sure to include "
|
|
#~ "breaks, we recommend a break every hour!"
|
|
#~ msgstr ""
|
|
#~ "물론 필요에 따라 조절할 수 있습니다. 강의 중간에 쉬는시간을 넣는 것을 잊"
|
|
#~ "지 마세요. 매 시간 휴식을 갖는걸 추천합니다!"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"Hello 🌍!\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"Hello 🌍!\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Here is a small example program in Rust:"
|
|
#~ msgstr "러스트로 작성된 작은 예제입니다:"
|
|
|
|
#~ 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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "The code implements the Collatz conjecture: it is believed that the loop "
|
|
#~ "will always end, but this is not yet proved. Edit the code and play with "
|
|
#~ "different inputs."
|
|
#~ msgstr ""
|
|
#~ "이 코드는 콜라츠 추측(Collatz conjecture)으로 구현됩니다: 반복문이 언제나 "
|
|
#~ "종료될 것이라고 믿지만 증명된 것은 아닙니다. 코드를 수정하고 실행해 보시"
|
|
#~ "기 바랍니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Explain that all variables are statically typed. Try removing `i32` to "
|
|
#~ "trigger type inference. Try with `i8` instead and trigger a runtime "
|
|
#~ "integer overflow."
|
|
#~ msgstr ""
|
|
#~ "모든 변수가 컴파일 시 정해진 타입을 가짐을 설명합니다. `i32`를 삭제하여 컴"
|
|
#~ "파일러가 타입 추론을 하도록 해 봅니다. `i32`을 `i8`로 변경하여 런타임 오버"
|
|
#~ "플로를 유발해 볼 수 있습니다."
|
|
|
|
#~ msgid "Change `let mut x` to `let x`, discuss the compiler error."
|
|
#~ msgstr "`let mut x`를 `let x`로 수정하여 컴파일 오류에 대해 토론합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Show how `print!` gives a compilation error if the arguments don't match "
|
|
#~ "the format string."
|
|
#~ msgstr ""
|
|
#~ "인자가 포맷 문자열과 일치하지 않는 경우 `print!`에서 컴파일 오류가 발생함"
|
|
#~ "을 언급하는 것도 좋습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Show how you need to use `{}` as a placeholder if you want to print an "
|
|
#~ "expression which is more complex than just a single variable."
|
|
#~ msgstr ""
|
|
#~ "단일 변수보다 복잡한 식을 출려하려면 `{}`을 자리 표시자로 사용하는 방법을 "
|
|
#~ "보여 줍니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Show the students the standard library, show them how to search for `std::"
|
|
#~ "fmt` which has the rules of the formatting mini-language. It's important "
|
|
#~ "that the students become familiar with searching in the standard library."
|
|
#~ msgstr ""
|
|
#~ "학생들에게 표준 라이브러리가 어디 있는지 알려 주고는, `print!`가 지원하는 "
|
|
#~ "포맷팅 언어의 문법을 알기 위해 `std::fmt`를 검색해야 한다는 것을 가르치세"
|
|
#~ "요.학생들이 표준 라이브러리의 검색 기능에 익숙해 지도록 하는 것이 중요합니"
|
|
#~ "다."
|
|
|
|
#~ msgid ""
|
|
#~ "In a shell `rustup doc std::fmt` will open a browser on the local std::"
|
|
#~ "fmt documentation"
|
|
#~ msgstr ""
|
|
#~ "쉘에서 `rustup doc std::fmt`를 수행하면 로컬 브라우저로 `std:fmt`에 대한 "
|
|
#~ "문서를 보여줍니다"
|
|
|
|
#~ msgid "Compile time memory safety."
|
|
#~ msgstr "컴파일 시 메모리 안전이 보장됨."
|
|
|
|
#~ msgid "Lack of undefined runtime behavior."
|
|
#~ msgstr "정의되지 않은 런타임 동작이 없음."
|
|
|
|
#~ msgid "Modern language features."
|
|
#~ msgstr "현대적인 언어 기능."
|
|
|
|
#~ msgid "Static memory management at compile time:"
|
|
#~ msgstr "컴파일 시 정적 메모리 관리:"
|
|
|
|
#~ msgid "No memory leaks (_mostly_, see notes)."
|
|
#~ msgstr "메모리 누출 없음(_거의_. 강의참조노트 참고.)"
|
|
|
|
#~ msgid ""
|
|
#~ "It is possible to produce memory leaks in (safe) Rust. Some examples are:"
|
|
#~ msgstr ""
|
|
#~ "(안전한) 러스트에서도 메모리 누출이 발생할 수 있는 몇 가지 경우가 있습니"
|
|
#~ "다:"
|
|
|
|
#~ msgid ""
|
|
#~ "You can use [`Box::leak`](https://doc.rust-lang.org/std/boxed/struct.Box."
|
|
#~ "html#method.leak) to leak a pointer. A use of this could be to get "
|
|
#~ "runtime-initialized and runtime-sized static variables"
|
|
#~ msgstr ""
|
|
#~ "[`Box::leak`](https://doc.rust-lang.org/std/boxed/struct.Box.html#method."
|
|
#~ "leak)을 이용하여 포인터를 의도적으로 누출시킬 수 있습니다. 이를 이용해서 "
|
|
#~ "런타임이 생성하고 런타임이 크기를 정한 정적 변수를 가져올 수 있습니다"
|
|
|
|
#~ msgid ""
|
|
#~ "You can use [`std::mem::forget`](https://doc.rust-lang.org/std/mem/fn."
|
|
#~ "forget.html) to make the compiler \"forget\" about a value (meaning the "
|
|
#~ "destructor is never run)."
|
|
#~ msgstr ""
|
|
#~ "[`std::mem::forget`](https://doc.rust-lang.org/std/mem/fn.forget.html)을 "
|
|
#~ "사용하여 컴파일러가 값에 대해 \"잊도록\" 만들 수 있습니다(소멸자가 실행되"
|
|
#~ "지 않음을 의미합니다)."
|
|
|
|
#~ msgid ""
|
|
#~ "You can also accidentally create a [reference cycle](https://doc.rust-"
|
|
#~ "lang.org/book/ch15-06-reference-cycles.html) with `Rc` or `Arc`."
|
|
#~ msgstr ""
|
|
#~ "`Rc` 또는 `Arc`를 사용하여 실수로 [순환참조](https://doc.rust-lang.org/"
|
|
#~ "book/ch15-06-reference-cycles.html)를 생성할 수도 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "In fact, some will consider infinitely populating a collection a memory "
|
|
#~ "leak and Rust does not protect from those."
|
|
#~ msgstr ""
|
|
#~ "컬렉션을 무한정 채우는 것을 메모리 누출로 간주할 수도 있지만, 러스트는 이"
|
|
#~ "를 보호하진 못합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "For the purpose of this course, \"No memory leaks\" should be understood "
|
|
#~ "as \"Pretty much no _accidental_ memory leaks\"."
|
|
#~ msgstr ""
|
|
#~ "본 강의에서는 \"메모리 누출 없음\"을 \"우발적인 메모리 누출 없음\"으로 이"
|
|
#~ "해해야 합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Integer overflow is defined via the [`overflow-checks`](https://doc.rust-"
|
|
#~ "lang.org/rustc/codegen-options/index.html#overflow-checks) compile-time "
|
|
#~ "flag. If enabled, the program will panic (a controlled crash of the "
|
|
#~ "program), otherwise you get wrap-around semantics. By default, you get "
|
|
#~ "panics in debug mode (`cargo build`) and wrap-around in release mode "
|
|
#~ "(`cargo build --release`)."
|
|
#~ msgstr ""
|
|
#~ "정수형 오버플로우는 [`overflow-checks`](https://doc.rust-lang.org/rustc/"
|
|
#~ "codegen-options/index.html#overflow-checks) 컴파일 타임 플래그를 통해 정의"
|
|
#~ "됩니다. 이 플래그가 켜지면, 프로그램은 정수형 오버플로우 발생시 panic (프"
|
|
#~ "로그램을 크래시 시키는 잘 정의된 방법) 합니다. 이 플래그가 꺼지면, 오버플"
|
|
#~ "로우는 wrap-around 가 됩니다. 기본적으로 디버그 모드(`cargo build`)에서는 "
|
|
#~ "패닉이, 릴리즈 모드(`cargo build --release`)에서는 wrap-around가 발생합니"
|
|
#~ "다."
|
|
|
|
#~ msgid ""
|
|
#~ "Bounds checking cannot be disabled with a compiler flag. It can also not "
|
|
#~ "be disabled directly with the `unsafe` keyword. However, `unsafe` allows "
|
|
#~ "you to call functions such as `slice::get_unchecked` which does not do "
|
|
#~ "bounds checking."
|
|
#~ msgstr ""
|
|
#~ "컴파일 플래그를 사용하여 경계체크를 무력화 할 수 없습니다. `unsafe`를 사용"
|
|
#~ "하더라도 마찬가지입니다. 하지만 `unsafe`에서 호출 가능한 `slice::"
|
|
#~ "get_unchecked`같은 함수는 경계 검사를 수행하지 않습니다."
|
|
|
|
#~ msgid "Rust is built with all the experience gained in the last decades."
|
|
#~ msgstr ""
|
|
#~ "러스트는 지난 수십년간의 모든 (프로그래밍 언어들의) 경험으로 만들어졌습니"
|
|
#~ "다."
|
|
|
|
#~ msgid "Language Features"
|
|
#~ msgstr "언어적 특징"
|
|
|
|
#~ msgid "Tooling"
|
|
#~ msgstr "도구들"
|
|
|
|
#~ msgid ""
|
|
#~ "Zero-cost abstractions, similar to C++, means that you don't have to "
|
|
#~ "'pay' for higher-level programming constructs with memory or CPU. For "
|
|
#~ "example, writing a loop using `for` should result in roughly the same low "
|
|
#~ "level instructions as using the `.iter().fold()` construct."
|
|
#~ msgstr ""
|
|
#~ "C++ 와 유사하게 제로 코스트 추상화는 CPU나 메모리를 사용하여 상위레벨 프로"
|
|
#~ "그래밍 구조를 만드는데 '비용'을 지불할 필요가 없습니다. 예를 들어 `for` 루"
|
|
#~ "프와와 `iter().fold()` 구조를 사용하는 것과 거의 동일한 낮은 수준의 명령어"
|
|
#~ "가 생성될 것 입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "It may be worth mentioning that Rust enums are 'Algebraic Data Types', "
|
|
#~ "also known as 'sum types', which allow the type system to express things "
|
|
#~ "like `Option<T>` and `Result<T, E>`."
|
|
#~ msgstr ""
|
|
#~ "러스트의 열거형(enum)은 합계 타입(sum type)으로 알려진 대수학적 데이터형"
|
|
#~ "(Algebraic Data Type)으로, 타입 시스템이 `Option<T>`와 `Result<T, E>`등을 "
|
|
#~ "표현할 수 있게 해줍니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Remind people to read the errors --- many developers have gotten used to "
|
|
#~ "ignore lengthy compiler output. The Rust compiler is significantly more "
|
|
#~ "talkative than other compilers. It will often provide you with "
|
|
#~ "_actionable_ feedback, ready to copy-paste into your code."
|
|
#~ msgstr ""
|
|
#~ "오류를 읽어보시기 바랍니다 --- 오랜기간 많은 개발자들이 컴파일러 출력을 무"
|
|
#~ "시하는데 익숙해져 있습니다. 러스트 컴파일러는 다른 컴파일러보다 더 수다스"
|
|
#~ "럽고, 복사-붙여넣기 할 수 있는 정도의 코드 피드백을 제공하는 경우가 많습니"
|
|
#~ "다."
|
|
|
|
#~ msgid ""
|
|
#~ "The Rust standard library is small compared to languages like Java, "
|
|
#~ "Python, and Go. Rust does not come with several things you might consider "
|
|
#~ "standard and essential:"
|
|
#~ msgstr ""
|
|
#~ "러스트 표준 라이브러리는 Java, Python이나 Go와 같은 언어에 비해서 규모가 "
|
|
#~ "작습니다. 당연히 포함되어야 한다고 생각할 수도 있는 아래와 같은 것들이 러"
|
|
#~ "스트의 표준 라이브러리에 없습니다:"
|
|
|
|
#~ msgid "a random number generator, but see [rand](https://docs.rs/rand/)."
|
|
#~ msgstr ""
|
|
#~ "난수 생성기, 하지만 [rand](https://docs.rs/rand/)문서를 참조하시기 바랍니"
|
|
#~ "다."
|
|
|
|
#~ msgid "support for SSL or TLS, but see [rusttls](https://docs.rs/rustls/)."
|
|
#~ msgstr ""
|
|
#~ "SSL 또는 TLS지원, 하지만 [rusttls](https://docs.rs/rustls/)문서를 참조하시"
|
|
#~ "기 바랍니다."
|
|
|
|
#~ msgid "support for JSON, but see [serde_json](https://docs.rs/serde_json/)."
|
|
#~ msgstr ""
|
|
#~ "JSON 지원, 하지만 [serde_json](https://docs.rs/serde_json/) 문서를 참조하"
|
|
#~ "시기 바랍니다."
|
|
|
|
#~ msgid ""
|
|
#~ "The reasoning behind this is that functionality in the standard library "
|
|
#~ "cannot go away, so it has to be very stable. For the examples above, the "
|
|
#~ "Rust community is still working on finding the best solution --- and "
|
|
#~ "perhaps there isn't a single \"best solution\" for some of these things."
|
|
#~ msgstr ""
|
|
#~ "그 이유는 표준 라이브러리에서 한 번 어떤 기능을 제공하면 뺄 수 없으며, 매"
|
|
#~ "우 안정적이어야 하기 때문입니다. 위에 언급한 기능들은 아직 러스트 커뮤니티"
|
|
#~ "가 최고의 솔루션을 찾지 못했기 때문에 표준 라이브러리에 포함되지 않았습니"
|
|
#~ "다. 어쩌면 이들 중 몇 개는 '최고의 솔루션'이 아예 존재할 수 없을 지도 모릅"
|
|
#~ "니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Rust comes with a built-in package manager in the form of Cargo and this "
|
|
#~ "makes it trivial to download and compile third-party crates. A "
|
|
#~ "consequence of this is that the standard library can be smaller."
|
|
#~ msgstr ""
|
|
#~ "러스트는 카고라는 패키지 관리자가 내장되어 있고, 서드파티 크레이트를 다운"
|
|
#~ "로드, 컴파일 하기 매우 쉽습니다. 이 또한 표준 라이브러리가 작은 이유입니"
|
|
#~ "다."
|
|
|
|
#~ msgid ""
|
|
#~ "Discovering good third-party crates can be a problem. Sites like <https://"
|
|
#~ "lib.rs/> help with this by letting you compare health metrics for crates "
|
|
#~ "to find a good and trusted one."
|
|
#~ msgstr ""
|
|
#~ "좋은 서드파티 크레이트를 찾는 것은 어렵습니다. <https://lib.rs> 와 같은 사"
|
|
#~ "이트가 신뢰할수 있는 좋은 크레이트를 비교하여 찾는데 좋습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "[rust-analyzer](https://rust-analyzer.github.io/) is a well supported LSP "
|
|
#~ "implementation used in major IDEs and text editors."
|
|
#~ msgstr ""
|
|
#~ "[rust-analyzer](https://rust-analyzer.github.io/)는 주요 IDE나 텍스트 에디"
|
|
#~ "터에서 사용되는 러스트용 LSP서버 입니다."
|
|
|
|
#~ msgid "`\"foo\"`, `\"two\\nlines\"`"
|
|
#~ msgstr "`\"foo\"`, `\"two\\nlines\"`"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(r#\"<a href=\"link.html\">link</a>\"#);\n"
|
|
#~ " println!(\"<a href=\\\"link.html\\\">link</a>\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(r#\"<a href=\"link.html\">link</a>\"#);\n"
|
|
#~ " println!(\"<a href=\\\"link.html\\\">link</a>\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"{:?}\", b\"abc\");\n"
|
|
#~ " println!(\"{:?}\", &[97, 98, 99]);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"{:?}\", b\"abc\");\n"
|
|
#~ " println!(\"{:?}\", &[97, 98, 99]);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut a: [i8; 10] = [42; 10];\n"
|
|
#~ " a[5] = 0;\n"
|
|
#~ " println!(\"a: {:?}\", a);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid "Like C++, Rust has references:"
|
|
#~ msgstr "C++와 마찬가지로 러스트도 참조형을 갖습니다:"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "We must dereference `ref_x` when assigning to it, similar to C and C++ "
|
|
#~ "pointers."
|
|
#~ msgstr ""
|
|
#~ "`ref_x`에 값을 할당할 때, C/C++의 포인터와 유사하게 `*`를 이용해서 참조를 "
|
|
#~ "따라가야(역참조) 합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "References that are declared as `mut` can be bound to different values "
|
|
#~ "over their lifetime."
|
|
#~ msgstr ""
|
|
#~ "`mut`로 선언된 참조는 그 변수가 살아있는 동안 다른 값을 가질 수 있습니다."
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid "A reference is said to \"borrow\" the value it refers to."
|
|
#~ msgstr "참조는 어떤 값을 \"빌리는\" 것입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Rust is tracking the lifetimes of all references to ensure they live long "
|
|
#~ "enough."
|
|
#~ msgstr ""
|
|
#~ "러스트는 참조 대상의 값이, 그 값에 대한 모든 참조들보다 더 오래 살아있음"
|
|
#~ "을 추적합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut a: [i32; 6] = [10, 20, 30, 40, 50, 60];\n"
|
|
#~ " println!(\"a: {a:?}\");\n"
|
|
#~ "\n"
|
|
#~ " let s: &[i32] = &a[2..4];\n"
|
|
#~ "\n"
|
|
#~ " println!(\"s: {s:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let a: [i32; 6] = [10, 20, 30, 40, 50, 60];\n"
|
|
#~ " println!(\"a: {a:?}\");\n"
|
|
#~ "\n"
|
|
#~ " let s: &[i32] = &a[2..4];\n"
|
|
#~ " println!(\"s: {s:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "`String` vs `str`"
|
|
#~ msgstr "`String`과 `str`"
|
|
|
|
#~ msgid "We can now understand the two string types in Rust:"
|
|
#~ msgstr "이제 러스트의 두 가지 문자열 타입에 대해서 이해해 보겠습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let s1: &str = \"World\";\n"
|
|
#~ " println!(\"s1: {s1}\");\n"
|
|
#~ "\n"
|
|
#~ " 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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let s1: &str = \"World\";\n"
|
|
#~ " println!(\"s1: {s1}\");\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "You can borrow `&str` slices from `String` via `&` and optionally range "
|
|
#~ "selection."
|
|
#~ msgstr ""
|
|
#~ "`&`와 범위 연산자를 이용하여 `String`에서 `&str`슬라이스를 빌려올 수 있습"
|
|
#~ "니다."
|
|
|
|
#~ 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) 함수입니"
|
|
#~ "다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " print_fizzbuzz_to(20);\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn is_divisible(n: u32, divisor: u32) -> bool {\n"
|
|
#~ " if divisor == 0 {\n"
|
|
#~ " return false;\n"
|
|
#~ " }\n"
|
|
#~ " n % divisor == 0\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn fizzbuzz(n: u32) -> String {\n"
|
|
#~ " let fizz = if is_divisible(n, 3) { \"fizz\" } else { \"\" };\n"
|
|
#~ " let buzz = if is_divisible(n, 5) { \"buzz\" } else { \"\" };\n"
|
|
#~ " if fizz.is_empty() && buzz.is_empty() {\n"
|
|
#~ " return format!(\"{n}\");\n"
|
|
#~ " }\n"
|
|
#~ " format!(\"{fizz}{buzz}\")\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn print_fizzbuzz_to(n: u32) {\n"
|
|
#~ " for i in 1..=n {\n"
|
|
#~ " println!(\"{}\", fizzbuzz(i));\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " print_fizzbuzz_to(20);\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn is_divisible(n: u32, divisor: u32) -> bool {\n"
|
|
#~ " if divisor == 0 {\n"
|
|
#~ " return false;\n"
|
|
#~ " }\n"
|
|
#~ " n % divisor == 0\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn fizzbuzz(n: u32) -> String {\n"
|
|
#~ " let fizz = if is_divisible(n, 3) { \"fizz\" } else { \"\" };\n"
|
|
#~ " let buzz = if is_divisible(n, 5) { \"buzz\" } else { \"\" };\n"
|
|
#~ " if fizz.is_empty() && buzz.is_empty() {\n"
|
|
#~ " return format!(\"{n}\");\n"
|
|
#~ " }\n"
|
|
#~ " format!(\"{fizz}{buzz}\")\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn print_fizzbuzz_to(n: u32) {\n"
|
|
#~ " for i in 1..=n {\n"
|
|
#~ " println!(\"{}\", fizzbuzz(i));\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "We refer in `main` to a function written below. Neither forward "
|
|
#~ "declarations nor headers are necessary. "
|
|
#~ msgstr ""
|
|
#~ "`main` 함수에서 그 다음에 오는 함수들을 사용할 수 있습니다. 미리 선언하기"
|
|
#~ "(forward declaration)나 헤더 같은건 필요 없습니다. "
|
|
|
|
#~ msgid ""
|
|
#~ "The range expression in the `for` loop in `print_fizzbuzz_to()` contains "
|
|
#~ "`=n`, which causes it to include the upper bound."
|
|
#~ msgstr ""
|
|
#~ "`fizzbuzz_to()`함수 내 `for` 반목문의 범위 표현식 중 `=n`은 n까지 포함한다"
|
|
#~ "는 의미입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "All language items in Rust can be documented using special `///` syntax."
|
|
#~ msgstr "Rust의 아이템(item)은 `///` 문법을 사용하여 문서화할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "/// Determine whether the first argument is divisible by the second "
|
|
#~ "argument.\n"
|
|
#~ "///\n"
|
|
#~ "/// If the second argument is zero, the result is false.\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "/// 첫 번째 인수가 두 번째 인수로 나눠질 수 있는지 결정합니다.\n"
|
|
#~ "///\n"
|
|
#~ "/// 두 번째 인수가 0이면 결과는 false입니다.\n"
|
|
#~ "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 // 블록 안의 마지막 표현식은 반환값입니다\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "This course does not include rustdoc on slides, just to save space, but "
|
|
#~ "in real code they should be present."
|
|
#~ msgstr ""
|
|
#~ "이 슬라이드의 예제 코드는 문서화 주석이 생략되어 있지만, 실제 코드라면 문"
|
|
#~ "서화 주석을 반드시 써야 합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Inner doc comments are discussed later (in the page on modules) and need "
|
|
#~ "not be addressed here."
|
|
#~ msgstr ""
|
|
#~ "문서 내부 주석 모듈 페이지 뒷부분에서 다루며 여기서 다루지 않아도 됩니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Rustdoc comments can contain code snippets that we can run and test using "
|
|
#~ "`cargo test`. We will discuss these tests in the [Testing section](../"
|
|
#~ "testing/doc-tests.html)."
|
|
#~ msgstr ""
|
|
#~ "문서화 주석은 코드를 포함할 수도 있으며, 이 코드는 `cargo test`를 통해 테"
|
|
#~ "스트로 동작할 수도 있습니다. [테스트](../testing/doc-tests.html)에서 더 자"
|
|
#~ "세히 다루겠습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Methods are functions associated with a type. The `self` argument of a "
|
|
#~ "method is an instance of the type it is associated with:"
|
|
#~ msgstr ""
|
|
#~ "메서드는 특정 타입과 연결된 함수입니다. 메서드의 `self` 인자가 그 메서드"
|
|
#~ "가 연결된 인스턴스의 타입입니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "struct Rectangle {\n"
|
|
#~ " width: u32,\n"
|
|
#~ " height: u32,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Rectangle {\n"
|
|
#~ " fn area(&self) -> u32 {\n"
|
|
#~ " self.width * self.height\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn inc_width(&mut self, delta: u32) {\n"
|
|
#~ " self.width += delta;\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "struct Rectangle {\n"
|
|
#~ " width: u32,\n"
|
|
#~ " height: u32,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Rectangle {\n"
|
|
#~ " fn area(&self) -> u32 {\n"
|
|
#~ " self.width * self.height\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn inc_width(&mut self, delta: u32) {\n"
|
|
#~ " self.width += delta;\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "We will look much more at methods in today's exercise and in tomorrow's "
|
|
#~ "class."
|
|
#~ msgstr "오늘과 내일 강의에서 더 많은 메서드 사용법을 다룰 것입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Add a static method called `Rectangle::new` and call this from `main`:"
|
|
#~ msgstr "`Rectangle::new` 생성자를 추가하고 이를 `main`에서 호출합니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "fn new(width: u32, height: u32) -> Rectangle {\n"
|
|
#~ " Rectangle { width, height }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "fn new(width: u32, height: u32) -> Rectangle {\n"
|
|
#~ " Rectangle { width, height }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "While _technically_, Rust does not have custom constructors, static "
|
|
#~ "methods are commonly used to initialize structs (but don't have to). The "
|
|
#~ "actual constructor, `Rectangle { width, height }`, could be called "
|
|
#~ "directly. See the [Rustnomicon](https://doc.rust-lang.org/nomicon/"
|
|
#~ "constructors.html)."
|
|
#~ msgstr ""
|
|
#~ "\\_기술적_으로 이야기 하자면, 러스트는 커스텀 생성자를 지원하지 않습니다. "
|
|
#~ "정적 메소드를 사용하는 것이 구조체를 초기화 하는 일반적인 방법입니다 (물"
|
|
#~ "론 이것이 강제되지는 않습니다). 진짜 생성자인 `Rectangle { width, height }"
|
|
#~ "`를 직접 호출할 수도 있습니다. 자세한 내용은 [Rustnomicon](https://doc."
|
|
#~ "rust-lang.org/nomicon/constructors.html)을 참조하세요."
|
|
|
|
#~ msgid ""
|
|
#~ "Add a `Rectangle::square(width: u32)` constructor to illustrate that such "
|
|
#~ "static methods can take arbitrary parameters."
|
|
#~ msgstr ""
|
|
#~ "`Rectangle::square(width: u32)` 생성자를 추가하여 생성자가 임의의 매개변수"
|
|
#~ "를 사용할 수 있음을 보입시다."
|
|
|
|
#~ msgid "Function Overloading"
|
|
#~ msgstr "(함수) 오버로딩"
|
|
|
|
#~ msgid "Overloading is not supported:"
|
|
#~ msgstr "오버로딩은 지원되지 않습니다:"
|
|
|
|
#~ msgid "Always takes a fixed number of parameters."
|
|
#~ msgstr "항상 고정된 수의 파라매터만 갖습니다."
|
|
|
|
#~ msgid "Default values are not supported:"
|
|
#~ msgstr "파라매터의 기본 값은 지원되지 않습니다:"
|
|
|
|
#~ msgid "All call sites have the same number of arguments."
|
|
#~ msgstr "모든 호출부에서는 동일한 수의 인자를 설정해야합니다."
|
|
|
|
#~ msgid "Macros are sometimes used as an alternative."
|
|
#~ msgstr "이런 사항들이 제약이 될 경우, 대안으로 매크로를 사용하기도 합니다."
|
|
|
|
#~ msgid "However, function parameters can be generic:"
|
|
#~ msgstr "하지만, 함수의 매개변수는 제네릭을 적용할 수 있습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn pick_one<T>(a: T, b: T) -> T {\n"
|
|
#~ " if std::process::id() % 2 == 0 { a } else { b }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"coin toss: {}\", pick_one(\"heads\", \"tails\"));\n"
|
|
#~ " println!(\"cash prize: {}\", pick_one(500, 1000));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn pick_one<T>(a: T, b: T) -> T {\n"
|
|
#~ " if std::process::id() % 2 == 0 { a } else { b }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"coin toss: {}\", pick_one(\"heads\", \"tails\"));\n"
|
|
#~ " println!(\"cash prize: {}\", pick_one(500, 1000));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "When using generics, the standard library's `Into<T>` can provide a kind "
|
|
#~ "of limited polymorphism on argument types. We will see more details in a "
|
|
#~ "later section."
|
|
#~ msgstr ""
|
|
#~ "제네릭을 사용할 때 표준 라이브러리의 `Into<T>`은 타입에 대한 다형성을 제공"
|
|
#~ "할 수 있습니다. 나중에 자세히 설명하겠습니다."
|
|
|
|
#~ msgid "Day 1: Morning Exercises"
|
|
#~ msgstr "1일차 오전 연습문제"
|
|
|
|
#~ msgid "In these exercises, we will explore two parts of Rust:"
|
|
#~ msgstr "이번 연습문제는 러스트의 두 부분을 알아볼 것입니다:"
|
|
|
|
#~ msgid "Implicit conversions between types."
|
|
#~ msgstr "타입의 묵시적 변환."
|
|
|
|
#~ msgid "Arrays and `for` loops."
|
|
#~ msgstr "배열과 `for` 반복문."
|
|
|
|
#~ msgid "A few things to consider while solving the exercises:"
|
|
#~ msgstr "연습문제를 해결하는데 고려해야 할 사항들:"
|
|
|
|
#~ msgid ""
|
|
#~ "Use a local Rust installation, if possible. This way you can get auto-"
|
|
#~ "completion in your editor. See the page about [Using Cargo](../../cargo."
|
|
#~ "md) for details on installing Rust."
|
|
#~ msgstr ""
|
|
#~ "가능하다면 러스트가 설치된 로컬 환경에서 진행하세요. 그러는 편이 텍스트 에"
|
|
#~ "디터의 자동완성 기능의 도움을 받을 수 있어서 좋습니다. [카고 사용하기]"
|
|
#~ "(../../cargo.md) 을 참조하시기 바랍니다."
|
|
|
|
#~ msgid "Alternatively, use the Rust Playground."
|
|
#~ msgstr "혹은 러스트 플레이그라운드를 이용할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "The code snippets are not editable on purpose: the inline code snippets "
|
|
#~ "lose their state if you navigate away from the page."
|
|
#~ msgstr ""
|
|
#~ "페이지 밖으로 이동할 경우 작성한 내용이 소실되기 때문에 제공되는 코드 스니"
|
|
#~ "펫은 의도적으로 편집할 수 없습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "After looking at the exercises, you can look at the \\[solutions\\] "
|
|
#~ "provided."
|
|
#~ msgstr ""
|
|
#~ "연습문제를 살펴 본 후, 제공된 \\[해답\\]\\[solutions\\]을 살펴볼 수 있습니"
|
|
#~ "다."
|
|
|
|
#~ msgid ""
|
|
#~ "Rust will not automatically apply _implicit conversions_ between types "
|
|
#~ "([unlike C++](https://en.cppreference.com/w/cpp/language/"
|
|
#~ "implicit_conversion)). You can see this in a program like this:"
|
|
#~ msgstr ""
|
|
#~ "러스트는 [C++ 와 다르게](https://en.cppreference.com/w/cpp/language/"
|
|
#~ "implicit_conversion) 타입 간 _묵시적 변환_을 자동으로 적용하지 않습니다. "
|
|
#~ "아래 예시를 확인해 보세요:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "fn multiply(x: i16, y: i16) -> i16 {\n"
|
|
#~ " x * y\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let x: i8 = 15;\n"
|
|
#~ " let y: i16 = 1000;\n"
|
|
#~ "\n"
|
|
#~ " println!(\"{x} * {y} = {}\", multiply(x, y));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "fn multiply(x: i16, y: i16) -> i16 {\n"
|
|
#~ " x * y\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let x: i8 = 15;\n"
|
|
#~ " let y: i16 = 1000;\n"
|
|
#~ "\n"
|
|
#~ " println!(\"{x} * {y} = {}\", multiply(x, y));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "The Rust integer types all implement the [`From<T>`](https://doc.rust-"
|
|
#~ "lang.org/std/convert/trait.From.html) and [`Into<T>`](https://doc.rust-"
|
|
#~ "lang.org/std/convert/trait.Into.html) traits to let us convert between "
|
|
#~ "them. The `From<T>` trait has a single `from()` method and similarly, the "
|
|
#~ "`Into<T>` trait has a single `into()` method. Implementing these traits "
|
|
#~ "is how a type expresses that it can be converted into another type."
|
|
#~ msgstr ""
|
|
#~ "러스트의 정수형 타입은 모두 [`From<T>`](https://doc.rust-lang.org/std/"
|
|
#~ "convert/trait.From.html) 와 [`Into<T>`](https://doc.rust-lang.org/std/"
|
|
#~ "convert/trait.Into.html) 트레잇을 구현하고 있으며, 이를 통해 타입 변환이 "
|
|
#~ "이루어 집니다. `From<T>` 트레잇은 `from()` 메서드를 가지고 있고, `Into<T>`"
|
|
#~ "트레잇은 `into()` 메서드를 가지고 있습니다. 러스트에서는 `From`과 `Into` "
|
|
#~ "트레잇을 구현함으로써, 타입 간 변환이 가능하다는 것을 표현합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "The standard library has an implementation of `From<i8> for i16`, which "
|
|
#~ "means that we can convert a variable `x` of type `i8` to an `i16` by "
|
|
#~ "calling `i16::from(x)`. Or, simpler, with `x.into()`, because `From<i8> "
|
|
#~ "for i16` implementation automatically create an implementation of "
|
|
#~ "`Into<i16> for i8`."
|
|
#~ msgstr ""
|
|
#~ "표준 라이브러리에는 `From<i8> for i16`가 구현되어 있는데 이것은 `i8` 타입"
|
|
#~ "의 변수 `x`를 `i16::from(x)`를 호출하여 `i16`타입으로 변환할 수 있다는 의"
|
|
#~ "미입니다. 혹은 더 간단하게 `x.into()`를 사용할 수도 있습니다. 이것이 가능"
|
|
#~ "한 이유는 `From<i8> for i16` 구현을 가지고 있으면 `Into<i16> for i8` 구현"
|
|
#~ "이 자동으로 생성되기 때문입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "The same applies for your own `From` implementations for your own types, "
|
|
#~ "so it is sufficient to only implement `From` to get a respective `Into` "
|
|
#~ "implementation automatically."
|
|
#~ msgstr ""
|
|
#~ "이는 사용자 정의 타입에도 동일하게 적용되는 규칙입니다. 따라서 `From`만을 "
|
|
#~ "구현해도 `Into`까지 자동으로 구현이 됩니다."
|
|
|
|
#~ msgid "Execute the above program and look at the compiler error."
|
|
#~ msgstr "위 예제코드를 실행하고 어떤 컴파일 에러가 발생하는지 확인해 보세요."
|
|
|
|
#~ msgid "Update the code above to use `into()` to do the conversion."
|
|
#~ msgstr "`into()`를 사용하여 코드를 수정하세요."
|
|
|
|
#~ msgid ""
|
|
#~ "Change the types of `x` and `y` to other things (such as `f32`, `bool`, "
|
|
#~ "`i128`) to see which types you can convert to which other types. Try "
|
|
#~ "converting small types to big types and the other way around. Check the "
|
|
#~ "[standard library documentation](https://doc.rust-lang.org/std/convert/"
|
|
#~ "trait.From.html) to see if `From<T>` is implemented for the pairs you "
|
|
#~ "check."
|
|
#~ msgstr ""
|
|
#~ "`x`와 `y`를 `f32`이나 `bool`, `i128` 등으로 바꿔서 해당 타입들로 변환이 되"
|
|
#~ "는지 확인해보세요. 작은 사이즈 타입에서 큰 사이즈로 변경해보시고 그 반대로"
|
|
#~ "도 해보세요. [표준 라이브러리 문서](https://doc.rust-lang.org/std/convert/"
|
|
#~ "trait.From.html)에서 시도해 본 케이스가 구현되어 있는지 확인해 보세요."
|
|
|
|
#~ msgid "Arrays and `for` Loops"
|
|
#~ msgstr "배열과 `for`반복문"
|
|
|
|
#~ msgid "We saw that an array can be declared like this:"
|
|
#~ msgstr "배열을 아래와 같이 선언 할 수 있음을 배웠습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust\n"
|
|
#~ "let array = [10, 20, 30];\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust\n"
|
|
#~ "let array = [10, 20, 30];\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "You can print such an array by asking for its debug representation with "
|
|
#~ "`{:?}`:"
|
|
#~ msgstr "배열을 출력하려면 `{:?}`를 씁니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let array = [10, 20, 30];\n"
|
|
#~ " println!(\"array: {array:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let array = [10, 20, 30];\n"
|
|
#~ " println!(\"array: {array:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Rust lets you iterate over things like arrays and ranges using the `for` "
|
|
#~ "keyword:"
|
|
#~ msgstr ""
|
|
#~ "러스트에서는 `for` 키워드를 사용해 배열이나 범위를 반복할 수 있습니다:"
|
|
|
|
#~ 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!();\n"
|
|
#~ "\n"
|
|
#~ " print!(\"Iterating over range:\");\n"
|
|
#~ " for i in 0..3 {\n"
|
|
#~ " print!(\" {}\", array[i]);\n"
|
|
#~ " }\n"
|
|
#~ " println!();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```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!();\n"
|
|
#~ "\n"
|
|
#~ " print!(\"Iterating over range:\");\n"
|
|
#~ " for i in 0..3 {\n"
|
|
#~ " print!(\" {}\", array[i]);\n"
|
|
#~ " }\n"
|
|
#~ " println!();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```bob\n"
|
|
#~ " ⎛⎡1 2 3⎤⎞ ⎡1 4 7⎤\n"
|
|
#~ "\"transpose\"⎜⎢4 5 6⎥⎟ \"==\"⎢2 5 8⎥\n"
|
|
#~ " ⎝⎣7 8 9⎦⎠ ⎣3 6 9⎦\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,should_panic\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "fn transpose(matrix: [[i32; 3]; 3]) -> [[i32; 3]; 3] {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn pretty_print(matrix: &[[i32; 3]; 3]) {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ "}\n"
|
|
#~ "\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"
|
|
#~ " ];\n"
|
|
#~ "\n"
|
|
#~ " println!(\"matrix:\");\n"
|
|
#~ " pretty_print(&matrix);\n"
|
|
#~ "\n"
|
|
#~ " let transposed = transpose(matrix);\n"
|
|
#~ " println!(\"transposed:\");\n"
|
|
#~ " pretty_print(&transposed);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,should_panic\n"
|
|
#~ "// TODO: 구현이 완료되면 아래 줄은 삭제합니다.\n"
|
|
#~ "#![allow(unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "fn transpose(matrix: [[i32; 3]; 3]) -> [[i32; 3]; 3] {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn pretty_print(matrix: &[[i32; 3]; 3]) {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ "}\n"
|
|
#~ "\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"
|
|
#~ " ];\n"
|
|
#~ "\n"
|
|
#~ " println!(\"matrix:\");\n"
|
|
#~ " pretty_print(&matrix);\n"
|
|
#~ "\n"
|
|
#~ " let transposed = transpose(matrix);\n"
|
|
#~ " println!(\"transposed:\");\n"
|
|
#~ " pretty_print(&transposed);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Bonus Question"
|
|
#~ msgstr "보너스 문제"
|
|
|
|
#~ msgid ""
|
|
#~ "Could you use `&[i32]` slices instead of hard-coded 3 × 3 matrices for "
|
|
#~ "your argument and return types? Something like `&[&[i32]]` for a two-"
|
|
#~ "dimensional slice-of-slices. Why or why not?"
|
|
#~ msgstr ""
|
|
#~ "`&[i32]`슬라이스를 잘 이용하면 행렬 크기를 3 x 3으로 하드코딩 하지 않을 "
|
|
#~ "수 있을까요? 예컨데 `&[&[i32]]`는 2차원 슬라이스의 슬라이스 입니다. 가능하"
|
|
#~ "다면/하지 않다면 왜 그런가요?"
|
|
|
|
#~ msgid ""
|
|
#~ "See the [`ndarray` crate](https://docs.rs/ndarray/) for a production "
|
|
#~ "quality implementation."
|
|
#~ msgstr ""
|
|
#~ "상용 품질의 구현에 대해서는 [`ndarray` 크레이트](https://docs.rs/ndarray/)"
|
|
#~ "를 참조하시기 바랍니다."
|
|
|
|
#~ msgid ""
|
|
#~ "The solution and the answer to the bonus section are available in the "
|
|
#~ "[Solution](solutions-morning.md#arrays-and-for-loops) section."
|
|
#~ msgstr ""
|
|
#~ "보너스 문제에 대한 답변 역시 [해답](solutions-morning.md#arrays-and-for-"
|
|
#~ "loops)에서 확인할 수 있습니다."
|
|
|
|
#~ 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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let x: i32 = 10;\n"
|
|
#~ " println!(\"x: {x}\");\n"
|
|
#~ " // x = 20;\n"
|
|
#~ " // println!(\"x: {x}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Due to type inference the `i32` is optional. We will gradually show the "
|
|
#~ "types less and less as the course progresses."
|
|
#~ msgstr ""
|
|
#~ "타입 추론에 덕분에 `i32`는 생략 가능합니다. 강의가 진행될 수록 생략 가능"
|
|
#~ "한 부분은 점점 생략할 것입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn takes_u32(x: u32) {\n"
|
|
#~ " println!(\"u32: {x}\");\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn takes_i8(y: i8) {\n"
|
|
#~ " println!(\"i8: {y}\");\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let x = 10;\n"
|
|
#~ " let y = 20;\n"
|
|
#~ "\n"
|
|
#~ " takes_u32(x);\n"
|
|
#~ " takes_i8(y);\n"
|
|
#~ " // takes_u32(y);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn takes_u32(x: u32) {\n"
|
|
#~ " println!(\"u32: {x}\");\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn takes_i8(y: i8) {\n"
|
|
#~ " println!(\"i8: {y}\");\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let x = 10;\n"
|
|
#~ " let y = 20;\n"
|
|
#~ "\n"
|
|
#~ " takes_u32(x);\n"
|
|
#~ " takes_i8(y);\n"
|
|
#~ " // takes_u32(y);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "아래 코드는, 제네릭 컨테이너를 쓸 때 컨테이터 안에 포함된 데이터의 타입을 "
|
|
#~ "명시적으로 쓰지 않고 `_`로 대체하여도 된다는 것을 보여줍니다:"
|
|
|
|
#~ 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:?}\");\n"
|
|
#~ "\n"
|
|
#~ " let vv = v.iter().collect::<std::collections::HashSet<_>>();\n"
|
|
#~ " println!(\"vv: {vv:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```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:?}\");\n"
|
|
#~ "\n"
|
|
#~ " let vv = v.iter().collect::<std::collections::HashSet<_>>();\n"
|
|
#~ " println!(\"vv: {vv:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "[`collect`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator."
|
|
#~ "html#method.collect) relies on [`FromIterator`](https://doc.rust-lang.org/"
|
|
#~ "std/iter/trait.FromIterator.html), which [`HashSet`](https://doc.rust-"
|
|
#~ "lang.org/std/collections/struct.HashSet.html#impl-FromIterator%3CT%3E-for-"
|
|
#~ "HashSet%3CT,+S%3E) implements."
|
|
#~ msgstr ""
|
|
#~ "[`collect`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator."
|
|
#~ "html#method.collect)는 [`HashSet`](https://doc.rust-lang.org/std/"
|
|
#~ "collections/struct.HashSet.html#impl-FromIterator%3CT%3E-for-HashSet%3CT,"
|
|
#~ "+S%3E)을 구현한 [`FromIterator`](https://doc.rust-lang.org/std/iter/trait."
|
|
#~ "FromIterator.html)에 의존합니다."
|
|
|
|
#~ msgid "Static and Constant Variables"
|
|
#~ msgstr "정적변수(static)과 상수(const)"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "const DIGEST_SIZE: usize = 3;\n"
|
|
#~ "const ZERO: Option<u8> = Some(42);\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let digest = compute_digest(\"Hello\");\n"
|
|
#~ " println!(\"Digest: {digest:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "const DIGEST_SIZE: usize = 3;\n"
|
|
#~ "const ZERO: Option<u8> = Some(42);\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let digest = compute_digest(\"Hello\");\n"
|
|
#~ " println!(\"Digest: {digest:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "static BANNER: &str = \"Welcome to RustOS 3.14\";\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"{BANNER}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "static BANNER: &str = \"Welcome to RustOS 3.14\";\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"{BANNER}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let a = 10;\n"
|
|
#~ " println!(\"before: {a}\");\n"
|
|
#~ "\n"
|
|
#~ " {\n"
|
|
#~ " let a = \"hello\";\n"
|
|
#~ " println!(\"inner scope: {a}\");\n"
|
|
#~ "\n"
|
|
#~ " let a = true;\n"
|
|
#~ " println!(\"shadowed in inner scope: {a}\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"after: {a}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let a = 10;\n"
|
|
#~ " println!(\"before: {a}\");\n"
|
|
#~ "\n"
|
|
#~ " {\n"
|
|
#~ " let a = \"hello\";\n"
|
|
#~ " println!(\"inner scope: {a}\");\n"
|
|
#~ "\n"
|
|
#~ " let a = true;\n"
|
|
#~ " println!(\"shadowed in inner scope: {a}\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"after: {a}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "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 ""
|
|
#~ "아래 코드는 불변 변수를 쉐도잉할 때 타입이 동일하더라도 새 변수가 원래 변"
|
|
#~ "수의 메모리 위치를 재사용 할 수 없는지 그 이유를 보여줍니다."
|
|
|
|
#~ 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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let a = 1;\n"
|
|
#~ " let b = &a;\n"
|
|
#~ " let a = a + 1;\n"
|
|
#~ " println!(\"{a} {b}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "First, let's refresh how memory management works."
|
|
#~ msgstr "우선 메모리 관리가 이뤄지는 방식을 다시 살펴 보겠습니다."
|
|
|
|
#~ msgid "The Stack vs The Heap"
|
|
#~ msgstr "스택(Stack)과 힙(Heap)"
|
|
|
|
#~ msgid "Stack and Heap Example"
|
|
#~ msgstr "스택과 힙에 관한 예제"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let s1 = String::from(\"Hello\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let s1 = String::from(\"Hello\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut s1 = String::from(\"Hello\");\n"
|
|
#~ " s1.push(' ');\n"
|
|
#~ " s1.push_str(\"world\");\n"
|
|
#~ " // DON'T DO THIS AT HOME! For educational purposes only.\n"
|
|
#~ " // String provides no guarantees about its layout, so this could lead "
|
|
#~ "to\n"
|
|
#~ " // undefined behavior.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " let (ptr, capacity, len): (usize, usize, usize) = std::mem::"
|
|
#~ "transmute(s1);\n"
|
|
#~ " println!(\"ptr = {ptr:#x}, len = {len}, capacity = "
|
|
#~ "{capacity}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut s1 = String::from(\"Hello\");\n"
|
|
#~ " s1.push(' ');\n"
|
|
#~ " s1.push_str(\"world\");\n"
|
|
#~ " // DON'T DO THIS AT HOME! For educational purposes only.\n"
|
|
#~ " // String provides no guarantees about its layout, so this could lead "
|
|
#~ "to\n"
|
|
#~ " // undefined behavior.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " let (ptr, capacity, len): (usize, usize, usize) = std::mem::"
|
|
#~ "transmute(s1);\n"
|
|
#~ " println!(\"ptr = {ptr:#x}, len = {len}, capacity = "
|
|
#~ "{capacity}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "You allocate and deallocate heap memory yourself."
|
|
#~ msgstr "사용자가 직접 메모리를 할당, 해제 합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "If not done with care, this can lead to crashes, bugs, security "
|
|
#~ "vulnerabilities, and memory leaks."
|
|
#~ msgstr ""
|
|
#~ "조심하지 않으면, 충돌(crash), 버그, 보안취약성 및 메모리 누출이 발생할 수 "
|
|
#~ "있습니다."
|
|
|
|
#~ msgid "C Example"
|
|
#~ msgstr "C 언어 예제"
|
|
|
|
#~ msgid "You must call `free` on every pointer you allocate with `malloc`:"
|
|
#~ msgstr "`malloc`으로 할당하는 포인터마다 `free`를 호출해야 합니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```c\n"
|
|
#~ "void foo(size_t n) {\n"
|
|
#~ " int* int_array = malloc(n * sizeof(int));\n"
|
|
#~ " //\n"
|
|
#~ " // ... lots of code\n"
|
|
#~ " //\n"
|
|
#~ " free(int_array);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```c\n"
|
|
#~ "void foo(size_t n) {\n"
|
|
#~ " int* int_array = malloc(n * sizeof(int));\n"
|
|
#~ " //\n"
|
|
#~ " // ... lots of code\n"
|
|
#~ " //\n"
|
|
#~ " free(int_array);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Memory is leaked if the function returns early between `malloc` and "
|
|
#~ "`free`: the pointer is lost and we cannot deallocate the memory. Worse, "
|
|
#~ "freeing the pointer twice, or accessing a freed pointer can lead to "
|
|
#~ "exploitable security vulnerabilities."
|
|
#~ msgstr ""
|
|
#~ "만약 `malloc` 과 `free` 사이에서 함수가 일찍 반환되면 메모리 누출이 일어납"
|
|
#~ "니다: 포인터를 잃어버리게 되어 메모리를 반환할 수 없게 됩니다. 같은 포인터"
|
|
#~ "를 두 번 반환하거나, 이미 반환된 포인터를 접근하는 것은 심각한 보안 문제"
|
|
#~ "를 일으킬 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Constructors and destructors let you hook into the lifetime of an object."
|
|
#~ msgstr ""
|
|
#~ "생성자와 소멸자를 사용하여 객체의 생명주기에 따라 메모리 할당/해제가 일어"
|
|
#~ "나도록 할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "By wrapping a pointer in an object, you can free memory when the object "
|
|
#~ "is destroyed. The compiler guarantees that this happens, even if an "
|
|
#~ "exception is raised."
|
|
#~ msgstr ""
|
|
#~ "포인터를 객체로 감싸도록 하면, 그 객체가 소멸될 때 그 포인터가 가리키는 메"
|
|
#~ "모리가 해제되도록 할 수 있습니다. 컴파일러는 객체가 소멸될 때 반드시 소멸"
|
|
#~ "자가 호출되는 것을 보장합니다. 심지어는 예외(exception)가 발생(_역주_: 함"
|
|
#~ "수의 리턴이나 스코프의 종료 뿐만이 아니라) 하더라도요."
|
|
|
|
#~ msgid ""
|
|
#~ "This is often called _resource acquisition is initialization_ (RAII) and "
|
|
#~ "gives you smart pointers."
|
|
#~ msgstr ""
|
|
#~ "이를 종종 RAII (Resource Acquisition Is Initialization)라고 하며, 이런 객"
|
|
#~ "체는 일종의 스마트 포인터 역할을 합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```c++\n"
|
|
#~ "void say_hello(std::unique_ptr<Person> person) {\n"
|
|
#~ " std::cout << \"Hello \" << person->name << std::endl;\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```c++\n"
|
|
#~ "void say_hello(std::unique_ptr<Person> person) {\n"
|
|
#~ " std::cout << \"Hello \" << person->name << std::endl;\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "The `std::unique_ptr` object is allocated on the stack, and points to "
|
|
#~ "memory allocated on the heap."
|
|
#~ msgstr ""
|
|
#~ "`std::unique_ptr`객체는 스택에 할당되며, 힙에 할당된 메모리를 가리킵니다."
|
|
|
|
#~ msgid ""
|
|
#~ "At the end of `say_hello`, the `std::unique_ptr` destructor will run."
|
|
#~ msgstr "`say_hello`함수가 끝나면 `std::unique_ptr`의 소멸자가 실행됩니다."
|
|
|
|
#~ msgid "The destructor frees the `Person` object it points to."
|
|
#~ msgstr "소멸자는 `Person` 객체가 가리키는 메모리를 해제합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Special move constructors are used when passing ownership to a function:"
|
|
#~ msgstr "이동 생성자는 함수 호출 시 소유권을 전달할때 사용됩니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```c++\n"
|
|
#~ "std::unique_ptr<Person> person = find_person(\"Carla\");\n"
|
|
#~ "say_hello(std::move(person));\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```c++\n"
|
|
#~ "std::unique_ptr<Person> person = find_person(\"Carla\");\n"
|
|
#~ "say_hello(std::move(person));\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "An alternative to manual and scope-based memory management is automatic "
|
|
#~ "memory management:"
|
|
#~ msgstr ""
|
|
#~ "수동, 스코프기반 메모리 관리의 대안으로 자동 메모리 관리 방식이 있습니다:"
|
|
|
|
#~ msgid "The programmer never allocates or deallocates memory explicitly."
|
|
#~ msgstr "개발자는 메모리를 명시적으로 할당/해제 하지 않습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "A garbage collector finds unused memory and deallocates it for the "
|
|
#~ "programmer."
|
|
#~ msgstr "가비지 컬렉터(GC)는 사용되지 않는 메모리를 찾아 해제합니다."
|
|
|
|
#~ msgid "Java Example"
|
|
#~ msgstr "Java 예제"
|
|
|
|
#~ msgid "The `person` object is not deallocated after `sayHello` returns:"
|
|
#~ msgstr ""
|
|
#~ "`person`객체는 `sayHello`함수 반환 후에도 해제되지 않습니다. (_역주_: GC"
|
|
#~ "가 나중에 알아서 해제합니다.)"
|
|
|
|
#~ msgid ""
|
|
#~ "```java\n"
|
|
#~ "void sayHello(Person person) {\n"
|
|
#~ " System.out.println(\"Hello \" + person.getName());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```java\n"
|
|
#~ "void sayHello(Person person) {\n"
|
|
#~ " System.out.println(\"Hello \" + person.getName());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Memory Management in Rust"
|
|
#~ msgstr "러스트에서의 메모리 관리"
|
|
|
|
#~ msgid "Memory management in Rust is a mix:"
|
|
#~ msgstr ""
|
|
#~ "러스트의 메모리 관리는 지금까지 설명한 방식들을 혼합해서 사용합니다:"
|
|
|
|
#~ msgid "Safe and correct like Java, but without a garbage collector."
|
|
#~ msgstr "자바처럼 안전하고 정확합니다. 하지만 GC는 없습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Depending on which abstraction (or combination of abstractions) you "
|
|
#~ "choose, can be a single unique pointer, reference counted, or atomically "
|
|
#~ "reference counted."
|
|
#~ msgstr ""
|
|
#~ "다양한 추상화를 제공합니다: 단일 포인터, 참조 카운트, 아토믹(atomic) 참조 "
|
|
#~ "카운트."
|
|
|
|
#~ msgid "Scope-based like C++, but the compiler enforces full adherence."
|
|
#~ msgstr ""
|
|
#~ "C++ 처럼 범위(스코프) 기반입니다. 하지만 컴파일러가 훨씬 더 엄격합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "A Rust user can choose the right abstraction for the situation, some even "
|
|
#~ "have no cost at runtime like C."
|
|
#~ msgstr ""
|
|
#~ "사용자는 상황에 따라 적합한 추상화를 선택할 수 있습니다. 그 중에는 C 언어 "
|
|
#~ "처럼 런타임 오버헤드가 없는 것도 있습니다."
|
|
|
|
#~ msgid "Rust achieves this by modeling _ownership_ explicitly."
|
|
#~ msgstr ""
|
|
#~ "러스트는 \\_소유권_을 언어 차원에서 명시적으로 모델링 함으로써 이를 이룹니"
|
|
#~ "다."
|
|
|
|
#~ msgid ""
|
|
#~ "If asked how at this point, you can mention that in Rust this is usually "
|
|
#~ "handled by RAII wrapper types such as [Box](https://doc.rust-lang.org/std/"
|
|
#~ "boxed/struct.Box.html), [Vec](https://doc.rust-lang.org/std/vec/struct."
|
|
#~ "Vec.html), [Rc](https://doc.rust-lang.org/std/rc/struct.Rc.html), or [Arc]"
|
|
#~ "(https://doc.rust-lang.org/std/sync/struct.Arc.html). These encapsulate "
|
|
#~ "ownership and memory allocation via various means, and prevent the "
|
|
#~ "potential errors in C."
|
|
#~ msgstr ""
|
|
#~ "이 시점에서 그게 어떻게 가능하냐는 질문이 있으면, 러스트에서 이 작업은 일"
|
|
#~ "반적으로 [Box](https://doc.rust-lang.org/std/boxed/struct.Box.html), [Vec]"
|
|
#~ "(https://doc.rust-lang.org/std/vec/struct.Vec.html), [Rc](https://doc."
|
|
#~ "rust-lang.org/std/rc/struct.Rc.html) 또는 [Arc](https://doc.rust-lang.org/"
|
|
#~ "std/sync/struct.Arc.html)와 같은 RAII 타입에 의해 처리된다고 답변할 수 있"
|
|
#~ "습니다. 이들은 다양한 방법을 통해 소유권과 메모리 할당에 대한 구체적인 내"
|
|
#~ "용을을 캡슐화하여, C 언어였다면 발생할 수 있었을 다양한 에러를 막습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "You may be asked about destructors here, the [Drop](https://doc.rust-lang."
|
|
#~ "org/std/ops/trait.Drop.html) trait is the Rust equivalent."
|
|
#~ msgstr ""
|
|
#~ "소멸자에 대한 질문도 있을 수 있습니다. [Drop](https://doc.rust-lang.org/"
|
|
#~ "std/ops/trait.Drop.html) 트레잇이 답입니다."
|
|
|
|
#~ msgid "Here is a rough comparison of the memory management techniques."
|
|
#~ msgstr "메모리 관리 기술의 대략적인 비교입니다."
|
|
|
|
#~ msgid "Pros of Different Memory Management Techniques"
|
|
#~ msgstr "메모리 관리 방법 별 장점"
|
|
|
|
#~ msgid "Manual like C:"
|
|
#~ msgstr "C와 같은 수동 관리:"
|
|
|
|
#~ msgid "No runtime overhead."
|
|
#~ msgstr "런타임 오버헤드가 없음."
|
|
|
|
#~ msgid "Automatic like Java:"
|
|
#~ msgstr "JAVA와 같은 자동화 관리:"
|
|
|
|
#~ msgid "Fully automatic."
|
|
#~ msgstr "완전한 자동화."
|
|
|
|
#~ msgid "Safe and correct."
|
|
#~ msgstr "안전하고 정확함."
|
|
|
|
#~ msgid "Scope-based like C++:"
|
|
#~ msgstr "C++ 와 같은 범위 기반 관리:"
|
|
|
|
#~ msgid "Partially automatic."
|
|
#~ msgstr "부분 자동화."
|
|
|
|
#~ msgid "Compiler-enforced scope-based like Rust:"
|
|
#~ msgstr "러스트와 같은 컴파일러 수행 범위 기반 관리:"
|
|
|
|
#~ msgid "Enforced by compiler."
|
|
#~ msgstr "컴파일러에 의해 수행됩니다."
|
|
|
|
#~ msgid "Cons of Different Memory Management Techniques"
|
|
#~ msgstr "메모리 관리 방법 별 단점"
|
|
|
|
#~ msgid "Use-after-free."
|
|
#~ msgstr "사용 후 해제 문제."
|
|
|
|
#~ msgid "Double-frees."
|
|
#~ msgstr "이중 해제 문제."
|
|
|
|
#~ msgid "Memory leaks."
|
|
#~ msgstr "메모리 누출 문제."
|
|
|
|
#~ msgid "Garbage collection pauses."
|
|
#~ msgstr "GC동작으로 인한 멈춤."
|
|
|
|
#~ msgid "Destructor delays."
|
|
#~ msgstr ""
|
|
#~ "소멸자 지연 (_역주_: 특정 메모리를 더이상 사용하지 않더라도 곧바로 해제 되"
|
|
#~ "지 않고 GC가 동작할 때 까지 기다려야 한다는 점)"
|
|
|
|
#~ msgid "Complex, opt-in by programmer (on C++)."
|
|
#~ msgstr "복잡하며, 개발자의 선택사항임."
|
|
|
|
#~ msgid "Circular references can lead to memory leaks"
|
|
#~ msgstr "순환 참조가 발생하면 메모리 누수가 발생함"
|
|
|
|
#~ msgid "Potential runtime overhead"
|
|
#~ msgstr "런타임 오버헤드 있을 수 있음"
|
|
|
|
#~ msgid "Compiler-enforced and scope-based like Rust:"
|
|
#~ msgstr "러스트와 같은 컴파일러가 강제하는 수행 범위 기반 관리:"
|
|
|
|
#~ msgid "Some upfront complexity."
|
|
#~ msgstr "처음에 배울 때 어려움."
|
|
|
|
#~ msgid "Can reject valid programs."
|
|
#~ msgstr "올바른 프로그램이더라도 컴파일러가 거부할 수 있음."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " {\n"
|
|
#~ " let p = Point(3, 4);\n"
|
|
#~ " println!(\"x: {}\", p.0);\n"
|
|
#~ " }\n"
|
|
#~ " println!(\"y: {}\", p.1);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " {\n"
|
|
#~ " let p = Point(3, 4);\n"
|
|
#~ " println!(\"x: {}\", p.0);\n"
|
|
#~ " }\n"
|
|
#~ " println!(\"y: {}\", p.1);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "A destructor can run here to free up resources."
|
|
#~ msgstr ""
|
|
#~ "스코프가 종료될 때 다른 리소스를 해제하기 위해 소멸자가 호출되도록 할 수 "
|
|
#~ "있습니다."
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid "There is always _exactly_ one variable binding which owns a value."
|
|
#~ msgstr "값(데이터)의 소유권을 갖는 변수는 항상 _단_ 하나 입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let s1: String = String::from(\"Rust\");\n"
|
|
#~ " let s2: String = s1;\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let s1: String = String::from(\"Rust\");\n"
|
|
#~ " let s2: String = s1;\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "The heap data from `s1` is reused for `s2`."
|
|
#~ msgstr "`s1`의 힙 데이터는 `s2`에서 재사용 됩니다."
|
|
|
|
#~ msgid ""
|
|
#~ "When `s1` goes out of scope, nothing happens (it has been moved from)."
|
|
#~ msgstr ""
|
|
#~ "`s1`의 스코프가 종료되면 아무일도 일어나지 않습니다.(이미 이동되었습니다.)"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid "Extra Work in Modern C++"
|
|
#~ msgstr "Modern C++에서 이중해제 문제"
|
|
|
|
#~ msgid ""
|
|
#~ "```c++\n"
|
|
#~ "std::string s1 = \"Cpp\";\n"
|
|
#~ "std::string s2 = s1; // Duplicate the data in s1.\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```c++\n"
|
|
#~ "std::string s1 = \"Cpp\";\n"
|
|
#~ "std::string s2 = s1; // s1의 데이터를 복제합니다.\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn say_hello(name: String) {\n"
|
|
#~ " println!(\"Hello {name}\")\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let name = String::from(\"Alice\");\n"
|
|
#~ " say_hello(name);\n"
|
|
#~ " // say_hello(name);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn say_hello(name: String) {\n"
|
|
#~ " println!(\"Hello {name}\")\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let name = String::from(\"Alice\");\n"
|
|
#~ " say_hello(name);\n"
|
|
#~ " // say_hello(name);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let x = 42;\n"
|
|
#~ " let y = x;\n"
|
|
#~ " println!(\"x: {x}\");\n"
|
|
#~ " println!(\"y: {y}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Copy, Clone, Debug)]\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let p1 = Point(3, 4);\n"
|
|
#~ " let p2 = p1;\n"
|
|
#~ " println!(\"p1: {p1:?}\");\n"
|
|
#~ " println!(\"p2: {p2:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Copy, Clone, Debug)]\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let p1 = Point(3, 4);\n"
|
|
#~ " let p2 = p1;\n"
|
|
#~ " println!(\"p1: {p1:?}\");\n"
|
|
#~ " println!(\"p2: {p2:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "If students ask about `derive`, it is sufficient to say that this is a "
|
|
#~ "way to generate code in Rust at compile time. In this case the default "
|
|
#~ "implementations of `Copy` and `Clone` traits are generated."
|
|
#~ msgstr ""
|
|
#~ "만약 학생들이 `derive`에 대해 묻는다면, 컴파일 시 러스트에서 코드를 생성하"
|
|
#~ "는방법이라고 말하는 것으로 충분합니다. 위 경우 `Copy`와 `Clone` 트레잇에 "
|
|
#~ "대한 기본 구현이 생성됩니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "fn add(p1: &Point, p2: &Point) -> Point {\n"
|
|
#~ " Point(p1.0 + p2.0, p1.1 + p2.1)\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "fn add(p1: &Point, p2: &Point) -> Point {\n"
|
|
#~ " Point(p1.0 + p2.0, p1.1 + p2.1)\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub 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"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub 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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut a: i32 = 10;\n"
|
|
#~ " let b: &i32 = &a;\n"
|
|
#~ "\n"
|
|
#~ " {\n"
|
|
#~ " let c: &mut i32 = &mut a;\n"
|
|
#~ " *c = 20;\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"a: {a}\");\n"
|
|
#~ " println!(\"b: {b}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut a: i32 = 10;\n"
|
|
#~ " let b: &i32 = &a;\n"
|
|
#~ "\n"
|
|
#~ " {\n"
|
|
#~ " let c: &mut i32 = &mut a;\n"
|
|
#~ " *c = 20;\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"a: {a}\");\n"
|
|
#~ " println!(\"b: {b}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "A borrowed value has a _lifetime_:"
|
|
#~ msgstr "빌려온 값은 _수명_을 갖습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "The lifetime can be implicit: `add(p1: &Point, p2: &Point) -> Point`."
|
|
#~ msgstr "수명은 생략할 수 있습니다: `add(p1: &Point, p2: &Point) -> Point`."
|
|
|
|
#~ msgid "Lifetimes can also be explicit: `&'a Point`, `&'document str`."
|
|
#~ msgstr "물론 명시할 수도 있습니다: `&'a Point`, `&'document str`."
|
|
|
|
#~ msgid ""
|
|
#~ "Read `&'a Point` as \"a borrowed `Point` which is valid for at least the "
|
|
#~ "lifetime `a`\"."
|
|
#~ msgstr ""
|
|
#~ "`&'a Point` 는 `Point`의 수명이 최소한 `'a`라는 수명보다는 같거나 더 길다"
|
|
#~ "는 것을 의미합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Lifetimes are always inferred by the compiler: you cannot assign a "
|
|
#~ "lifetime yourself."
|
|
#~ msgstr ""
|
|
#~ "수명은 항상 컴파일러가 자동으로 추론합니다. 직접 수명을 지정할 수는 없습니"
|
|
#~ "다."
|
|
|
|
#~ msgid ""
|
|
#~ "In addition to borrowing its arguments, a function can return a borrowed "
|
|
#~ "value:"
|
|
#~ msgstr "함수는 인수를 빌리는 것 외에도 빌린 값을 반환할 수 있습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n"
|
|
#~ " if p1.0 < p2.0 { p1 } else { p2 }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n"
|
|
#~ " if p1.0 < p2.0 { p1 } else { p2 }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid "`'a` is a generic parameter, it is inferred by the compiler."
|
|
#~ msgstr "`'a`는 제네릭 매개변수로 컴파일러로에 의해 추론됩니다."
|
|
|
|
#~ msgid "Lifetimes start with `'` and `'a` is a typical default name."
|
|
#~ msgstr "수명의 이름은 `'` 로 시작하며 보통 `'a`를 많이 씁니다."
|
|
|
|
#~ msgid ""
|
|
#~ "The _at least_ part is important when parameters are in different scopes."
|
|
#~ msgstr ""
|
|
#~ "매개변수들이 서로 다른 스코프에 있을 경우 \"최소한\"이라는 조건이 중요합니"
|
|
#~ "다."
|
|
|
|
#~ msgid ""
|
|
#~ "Move the declaration of `p2` and `p3` into a new scope (`{ ... }`), "
|
|
#~ "resulting in the following code:"
|
|
#~ msgstr ""
|
|
#~ "`p2`와 `p3`를 새로운 범위(`{...}`)로 아래 코드와 같이 이동해 봅니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n"
|
|
#~ " if p1.0 < p2.0 { p1 } else { p2 }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n"
|
|
#~ " if p1.0 < p2.0 { p1 } else { p2 }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid "Note how this does not compile since `p3` outlives `p2`."
|
|
#~ msgstr ""
|
|
#~ "`p3`의 수명이 `p2` 보다 길기 때문에 이 예제는 컴파일되지 않음을 확인하시"
|
|
#~ "기 바랍니다."
|
|
|
|
#~ 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."
|
|
#~ msgstr ""
|
|
#~ "작업공간을 초기화 한 후 함수 시그니처를 `fn left_most<'a, 'b>(p1: &'a "
|
|
#~ "Point, p2: &'a Point) -> &'b Point`로 변경해 봅니다. 이 경우 `'a`와 `'b`사"
|
|
#~ "이의 관계가 불분명하기 때문에 컴파일 되지 않습니다."
|
|
|
|
#~ msgid "Another way to explain it:"
|
|
#~ msgstr "이 에러를 설명하는 또 다른 방법은 다음과 같습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "Two references to two values are borrowed by a function and the function "
|
|
#~ "returns another reference."
|
|
#~ msgstr "이 함수는 두 값을 빌려서, 새로운 참조를 반환합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "It must have come from one of those two inputs (or from a global "
|
|
#~ "variable)."
|
|
#~ msgstr ""
|
|
#~ "이 반환된 참조는 두 입력 중 하나로 부터 와야 합니다. (아니면 전역 변수로 "
|
|
#~ "부터)"
|
|
|
|
#~ msgid ""
|
|
#~ "Which one is it? The compiler needs to know, so at the call site the "
|
|
#~ "returned reference is not used for longer than a variable from where the "
|
|
#~ "reference came from."
|
|
#~ msgstr ""
|
|
#~ "두 입력 중 어떤 것일까요? 컴파일러는 이를 알아야 합니다. 그래야만 함수 호"
|
|
#~ "출부에서 봤을 때, 반환된 참조의 수명이 원래 값을 수명보다 길지 않음을 확인"
|
|
#~ "할 수 있기 때문입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Highlight<'doc>(&'doc str);\n"
|
|
#~ "\n"
|
|
#~ "fn erase(text: String) {\n"
|
|
#~ " println!(\"Bye {text}!\");\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Highlight<'doc>(&'doc str);\n"
|
|
#~ "\n"
|
|
#~ "fn erase(text: String) {\n"
|
|
#~ " println!(\"Bye {text}!\");\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid "Day 1: Afternoon Exercises"
|
|
#~ msgstr "1일차 오후 연습문제"
|
|
|
|
#~ msgid "We will look at two things:"
|
|
#~ msgstr "이번 연습문제는 아래 두가지입니다:"
|
|
|
|
#~ msgid "A small book library,"
|
|
#~ msgstr "작은 도서관,"
|
|
|
|
#~ msgid "Iterators and ownership (hard)."
|
|
#~ msgstr "반복자와 소유권 (어려움)"
|
|
|
|
#~ msgid ""
|
|
#~ "We will learn much more about structs and the `Vec<T>` type tomorrow. For "
|
|
#~ "now, you just need to know part of its API:"
|
|
#~ msgstr ""
|
|
#~ "우리는 내일 구조체와 `Vec<T>`에 대해 더 많은 것을 배울 것입니다. 일단 오늘"
|
|
#~ "은 API의 일부만 알면 됩니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut vec = vec![10, 20];\n"
|
|
#~ " vec.push(30);\n"
|
|
#~ " let midpoint = vec.len() / 2;\n"
|
|
#~ " println!(\"middle value: {}\", vec[midpoint]);\n"
|
|
#~ " for item in &vec {\n"
|
|
#~ " println!(\"item: {item}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut vec = vec![10, 20];\n"
|
|
#~ " vec.push(30);\n"
|
|
#~ " let midpoint = vec.len() / 2;\n"
|
|
#~ " println!(\"middle value: {}\", vec[midpoint]);\n"
|
|
#~ " for item in &vec {\n"
|
|
#~ " println!(\"item: {item}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Use this to model a library's book collection. Copy the code below to "
|
|
#~ "<https://play.rust-lang.org/> and update the types to make it compile:"
|
|
#~ msgstr ""
|
|
#~ "아래 코드는 도서관에 있는 도서 컬랙션을 모델링 합니다. 아래 코드를 "
|
|
#~ "<https://play.rust-lang.org/>에 복사한 후, 컴파일 되도록 수정해 봅시다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,should_panic\n"
|
|
#~ "struct Library {\n"
|
|
#~ " books: Vec<Book>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "struct Book {\n"
|
|
#~ " title: String,\n"
|
|
#~ " year: u16,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// Implement the methods below. Update the `self` parameter to\n"
|
|
#~ "// indicate the method's required level of ownership over the object:\n"
|
|
#~ "//\n"
|
|
#~ "// - `&self` for shared read-only access,\n"
|
|
#~ "// - `&mut self` for unique and mutable access,\n"
|
|
#~ "// - `self` for unique access by value.\n"
|
|
#~ "impl Library {\n"
|
|
#~ " fn new() -> Library {\n"
|
|
#~ " todo!(\"Initialize and return a `Library` value\")\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " //fn len(self) -> usize {\n"
|
|
#~ " // todo!(\"Return the length of `self.books`\")\n"
|
|
#~ " //}\n"
|
|
#~ "\n"
|
|
#~ " //fn is_empty(self) -> bool {\n"
|
|
#~ " // todo!(\"Return `true` if `self.books` is empty\")\n"
|
|
#~ " //}\n"
|
|
#~ "\n"
|
|
#~ " //fn add_book(self, book: Book) {\n"
|
|
#~ " // todo!(\"Add a new book to `self.books`\")\n"
|
|
#~ " //}\n"
|
|
#~ "\n"
|
|
#~ " //fn print_books(self) {\n"
|
|
#~ " // todo!(\"Iterate over `self.books` and each book's title and "
|
|
#~ "year\")\n"
|
|
#~ " //}\n"
|
|
#~ "\n"
|
|
#~ " //fn oldest_book(self) -> Option<&Book> {\n"
|
|
#~ " // todo!(\"Return a reference to the oldest book (if any)\")\n"
|
|
#~ " //}\n"
|
|
#~ "}\n"
|
|
#~ "\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();\n"
|
|
#~ "\n"
|
|
#~ " //println!(\"The library is empty: 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"
|
|
#~ " //println!(\"The library is no longer empty: library.is_empty() -> "
|
|
#~ "{}\", library.is_empty());\n"
|
|
#~ " //\n"
|
|
#~ " //\n"
|
|
#~ " //library.print_books();\n"
|
|
#~ " //\n"
|
|
#~ " //match library.oldest_book() {\n"
|
|
#~ " // Some(book) => println!(\"The oldest book is {}\", book.title),\n"
|
|
#~ " // None => println!(\"The library is empty!\"),\n"
|
|
#~ " //}\n"
|
|
#~ " //\n"
|
|
#~ " //println!(\"The library has {} books\", library.len());\n"
|
|
#~ " //library.print_books();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,should_panic\n"
|
|
#~ "struct Library {\n"
|
|
#~ " books: Vec<Book>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "struct Book {\n"
|
|
#~ " title: String,\n"
|
|
#~ " year: u16,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// Implement the methods below. Update the `self` parameter to\n"
|
|
#~ "// indicate the method's required level of ownership over the object:\n"
|
|
#~ "//\n"
|
|
#~ "// - `&self` for shared read-only access,\n"
|
|
#~ "// - `&mut self` for unique and mutable access,\n"
|
|
#~ "// - `self` for unique access by value.\n"
|
|
#~ "impl Library {\n"
|
|
#~ " fn new() -> Library {\n"
|
|
#~ " todo!(\"Initialize and return a `Library` value\")\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " //fn len(self) -> usize {\n"
|
|
#~ " // todo!(\"Return the length of `self.books`\")\n"
|
|
#~ " //}\n"
|
|
#~ "\n"
|
|
#~ " //fn is_empty(self) -> bool {\n"
|
|
#~ " // todo!(\"Return `true` if `self.books` is empty\")\n"
|
|
#~ " //}\n"
|
|
#~ "\n"
|
|
#~ " //fn add_book(self, book: Book) {\n"
|
|
#~ " // todo!(\"Add a new book to `self.books`\")\n"
|
|
#~ " //}\n"
|
|
#~ "\n"
|
|
#~ " //fn print_books(self) {\n"
|
|
#~ " // todo!(\"Iterate over `self.books` and each book's title and "
|
|
#~ "year\")\n"
|
|
#~ " //}\n"
|
|
#~ "\n"
|
|
#~ " //fn oldest_book(self) -> Option<&Book> {\n"
|
|
#~ " // todo!(\"Return a reference to the oldest book (if any)\")\n"
|
|
#~ " //}\n"
|
|
#~ "}\n"
|
|
#~ "\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();\n"
|
|
#~ "\n"
|
|
#~ " //println!(\"The library is empty: 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"
|
|
#~ " //println!(\"The library is no longer empty: library.is_empty() -> "
|
|
#~ "{}\", library.is_empty());\n"
|
|
#~ " //\n"
|
|
#~ " //\n"
|
|
#~ " //library.print_books();\n"
|
|
#~ " //\n"
|
|
#~ " //match library.oldest_book() {\n"
|
|
#~ " // Some(book) => println!(\"The oldest book is {}\", book.title),\n"
|
|
#~ " // None => println!(\"The library is empty!\"),\n"
|
|
#~ " //}\n"
|
|
#~ " //\n"
|
|
#~ " //println!(\"The library has {} books\", library.len());\n"
|
|
#~ " //library.print_books();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "[Solution](solutions-afternoon.md#designing-a-library)"
|
|
#~ msgstr "[해답](solutions-afternoon.md#designing-a-library)"
|
|
|
|
#~ msgid ""
|
|
#~ "The ownership model of Rust affects many APIs. An example of this is the "
|
|
#~ "[`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html) and "
|
|
#~ "[`IntoIterator`](https://doc.rust-lang.org/std/iter/trait.IntoIterator."
|
|
#~ "html) traits."
|
|
#~ msgstr ""
|
|
#~ "러스트의 소유권 모델은 많은 API에 반영이 되어 있습니다. 예를들어 "
|
|
#~ "[`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html) 와 "
|
|
#~ "[`IntoIterator`](https://doc.rust-lang.org/std/iter/trait.IntoIterator."
|
|
#~ "html) 같은 트레잇이 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Traits are like interfaces: they describe behavior (methods) for a type. "
|
|
#~ "The `Iterator` trait simply says that you can call `next` until you get "
|
|
#~ "`None` back:"
|
|
#~ msgstr ""
|
|
#~ "트레잇은 타입에 대한 행동(메서드)를 설명한다는 점에서 인터페이스와 유사합"
|
|
#~ "니다. `Iterator`는 단순히 `None`이 나올때까지 `next`를 호출하는 것이 가능"
|
|
#~ "하다는 것을 나타내는 트레잇입니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust\n"
|
|
#~ "pub trait Iterator {\n"
|
|
#~ " type Item;\n"
|
|
#~ " fn next(&mut self) -> Option<Self::Item>;\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust\n"
|
|
#~ "pub trait Iterator {\n"
|
|
#~ " type Item;\n"
|
|
#~ " fn next(&mut self) -> Option<Self::Item>;\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "You use this trait like this:"
|
|
#~ msgstr "`Iterator` 트레잇은 이렇게 사용합니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v: Vec<i8> = vec![10, 20, 30];\n"
|
|
#~ " let mut iter = v.iter();\n"
|
|
#~ "\n"
|
|
#~ " 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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v: Vec<i8> = vec![10, 20, 30];\n"
|
|
#~ " let mut iter = v.iter();\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ "```"
|
|
|
|
#~ msgid "What is the type returned by the iterator? Test your answer here:"
|
|
#~ msgstr ""
|
|
#~ "반복자가 반환하는 값들은 타입이 뭘까요? 여기서 답을 테스트 해 보세요:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v: Vec<i8> = vec![10, 20, 30];\n"
|
|
#~ " let mut iter = v.iter();\n"
|
|
#~ "\n"
|
|
#~ " let v0: Option<..> = iter.next();\n"
|
|
#~ " println!(\"v0: {v0:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v: Vec<i8> = vec![10, 20, 30];\n"
|
|
#~ " let mut iter = v.iter();\n"
|
|
#~ "\n"
|
|
#~ " let v0: Option<..> = iter.next();\n"
|
|
#~ " println!(\"v0: {v0:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Why is this type used?"
|
|
#~ msgstr "왜 이런 타입이 사용되는 것일까요?"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust\n"
|
|
#~ "pub trait IntoIterator {\n"
|
|
#~ " type Item;\n"
|
|
#~ " type IntoIter: Iterator<Item = Self::Item>;\n"
|
|
#~ "\n"
|
|
#~ " fn into_iter(self) -> Self::IntoIter;\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust\n"
|
|
#~ "pub trait IntoIterator {\n"
|
|
#~ " type Item;\n"
|
|
#~ " type IntoIter: Iterator<Item = Self::Item>;\n"
|
|
#~ "\n"
|
|
#~ " fn into_iter(self) -> Self::IntoIter;\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Like before, what is the type returned by the iterator?"
|
|
#~ msgstr "이전과 마찬가지로, 반복자가 반환하는 타입은 무엇입니까?"
|
|
|
|
#~ 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();\n"
|
|
#~ "\n"
|
|
#~ " let v0: Option<..> = iter.next();\n"
|
|
#~ " println!(\"v0: {v0:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```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();\n"
|
|
#~ "\n"
|
|
#~ " let v0: Option<..> = iter.next();\n"
|
|
#~ " println!(\"v0: {v0:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Now that we know both `Iterator` and `IntoIterator`, we can build `for` "
|
|
#~ "loops. They call `into_iter()` on an expression and iterates over the "
|
|
#~ "resulting iterator:"
|
|
#~ msgstr ""
|
|
#~ "자, 이제 우리는 `Iterator`와 `IntoIterator`를 알았으므로 `for` 루프를 만"
|
|
#~ "들 수 있습니다. `for` 루프는 `into_iter()`를 호출하여 반복자를 만든 다음 "
|
|
#~ "그 반복자를 이용하여 요소들을 반복해서 접근합니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v: Vec<String> = vec![String::from(\"foo\"), String::"
|
|
#~ "from(\"bar\")];\n"
|
|
#~ "\n"
|
|
#~ " for word in &v {\n"
|
|
#~ " println!(\"word: {word}\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " for word in v {\n"
|
|
#~ " println!(\"word: {word}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v: Vec<String> = vec![String::from(\"foo\"), String::"
|
|
#~ "from(\"bar\")];\n"
|
|
#~ "\n"
|
|
#~ " for word in &v {\n"
|
|
#~ " println!(\"word: {word}\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " for word in v {\n"
|
|
#~ " println!(\"word: {word}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Experiment with the code above and then consult the documentation for "
|
|
#~ "[`impl IntoIterator for &Vec<T>`](https://doc.rust-lang.org/std/vec/"
|
|
#~ "struct.Vec.html#impl-IntoIterator-for-%26'a+Vec%3CT,+A%3E) and [`impl "
|
|
#~ "IntoIterator for Vec<T>`](https://doc.rust-lang.org/std/vec/struct.Vec."
|
|
#~ "html#impl-IntoIterator-for-Vec%3CT,+A%3E) to check your answers."
|
|
#~ msgstr ""
|
|
#~ "위 코드에서 실험 해 본 후, 다음 문서를 참조해서 답변을 확인하시기 바랍니"
|
|
#~ "다:[`impl IntoIterator for &Vec<T>`](https://doc.rust-lang.org/std/vec/"
|
|
#~ "struct.Vec.html#impl-IntoIterator-for-%26'a+Vec%3CT,+A%3E), [`impl "
|
|
#~ "IntoIterator for Vec<T>`](https://doc.rust-lang.org/std/vec/struct.Vec."
|
|
#~ "html#impl-IntoIterator-for-Vec%3CT%2C%20A%3E)"
|
|
|
|
#~ msgid "Structs, enums, methods."
|
|
#~ msgstr "구조체, 열거형, 메서드."
|
|
|
|
#~ msgid ""
|
|
#~ "Control flow constructs: `if`, `if let`, `while`, `while let`, `break`, "
|
|
#~ "and `continue`."
|
|
#~ msgstr ""
|
|
#~ "흐름 제어: `if`, `if let`, `while`, `while let`, `break`, 그리고 "
|
|
#~ "`continue`."
|
|
|
|
#~ msgid ""
|
|
#~ "The Standard Library: `String`, `Option` and `Result`, `Vec`, `HashMap`, "
|
|
#~ "`Rc` and `Arc`."
|
|
#~ msgstr ""
|
|
#~ "표준 라이브러리: `String`, `Option` 과 `Result`, `Vec`, `HashMap`, `Rc` 그"
|
|
#~ "리고 `Arc`."
|
|
|
|
#~ msgid "Modules: visibility, paths, and filesystem hierarchy."
|
|
#~ msgstr "모듈: 가시성, 경로 및 파일 시스템 계층."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "struct Person {\n"
|
|
#~ " name: String,\n"
|
|
#~ " age: u8,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "struct Person {\n"
|
|
#~ " name: String,\n"
|
|
#~ " age: u8,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Methods are defined in an `impl` block, which we will see in following "
|
|
#~ "slides."
|
|
#~ msgstr ""
|
|
#~ "메서드는 `impl`블록에 정의 합니다. 다음 슬라이드에서 확인 할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let p = Point(17, 23);\n"
|
|
#~ " println!(\"({}, {})\", p.0, p.1);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "struct Point(i32, i32);\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let p = Point(17, 23);\n"
|
|
#~ " println!(\"({}, {})\", p.0, p.1);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "struct PoundsOfForce(f64);\n"
|
|
#~ "struct Newtons(f64);\n"
|
|
#~ "\n"
|
|
#~ "fn compute_thruster_force() -> PoundsOfForce {\n"
|
|
#~ " todo!(\"Ask a rocket scientist at NASA\")\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn set_thruster_force(force: Newtons) {\n"
|
|
#~ " // ...\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let force = compute_thruster_force();\n"
|
|
#~ " set_thruster_force(force);\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "struct PoundsOfForce(f64);\n"
|
|
#~ "struct Newtons(f64);\n"
|
|
#~ "\n"
|
|
#~ "fn compute_thruster_force() -> PoundsOfForce {\n"
|
|
#~ " todo!(\"Ask a rocket scientist at NASA\")\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn set_thruster_force(force: Newtons) {\n"
|
|
#~ " // ...\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let force = compute_thruster_force();\n"
|
|
#~ " set_thruster_force(force);\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Person {\n"
|
|
#~ " name: String,\n"
|
|
#~ " age: u8,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Person {\n"
|
|
#~ " fn new(name: String, age: u8) -> Person {\n"
|
|
#~ " Person { name, age }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let peter = Person::new(String::from(\"Peter\"), 27);\n"
|
|
#~ " println!(\"{peter:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Person {\n"
|
|
#~ " name: String,\n"
|
|
#~ " age: u8,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Person {\n"
|
|
#~ " fn new(name: String, age: u8) -> Person {\n"
|
|
#~ " Person { name, age }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let peter = Person::new(String::from(\"Peter\"), 27);\n"
|
|
#~ " println!(\"{peter:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "The `new` function could be written using `Self` as a type, as it is "
|
|
#~ "interchangeable with the struct type name"
|
|
#~ msgstr ""
|
|
#~ "`new`함수를 다음처럼 구조체 이름 대신 `Self`를 사용하여 작성해도 됩니다"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Person {\n"
|
|
#~ " name: String,\n"
|
|
#~ " age: u8,\n"
|
|
#~ "}\n"
|
|
#~ "impl Person {\n"
|
|
#~ " fn new(name: String, age: u8) -> Self {\n"
|
|
#~ " Self { name, age }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Person {\n"
|
|
#~ " name: String,\n"
|
|
#~ " age: u8,\n"
|
|
#~ "}\n"
|
|
#~ "impl Person {\n"
|
|
#~ " fn new(name: String, age: u8) -> Self {\n"
|
|
#~ " Self { name, age }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Implement the `Default` trait for the struct. Define some fields and use "
|
|
#~ "the default values for the other fields."
|
|
#~ msgstr ""
|
|
#~ "`Default` 트레잇을 구현해보세요. 필드 몇개는 초기화하고 나머지 필드는 디폴"
|
|
#~ "트 값을 사용할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Person {\n"
|
|
#~ " name: String,\n"
|
|
#~ " age: u8,\n"
|
|
#~ "}\n"
|
|
#~ "impl Default for Person {\n"
|
|
#~ " fn default() -> Person {\n"
|
|
#~ " Person {\n"
|
|
#~ " name: \"Bot\".to_string(),\n"
|
|
#~ " age: 0,\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "fn create_default() {\n"
|
|
#~ " let tmp = Person {\n"
|
|
#~ " ..Person::default()\n"
|
|
#~ " };\n"
|
|
#~ " let tmp = Person {\n"
|
|
#~ " name: \"Sam\".to_string(),\n"
|
|
#~ " ..Person::default()\n"
|
|
#~ " };\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Person {\n"
|
|
#~ " name: String,\n"
|
|
#~ " age: u8,\n"
|
|
#~ "}\n"
|
|
#~ "impl Default for Person {\n"
|
|
#~ " fn default() -> Person {\n"
|
|
#~ " Person {\n"
|
|
#~ " name: \"Bot\".to_string(),\n"
|
|
#~ " age: 0,\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "fn create_default() {\n"
|
|
#~ " let tmp = Person {\n"
|
|
#~ " ..Person::default()\n"
|
|
#~ " };\n"
|
|
#~ " let tmp = Person {\n"
|
|
#~ " name: \"Sam\".to_string(),\n"
|
|
#~ " ..Person::default()\n"
|
|
#~ " };\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Methods are defined in the `impl` block."
|
|
#~ msgstr "메서드는 `impl` 블록에 정의됩니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Use struct update syntax to define a new structure using `peter`. Note "
|
|
#~ "that the variable `peter` will no longer be accessible afterwards."
|
|
#~ msgstr ""
|
|
#~ "`peter`와 구조체 업데이트 문법을 사용하여 새로운 구조체 인스턴스를 만들어"
|
|
#~ "보세요. 이때, `peter`는 더이상 사용할 수 없게 됩니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Use `{:#?}` when printing structs to request the `Debug` representation."
|
|
#~ msgstr "구조체를 `Debug` 형태로 출력하려면 `{:#?}`를 사용하세요."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn generate_random_number() -> i32 {\n"
|
|
#~ " // Implementation based on https://xkcd.com/221/\n"
|
|
#~ " 4 // Chosen by fair dice roll. Guaranteed to be random.\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "enum CoinFlip {\n"
|
|
#~ " Heads,\n"
|
|
#~ " Tails,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"You got: {:?}\", flip_coin());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn generate_random_number() -> i32 {\n"
|
|
#~ " // Implementation based on https://xkcd.com/221/\n"
|
|
#~ " 4 // Chosen by fair dice roll. Guaranteed to be random.\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "enum CoinFlip {\n"
|
|
#~ " Heads,\n"
|
|
#~ " Tails,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"You got: {:?}\", flip_coin());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "This page offers an enum type `CoinFlip` with two variants `Heads` and "
|
|
#~ "`Tails`. You might note the namespace when using variants."
|
|
#~ msgstr ""
|
|
#~ "위의 `CoinFlip` 열거형 타입은 `Heads`와 `Tail` 두 가지 variant를 가집니"
|
|
#~ "다. 열거형 타입의 variant는 네임스페이스를 붙여서 사용합니다."
|
|
|
|
#~ msgid "In both, associated functions are defined within an `impl` block."
|
|
#~ msgstr "둘 다 연관함수를 `impl`블록으로 정의 할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "You can define richer enums where the variants carry data. You can then "
|
|
#~ "use the `match` statement to extract the data from each variant:"
|
|
#~ msgstr ""
|
|
#~ "좀더 복잡한 열거형의 경우 variant에 데이터(payload)를 포함시키도 합니다. "
|
|
#~ "각 variant에 담긴 데이터는 `match`문을 이용해 추출합니다:"
|
|
|
|
#~ 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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let load = WebEvent::PageLoad;\n"
|
|
#~ " let press = WebEvent::KeyPress('x');\n"
|
|
#~ " let click = WebEvent::Click { x: 20, y: 80 };\n"
|
|
#~ "\n"
|
|
#~ " inspect(load);\n"
|
|
#~ " inspect(press);\n"
|
|
#~ " inspect(click);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "enum WebEvent {\n"
|
|
#~ " PageLoad, // 페이로드가 없는 유형\n"
|
|
#~ " KeyPress(char), // 튜플 구조체 유형\n"
|
|
#~ " Click { x: i64, y: i64 }, // 완전한 구조체 유형\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let load = WebEvent::PageLoad;\n"
|
|
#~ " let press = WebEvent::KeyPress('x');\n"
|
|
#~ " let click = WebEvent::Click { x: 20, y: 80 };\n"
|
|
#~ "\n"
|
|
#~ " inspect(load);\n"
|
|
#~ " inspect(press);\n"
|
|
#~ " inspect(click);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "The expression is matched against the patterns from top to bottom. There "
|
|
#~ "is no fall-through like in C or C++."
|
|
#~ msgstr ""
|
|
#~ "매치 패턴들은 위에서 아래로 순서에 따라 검사합니다. C나 C++에서와 같은 "
|
|
#~ "fall-through는 없습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "The match expression has a value. The value is the last expression in the "
|
|
#~ "match arm which was executed."
|
|
#~ msgstr ""
|
|
#~ "매치 표현식 자체는 값을 가집니다. 그 값은 매칭이 된 패턴에서 가장 마지막"
|
|
#~ "에 수행된 표현식이 됩니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Starting from the top we look for what pattern matches the value then run "
|
|
#~ "the code following the arrow. Once we find a match, we stop. "
|
|
#~ msgstr ""
|
|
#~ "가장 위에서 부터 어떤 패턴이 주어진 값과 매칭하는지 검사한 다음, 매칭된 것"
|
|
#~ "이 발견되면 화살표를 따라 코드를 수행합니다. 한 번 매칭이 되고 코드가 수행"
|
|
#~ "이 되면, 더이상의 매칭은 없습니다. "
|
|
|
|
#~ msgid "`match` inspects a hidden discriminant field in the `enum`."
|
|
#~ msgstr ""
|
|
#~ "`match`는 주어진 열거형 값이 실제로 어떤 variant인지 판단하기 위해, 그 "
|
|
#~ "variant의 종류가 기록된, 숨겨진 필드(식별자)의 값을 검사합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "It is possible to retrieve the discriminant by calling `std::mem::"
|
|
#~ "discriminant()`"
|
|
#~ msgstr "`std::mem::discriminant()`를 이용하여 식별자를 얻을 수도 있습니다"
|
|
|
|
#~ msgid ""
|
|
#~ "This is useful, for example, if implementing `PartialEq` for structs "
|
|
#~ "where comparing field values doesn't affect equality."
|
|
#~ msgstr ""
|
|
#~ "이는 각 필드 값을 굳이 비교할 필요 없는 구조체에 대해 `PartialEq` 트레잇"
|
|
#~ "을 구현할 때 유용합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "`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 ""
|
|
#~ "`WebEvent::Click { ... }`은 최상위 레벨 구조체 `struct Click {...}`를 따"
|
|
#~ "로 정의하고 `WebEvent::Click(Click)`처럼 튜플 형태로 정의한 것과 정확히 같"
|
|
#~ "진 않습니다. 예를 들어 `WebEvent::Click { ... }` 로 정의한 경우, 구조체 형"
|
|
#~ "태와 유사하지만 트레잇을 구현 할 수 없습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Rust enums are packed tightly, taking constraints due to alignment into "
|
|
#~ "account:"
|
|
#~ msgstr ""
|
|
#~ "러스트의 열거형은 정렬(alignment)로 인한 제약을 고려하여 크기를 빽빽하게 "
|
|
#~ "잡습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::any::type_name;\n"
|
|
#~ "use std::mem::{align_of, size_of};\n"
|
|
#~ "\n"
|
|
#~ "fn dbg_size<T>() {\n"
|
|
#~ " println!(\"{}: size {} bytes, align: {} bytes\",\n"
|
|
#~ " type_name::<T>(), size_of::<T>(), align_of::<T>());\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "enum Foo {\n"
|
|
#~ " A,\n"
|
|
#~ " B,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " dbg_size::<Foo>();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::any::type_name;\n"
|
|
#~ "use std::mem::{align_of, size_of};\n"
|
|
#~ "\n"
|
|
#~ "fn dbg_size<T>() {\n"
|
|
#~ " println!(\"{}: size {} bytes, align: {} bytes\",\n"
|
|
#~ " type_name::<T>(), size_of::<T>(), align_of::<T>());\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "enum Foo {\n"
|
|
#~ " A,\n"
|
|
#~ " B,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " dbg_size::<Foo>();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Internally Rust is using a field (discriminant) to keep track of the enum "
|
|
#~ "variant."
|
|
#~ msgstr ""
|
|
#~ "러스트는 열거형 variant를 구분하기 위해 내부적으로 식별자(discriminant) 필"
|
|
#~ "드를 사용합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[repr(u32)]\n"
|
|
#~ "enum Bar {\n"
|
|
#~ " A, // 0\n"
|
|
#~ " B = 10000,\n"
|
|
#~ " C, // 10001\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"A: {}\", Bar::A as u32);\n"
|
|
#~ " println!(\"B: {}\", Bar::B as u32);\n"
|
|
#~ " println!(\"C: {}\", Bar::C as u32);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[repr(u32)]\n"
|
|
#~ "enum Bar {\n"
|
|
#~ " A, // 0\n"
|
|
#~ " B = 10000,\n"
|
|
#~ " C, // 10001\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"A: {}\", Bar::A as u32);\n"
|
|
#~ " println!(\"B: {}\", Bar::B as u32);\n"
|
|
#~ " println!(\"C: {}\", Bar::C as u32);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Try out other types such as"
|
|
#~ msgstr "다른 타입들도 확인해보세요"
|
|
|
|
#~ msgid "`dbg_size!(bool)`: size 1 bytes, align: 1 bytes,"
|
|
#~ msgstr "`dbg_size!(bool)`: 크기 1 바이트, 정렬: 1 바이트,"
|
|
|
|
#~ msgid ""
|
|
#~ "`dbg_size!(Option<bool>)`: size 1 bytes, align: 1 bytes (niche "
|
|
#~ "optimization, see below),"
|
|
#~ msgstr ""
|
|
#~ "`dbg_size!(Option<bool>)`: 크기 1 바이트, 정렬: 1 바이트 (니치 최적화, 아"
|
|
#~ "래 설명 참조)"
|
|
|
|
#~ msgid ""
|
|
#~ "`dbg_size!(&i32)`: size 8 bytes, align: 8 bytes (on a 64-bit machine),"
|
|
#~ msgstr ""
|
|
#~ "`dbg_size!(&i32)`: 크기 8 바이트, 정렬: 8 바이트 (64비트 머신인 경우)"
|
|
|
|
#~ msgid ""
|
|
#~ "`dbg_size!(Option<&i32>)`: size 8 bytes, align: 8 bytes (null pointer "
|
|
#~ "optimization, see below)."
|
|
#~ msgstr ""
|
|
#~ "`dbg_size!(Option<&i32>)`: 크기 8 바이트, 정렬: 8 바이트 (널포인터 최적"
|
|
#~ "화, 아래 설명 참조)"
|
|
|
|
#~ msgid ""
|
|
#~ "Niche optimization: Rust will merge unused bit patterns for the enum "
|
|
#~ "discriminant."
|
|
#~ msgstr ""
|
|
#~ "니치 최적화: 러스트는 열거형 식별자를 사용되지 않은 비트 패턴과 병합합니"
|
|
#~ "다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::mem::transmute;\n"
|
|
#~ "\n"
|
|
#~ "macro_rules! dbg_bits {\n"
|
|
#~ " ($e:expr, $bit_type:ty) => {\n"
|
|
#~ " println!(\"- {}: {:#x}\", stringify!($e), transmute::<_, "
|
|
#~ "$bit_type>($e));\n"
|
|
#~ " };\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " // TOTALLY UNSAFE. Rust provides no guarantees about the bitwise\n"
|
|
#~ " // representation of types.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " println!(\"Bitwise representation of bool\");\n"
|
|
#~ " dbg_bits!(false, u8);\n"
|
|
#~ " dbg_bits!(true, u8);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Bitwise representation of Option<bool>\");\n"
|
|
#~ " dbg_bits!(None::<bool>, u8);\n"
|
|
#~ " dbg_bits!(Some(false), u8);\n"
|
|
#~ " dbg_bits!(Some(true), u8);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Bitwise representation of Option<Option<bool>>\");\n"
|
|
#~ " dbg_bits!(Some(Some(false)), u8);\n"
|
|
#~ " dbg_bits!(Some(Some(true)), u8);\n"
|
|
#~ " dbg_bits!(Some(None::<bool>), u8);\n"
|
|
#~ " dbg_bits!(None::<Option<bool>>, u8);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Bitwise representation of Option<&i32>\");\n"
|
|
#~ " dbg_bits!(None::<&i32>, usize);\n"
|
|
#~ " dbg_bits!(Some(&0i32), usize);\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::mem::transmute;\n"
|
|
#~ "\n"
|
|
#~ "macro_rules! dbg_bits {\n"
|
|
#~ " ($e:expr, $bit_type:ty) => {\n"
|
|
#~ " println!(\"- {}: {:#x}\", stringify!($e), transmute::<_, "
|
|
#~ "$bit_type>($e));\n"
|
|
#~ " };\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " // TOTALLY UNSAFE. Rust provides no guarantees about the bitwise\n"
|
|
#~ " // representation of types.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " println!(\"Bitwise representation of bool\");\n"
|
|
#~ " dbg_bits!(false, u8);\n"
|
|
#~ " dbg_bits!(true, u8);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Bitwise representation of Option<bool>\");\n"
|
|
#~ " dbg_bits!(None::<bool>, u8);\n"
|
|
#~ " dbg_bits!(Some(false), u8);\n"
|
|
#~ " dbg_bits!(Some(true), u8);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Bitwise representation of Option<Option<bool>>\");\n"
|
|
#~ " dbg_bits!(Some(Some(false)), u8);\n"
|
|
#~ " dbg_bits!(Some(Some(true)), u8);\n"
|
|
#~ " dbg_bits!(Some(None::<bool>), u8);\n"
|
|
#~ " dbg_bits!(None::<Option<bool>>, u8);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Bitwise representation of Option<&i32>\");\n"
|
|
#~ " dbg_bits!(None::<&i32>, usize);\n"
|
|
#~ " dbg_bits!(Some(&0i32), usize);\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "More complex example if you want to discuss what happens when we chain "
|
|
#~ "more than 256 `Option`s together."
|
|
#~ msgstr ""
|
|
#~ "아래는 좀 더 복잡한 예제입니다. 256개 이상의 `Option`이 중첩되어 연결되"
|
|
#~ "어 있을 경우 어떻게 되는지 보여줍니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#![recursion_limit = \"1000\"]\n"
|
|
#~ "\n"
|
|
#~ "use std::mem::transmute;\n"
|
|
#~ "\n"
|
|
#~ "macro_rules! dbg_bits {\n"
|
|
#~ " ($e:expr, $bit_type:ty) => {\n"
|
|
#~ " println!(\"- {}: {:#x}\", stringify!($e), transmute::<_, "
|
|
#~ "$bit_type>($e));\n"
|
|
#~ " };\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// Macro to wrap a value in 2^n Some() where n is the number of \"@\" "
|
|
#~ "signs.\n"
|
|
#~ "// Increasing the recursion limit is required to evaluate this macro.\n"
|
|
#~ "macro_rules! many_options {\n"
|
|
#~ " ($value:expr) => { Some($value) };\n"
|
|
#~ " ($value:expr, @) => {\n"
|
|
#~ " Some(Some($value))\n"
|
|
#~ " };\n"
|
|
#~ " ($value:expr, @ $($more:tt)+) => {\n"
|
|
#~ " many_options!(many_options!($value, $($more)+), $($more)+)\n"
|
|
#~ " };\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " // TOTALLY UNSAFE. Rust provides no guarantees about the bitwise\n"
|
|
#~ " // representation of types.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " assert_eq!(many_options!(false), Some(false));\n"
|
|
#~ " assert_eq!(many_options!(false, @), Some(Some(false)));\n"
|
|
#~ " assert_eq!(many_options!(false, @@), "
|
|
#~ "Some(Some(Some(Some(false)))));\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Bitwise representation of a chain of 128 Option's."
|
|
#~ "\");\n"
|
|
#~ " dbg_bits!(many_options!(false, @@@@@@@), u8);\n"
|
|
#~ " dbg_bits!(many_options!(true, @@@@@@@), u8);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Bitwise representation of a chain of 256 Option's."
|
|
#~ "\");\n"
|
|
#~ " dbg_bits!(many_options!(false, @@@@@@@@), u16);\n"
|
|
#~ " dbg_bits!(many_options!(true, @@@@@@@@), u16);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Bitwise representation of a chain of 257 Option's."
|
|
#~ "\");\n"
|
|
#~ " dbg_bits!(many_options!(Some(false), @@@@@@@@), u16);\n"
|
|
#~ " dbg_bits!(many_options!(Some(true), @@@@@@@@), u16);\n"
|
|
#~ " dbg_bits!(many_options!(None::<bool>, @@@@@@@@), u16);\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#![recursion_limit = \"1000\"]\n"
|
|
#~ "\n"
|
|
#~ "use std::mem::transmute;\n"
|
|
#~ "\n"
|
|
#~ "macro_rules! dbg_bits {\n"
|
|
#~ " ($e:expr, $bit_type:ty) => {\n"
|
|
#~ " println!(\"- {}: {:#x}\", stringify!($e), transmute::<_, "
|
|
#~ "$bit_type>($e));\n"
|
|
#~ " };\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// Macro to wrap a value in 2^n Some() where n is the number of \"@\" "
|
|
#~ "signs.\n"
|
|
#~ "// Increasing the recursion limit is required to evaluate this macro.\n"
|
|
#~ "macro_rules! many_options {\n"
|
|
#~ " ($value:expr) => { Some($value) };\n"
|
|
#~ " ($value:expr, @) => {\n"
|
|
#~ " Some(Some($value))\n"
|
|
#~ " };\n"
|
|
#~ " ($value:expr, @ $($more:tt)+) => {\n"
|
|
#~ " many_options!(many_options!($value, $($more)+), $($more)+)\n"
|
|
#~ " };\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " // TOTALLY UNSAFE. Rust provides no guarantees about the bitwise\n"
|
|
#~ " // representation of types.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " assert_eq!(many_options!(false), Some(false));\n"
|
|
#~ " assert_eq!(many_options!(false, @), Some(Some(false)));\n"
|
|
#~ " assert_eq!(many_options!(false, @@), "
|
|
#~ "Some(Some(Some(Some(false)))));\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Bitwise representation of a chain of 128 Option's."
|
|
#~ "\");\n"
|
|
#~ " dbg_bits!(many_options!(false, @@@@@@@), u8);\n"
|
|
#~ " dbg_bits!(many_options!(true, @@@@@@@), u8);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Bitwise representation of a chain of 256 Option's."
|
|
#~ "\");\n"
|
|
#~ " dbg_bits!(many_options!(false, @@@@@@@@), u16);\n"
|
|
#~ " dbg_bits!(many_options!(true, @@@@@@@@), u16);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Bitwise representation of a chain of 257 Option's."
|
|
#~ "\");\n"
|
|
#~ " dbg_bits!(many_options!(Some(false), @@@@@@@@), u16);\n"
|
|
#~ " dbg_bits!(many_options!(Some(true), @@@@@@@@), u16);\n"
|
|
#~ " dbg_bits!(many_options!(None::<bool>, @@@@@@@@), u16);\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Person {\n"
|
|
#~ " name: String,\n"
|
|
#~ " age: u8,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Person {\n"
|
|
#~ " fn say_hello(&self) {\n"
|
|
#~ " println!(\"Hello, my name is {}\", self.name);\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let peter = Person {\n"
|
|
#~ " name: String::from(\"Peter\"),\n"
|
|
#~ " age: 27,\n"
|
|
#~ " };\n"
|
|
#~ " peter.say_hello();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Person {\n"
|
|
#~ " name: String,\n"
|
|
#~ " age: u8,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Person {\n"
|
|
#~ " fn say_hello(&self) {\n"
|
|
#~ " println!(\"Hello, my name is {}\", self.name);\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let peter = Person {\n"
|
|
#~ " name: String::from(\"Peter\"),\n"
|
|
#~ " age: 27,\n"
|
|
#~ " };\n"
|
|
#~ " peter.say_hello();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "We describe the distinction between method receivers next."
|
|
#~ msgstr "다음 슬라이드에서 receiver의 구분을 설명합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Consider emphasizing \"shared and immutable\" and \"unique and mutable\". "
|
|
#~ "These constraints always come together in Rust due to borrow checker "
|
|
#~ "rules, and `self` is no exception. It isn't possible to reference a "
|
|
#~ "struct from multiple locations and call a mutating (`&mut self`) method "
|
|
#~ "on it."
|
|
#~ msgstr ""
|
|
#~ "\"공유가능한 불변\"과 \"유일한 가변\" 부분은 강조할 만합니다. 이러한 제약"
|
|
#~ "은 러스트의 빌림 검사기(borrow checker) 규칙으로 늘 붙어다닙니다. `self`"
|
|
#~ "도 예외는 아닙니다. 여러 위치에서 구조체를 참조하면서 객체를 수정하는"
|
|
#~ "(`&mut self`를 리시버로 하는) 메서드를 호출하는 것은 불가능합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Race {\n"
|
|
#~ " name: String,\n"
|
|
#~ " laps: Vec<i32>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Race {\n"
|
|
#~ " fn new(name: &str) -> Race { // No receiver, a static method\n"
|
|
#~ " Race { name: String::from(name), laps: Vec::new() }\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn add_lap(&mut self, lap: i32) { // Exclusive borrowed read-write "
|
|
#~ "access to self\n"
|
|
#~ " self.laps.push(lap);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Race {\n"
|
|
#~ " name: String,\n"
|
|
#~ " laps: Vec<i32>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Race {\n"
|
|
#~ " fn new(name: &str) -> Race { // No receiver, a static method\n"
|
|
#~ " Race { name: String::from(name), laps: Vec::new() }\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn add_lap(&mut self, lap: i32) { // Exclusive borrowed read-write "
|
|
#~ "access to self\n"
|
|
#~ " self.laps.push(lap);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid "All four methods here use a different method receiver."
|
|
#~ msgstr "이 네 개의 메서드는 서로 다른 유형의 리시버를 사용합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "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`."
|
|
#~ msgstr ""
|
|
#~ "리시버의 유형에 따라 함수가 할 수 있는 일이 달라지고, 또 메소드를 호출한 "
|
|
#~ "뒤 `main`에서 해당 객체를 사용할 수 있는지 여부도 달라진다는 점을 강조하세"
|
|
#~ "요."
|
|
|
|
#~ msgid ""
|
|
#~ "You can showcase the error that appears when trying to call `finish` "
|
|
#~ "twice."
|
|
#~ msgstr "`finish`를 두번 호출하여 오류가 발생하는 것을 보일 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "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."
|
|
#~ msgstr ""
|
|
#~ "비록 메서드 receiver는 다르지만 main 함수에서 비 정적 함수를 부르는 방법"
|
|
#~ "은 같습니다. 러스트는 메서드를 호출할 때 자동으로 참조/역참조(따라가기)를 "
|
|
#~ "수행합니다. 러스트는 객체와 매서드 시그니처가 서로 매치되도록 객체에 `&`, "
|
|
#~ "`*`, `muts`를 자동으로 붙여줍니다."
|
|
|
|
#~ msgid ""
|
|
#~ "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 ""
|
|
#~ "`print_laps`함수에서 벡터를 어떤 식으로 사용하고 있는지 언급하는 것도 좋습"
|
|
#~ "니다. 벡터는 오후 강의에서 더 자세히 설명할 것입니다. "
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let input = 'x';\n"
|
|
#~ "\n"
|
|
#~ " 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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let input = 'x';\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ "```"
|
|
|
|
#~ msgid "The `_` pattern is a wildcard pattern which matches any value."
|
|
#~ msgstr "`_`패턴은 어떤 값과도 매칭되는 와일드카드입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "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`."
|
|
#~ msgstr ""
|
|
#~ "와일드카드 문자를 변수로 바꾸거나 `q`의 따옴표를 제거하는 식으로 수정하면"
|
|
#~ "서 바인딩이 어떻게 작동하는지 보여주는 것도 유용할 수 있습니다."
|
|
|
|
#~ msgid "You can demonstrate matching on a reference."
|
|
#~ msgstr "참조를 매칭하는 것도 시연할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "This might be a good time to bring up the concept of irrefutable "
|
|
#~ "patterns, as the term can show up in error messages."
|
|
#~ msgstr ""
|
|
#~ "에러 메시지에 \"반박 불가능 패턴(irrefutable pattern)\"이란 용어가 등장하"
|
|
#~ "기도 합니다. 지금 그 의미를 소개하는 것도 좋을 것 같습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "enum Result {\n"
|
|
#~ " Ok(i32),\n"
|
|
#~ " Err(String),\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 {n} into two equal parts\"))\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "enum Result {\n"
|
|
#~ " Ok(i32),\n"
|
|
#~ " Err(String),\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 {n} into two equal parts\"))\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid "You can also destructure `structs`:"
|
|
#~ msgstr "`struct` 구조체 역시 분해할 수 있습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "struct Foo {\n"
|
|
#~ " x: (u32, u32),\n"
|
|
#~ " y: u32,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[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, x = {i:?}\"),\n"
|
|
#~ " Foo { y, .. } => println!(\"y = {y}, other fields were "
|
|
#~ "ignored\"),\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "struct Foo {\n"
|
|
#~ " x: (u32, u32),\n"
|
|
#~ " y: u32,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[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, x = {i:?}\"),\n"
|
|
#~ " Foo { y, .. } => println!(\"y = {y}, other fields were "
|
|
#~ "ignored\"),\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Destructuring of slices of unknown length also works with patterns of "
|
|
#~ "fixed length."
|
|
#~ msgstr ""
|
|
#~ "길이를 알 수 없는 슬라이스에 대해서도 고정 길이 패턴으로 분해할 수 있습니"
|
|
#~ "다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " inspect(&[0, -2, 3]);\n"
|
|
#~ " inspect(&[0, -2, 3, 4]);\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[rustfmt::skip]\n"
|
|
#~ "fn inspect(slice: &[i32]) {\n"
|
|
#~ " println!(\"Tell me about {slice:?}\");\n"
|
|
#~ " match slice {\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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " inspect(&[0, -2, 3]);\n"
|
|
#~ " inspect(&[0, -2, 3, 4]);\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[rustfmt::skip]\n"
|
|
#~ "fn inspect(slice: &[i32]) {\n"
|
|
#~ " println!(\"Tell me about {slice:?}\");\n"
|
|
#~ " match slice {\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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "When matching, you can add a _guard_ to a pattern. This is an arbitrary "
|
|
#~ "Boolean expression which will be executed if the pattern matches:"
|
|
#~ msgstr ""
|
|
#~ "패턴 뒤에 가드(guard, 조건식)를 덧붙일 수 있습니다. 가드는 패턴이 매치되"
|
|
#~ "면 추가로 따져보는 불리언 표현식입니다:"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "You can use the variables defined in the pattern in your if expression."
|
|
#~ msgstr "패턴에 정의된 변수를 가드의 표현식에서 사용할 수 있습니다."
|
|
|
|
#~ msgid "Day 2: Morning Exercises"
|
|
#~ msgstr "2일차 오전 연습문제"
|
|
|
|
#~ msgid "We will look at implementing methods in two contexts:"
|
|
#~ msgstr "이번 연습문제들은 두가지 맥락에서 메서드 구현방법을 다룹니다:"
|
|
|
|
#~ msgid "Simple struct which tracks health statistics."
|
|
#~ msgstr "건강 상태 통계를 추적하는 프로그램의 간단한 구조체."
|
|
|
|
#~ msgid "Multiple structs and enums for a drawing library."
|
|
#~ msgstr "드로잉 라이브러리를 위한 구조체 및 열거헝."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,should_panic\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "pub struct User {\n"
|
|
#~ " name: String,\n"
|
|
#~ " age: u32,\n"
|
|
#~ " height: f32,\n"
|
|
#~ " visit_count: usize,\n"
|
|
#~ " last_blood_pressure: Option<(u32, u32)>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct Measurements {\n"
|
|
#~ " height: f32,\n"
|
|
#~ " blood_pressure: (u32, u32),\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct HealthReport<'a> {\n"
|
|
#~ " patient_name: &'a str,\n"
|
|
#~ " visit_count: u32,\n"
|
|
#~ " height_change: f32,\n"
|
|
#~ " blood_pressure_change: Option<(i32, i32)>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl User {\n"
|
|
#~ " pub fn new(name: String, age: u32, height: f32) -> Self {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn name(&self) -> &str {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn age(&self) -> u32 {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn height(&self) -> f32 {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn doctor_visits(&self) -> u32 {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn set_age(&mut self, new_age: u32) {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn set_height(&mut self, new_height: f32) {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn visit_doctor(&mut self, measurements: Measurements) -> "
|
|
#~ "HealthReport {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_height() {\n"
|
|
#~ " let bob = User::new(String::from(\"Bob\"), 32, 155.2);\n"
|
|
#~ " assert_eq!(bob.height(), 155.2);\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[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"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_visit() {\n"
|
|
#~ " let mut bob = User::new(String::from(\"Bob\"), 32, 155.2);\n"
|
|
#~ " assert_eq!(bob.doctor_visits(), 0);\n"
|
|
#~ " let report = bob.visit_doctor(Measurements {\n"
|
|
#~ " height: 156.1,\n"
|
|
#~ " blood_pressure: (120, 80),\n"
|
|
#~ " });\n"
|
|
#~ " assert_eq!(report.patient_name, \"Bob\");\n"
|
|
#~ " assert_eq!(report.visit_count, 1);\n"
|
|
#~ " assert_eq!(report.blood_pressure_change, None);\n"
|
|
#~ "\n"
|
|
#~ " let report = bob.visit_doctor(Measurements {\n"
|
|
#~ " height: 156.1,\n"
|
|
#~ " blood_pressure: (115, 76),\n"
|
|
#~ " });\n"
|
|
#~ "\n"
|
|
#~ " assert_eq!(report.visit_count, 2);\n"
|
|
#~ " assert_eq!(report.blood_pressure_change, Some((-5, -4)));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,should_panic\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "pub struct User {\n"
|
|
#~ " name: String,\n"
|
|
#~ " age: u32,\n"
|
|
#~ " height: f32,\n"
|
|
#~ " visit_count: usize,\n"
|
|
#~ " last_blood_pressure: Option<(u32, u32)>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct Measurements {\n"
|
|
#~ " height: f32,\n"
|
|
#~ " blood_pressure: (u32, u32),\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct HealthReport<'a> {\n"
|
|
#~ " patient_name: &'a str,\n"
|
|
#~ " visit_count: u32,\n"
|
|
#~ " height_change: f32,\n"
|
|
#~ " blood_pressure_change: Option<(i32, i32)>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl User {\n"
|
|
#~ " pub fn new(name: String, age: u32, height: f32) -> Self {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn name(&self) -> &str {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn age(&self) -> u32 {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn height(&self) -> f32 {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn doctor_visits(&self) -> u32 {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn set_age(&mut self, new_age: u32) {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn set_height(&mut self, new_height: f32) {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn visit_doctor(&mut self, measurements: Measurements) -> "
|
|
#~ "HealthReport {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_height() {\n"
|
|
#~ " let bob = User::new(String::from(\"Bob\"), 32, 155.2);\n"
|
|
#~ " assert_eq!(bob.height(), 155.2);\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[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"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_visit() {\n"
|
|
#~ " let mut bob = User::new(String::from(\"Bob\"), 32, 155.2);\n"
|
|
#~ " assert_eq!(bob.doctor_visits(), 0);\n"
|
|
#~ " let report = bob.visit_doctor(Measurements {\n"
|
|
#~ " height: 156.1,\n"
|
|
#~ " blood_pressure: (120, 80),\n"
|
|
#~ " });\n"
|
|
#~ " assert_eq!(report.patient_name, \"Bob\");\n"
|
|
#~ " assert_eq!(report.visit_count, 1);\n"
|
|
#~ " assert_eq!(report.blood_pressure_change, None);\n"
|
|
#~ "\n"
|
|
#~ " let report = bob.visit_doctor(Measurements {\n"
|
|
#~ " height: 156.1,\n"
|
|
#~ " blood_pressure: (115, 76),\n"
|
|
#~ " });\n"
|
|
#~ "\n"
|
|
#~ " assert_eq!(report.visit_count, 2);\n"
|
|
#~ " assert_eq!(report.blood_pressure_change, Some((-5, -4)));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Polygon Struct"
|
|
#~ msgstr "Polygon 구조체"
|
|
|
|
#~ msgid ""
|
|
#~ "We will create a `Polygon` struct which contain some points. Copy the "
|
|
#~ "code below to <https://play.rust-lang.org/> and fill in the missing "
|
|
#~ "methods to make the tests pass:"
|
|
#~ msgstr ""
|
|
#~ "우리는 몇개의 꼭지점을 가진 다각형을 표현하는 `Polygon` 구조체를 만들 것입"
|
|
#~ "니다. 아래 코드를 <https://play.rust-lang.org/>에 복사해서 테스트가 통과하"
|
|
#~ "도록 빠진 메서드를 구현하시면 됩니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "pub struct Point {\n"
|
|
#~ " // add fields\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Point {\n"
|
|
#~ " // add methods\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct Polygon {\n"
|
|
#~ " // add fields\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Polygon {\n"
|
|
#~ " // add methods\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct Circle {\n"
|
|
#~ " // add fields\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Circle {\n"
|
|
#~ " // add methods\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub enum Shape {\n"
|
|
#~ " Polygon(Polygon),\n"
|
|
#~ " Circle(Circle),\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[cfg(test)]\n"
|
|
#~ "mod tests {\n"
|
|
#~ " use super::*;\n"
|
|
#~ "\n"
|
|
#~ " fn round_two_digits(x: f64) -> f64 {\n"
|
|
#~ " (x * 100.0).round() / 100.0\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " #[test]\n"
|
|
#~ " fn test_point_magnitude() {\n"
|
|
#~ " let p1 = Point::new(12, 13);\n"
|
|
#~ " assert_eq!(round_two_digits(p1.magnitude()), 17.69);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " #[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"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " #[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"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " #[test]\n"
|
|
#~ " fn test_polygon_left_most_point() {\n"
|
|
#~ " let p1 = Point::new(12, 13);\n"
|
|
#~ " let p2 = Point::new(16, 16);\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " #[test]\n"
|
|
#~ " fn test_polygon_iter() {\n"
|
|
#~ " let p1 = Point::new(12, 13);\n"
|
|
#~ " let p2 = Point::new(16, 16);\n"
|
|
#~ "\n"
|
|
#~ " let mut poly = Polygon::new();\n"
|
|
#~ " poly.add_point(p1);\n"
|
|
#~ " poly.add_point(p2);\n"
|
|
#~ "\n"
|
|
#~ " let points = poly.iter().cloned().collect::<Vec<_>>();\n"
|
|
#~ " assert_eq!(points, vec![Point::new(12, 13), Point::new(16, "
|
|
#~ "16)]);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " #[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"
|
|
#~ "\n"
|
|
#~ "#[allow(dead_code)]\n"
|
|
#~ "fn main() {}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "pub struct Point {\n"
|
|
#~ " // add fields\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Point {\n"
|
|
#~ " // add methods\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct Polygon {\n"
|
|
#~ " // add fields\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Polygon {\n"
|
|
#~ " // add methods\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct Circle {\n"
|
|
#~ " // add fields\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Circle {\n"
|
|
#~ " // add methods\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub enum Shape {\n"
|
|
#~ " Polygon(Polygon),\n"
|
|
#~ " Circle(Circle),\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[cfg(test)]\n"
|
|
#~ "mod tests {\n"
|
|
#~ " use super::*;\n"
|
|
#~ "\n"
|
|
#~ " fn round_two_digits(x: f64) -> f64 {\n"
|
|
#~ " (x * 100.0).round() / 100.0\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " #[test]\n"
|
|
#~ " fn test_point_magnitude() {\n"
|
|
#~ " let p1 = Point::new(12, 13);\n"
|
|
#~ " assert_eq!(round_two_digits(p1.magnitude()), 17.69);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " #[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"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " #[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"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " #[test]\n"
|
|
#~ " fn test_polygon_left_most_point() {\n"
|
|
#~ " let p1 = Point::new(12, 13);\n"
|
|
#~ " let p2 = Point::new(16, 16);\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " #[test]\n"
|
|
#~ " fn test_polygon_iter() {\n"
|
|
#~ " let p1 = Point::new(12, 13);\n"
|
|
#~ " let p2 = Point::new(16, 16);\n"
|
|
#~ "\n"
|
|
#~ " let mut poly = Polygon::new();\n"
|
|
#~ " poly.add_point(p1);\n"
|
|
#~ " poly.add_point(p2);\n"
|
|
#~ "\n"
|
|
#~ " let points = poly.iter().cloned().collect::<Vec<_>>();\n"
|
|
#~ " assert_eq!(points, vec![Point::new(12, 13), Point::new(16, "
|
|
#~ "16)]);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " #[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"
|
|
#~ "\n"
|
|
#~ "#[allow(dead_code)]\n"
|
|
#~ "fn main() {}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Since the method signatures are missing from the problem statements, the "
|
|
#~ "key part of the exercise is to specify those correctly. You don't have to "
|
|
#~ "modify the tests."
|
|
#~ msgstr ""
|
|
#~ "누락된 메서드 시그니처를 올바르게 정의하는 것이 문제의 핵심 부분입니다. 테"
|
|
#~ "스트는 수정하면 안됩니다."
|
|
|
|
#~ msgid "Other interesting parts of the exercise:"
|
|
#~ msgstr "연습문제의 다른 흥미로운 부분:"
|
|
|
|
#~ msgid ""
|
|
#~ "Derive a `Copy` trait for some structs, as in tests the methods sometimes "
|
|
#~ "don't borrow their arguments."
|
|
#~ msgstr ""
|
|
#~ "테스트 코드를 보면 어떤 메서드들은 인자를 borrow하는 대신 `Copy` 트레잇을 "
|
|
#~ "사용하기도 합니다. 구조체가 `Copy` 트레잇을 상속(derive)하도록 하면 됩니"
|
|
#~ "다."
|
|
|
|
#~ msgid ""
|
|
#~ "Discover that `Add` trait must be implemented for two objects to be "
|
|
#~ "addable via \"+\". Note that we do not discuss generics until Day 3."
|
|
#~ msgstr ""
|
|
#~ "\"+\"를 사용하여 두 객체를 서로 더하려면 `Add` 트레잇을 구현해야 합니다. "
|
|
#~ "이는 3일차에 다룰 내용입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "As we have seen, `if` is an expression in Rust. It is used to "
|
|
#~ "conditionally evaluate one of two blocks, but the blocks can have a value "
|
|
#~ "which then becomes the value of the `if` expression. Other control flow "
|
|
#~ "expressions work similarly in Rust."
|
|
#~ msgstr ""
|
|
#~ "앞에서 살펴본 바와 같이 러스트에서 `if`는 표현식입니다. 조건에 따라 두 블"
|
|
#~ "록 중 하나를 평가하며, 그 결과값이 `if` 표현식의 값이 됩니다. 다른 흐름제"
|
|
#~ "어 표현식도 유사하게 작동합니다."
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "The same rule is used for functions: the value of the function body is "
|
|
#~ "the return value:"
|
|
#~ msgstr ""
|
|
#~ "함수에도 동일한 규칙이 적용됩니다. 함수 바디를 이루는 블록의 값이 반환값"
|
|
#~ "이 됩니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn double(x: i32) -> i32 {\n"
|
|
#~ " x + x\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"doubled: {}\", double(7));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn double(x: i32) -> i32 {\n"
|
|
#~ " x + x\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"doubled: {}\", double(7));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "The point of this slide is to show that blocks have a type and value in "
|
|
#~ "Rust. "
|
|
#~ msgstr ""
|
|
#~ "러스트에서는 블록이 타입과 값을 가진다는 점이 이 슬라이드의 핵심입니다. "
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Since 1.65, a similar [let-else](https://doc.rust-lang.org/rust-by-"
|
|
#~ "example/flow_control/let_else.html) construct allows to do a "
|
|
#~ "destructuring assignment, or if it fails, execute a block which is "
|
|
#~ "required to abort normal control flow (with `panic`/`return`/`break`/"
|
|
#~ "`continue`):"
|
|
#~ msgstr ""
|
|
#~ "1.65부터 유사한 [let-else](https://doc.rust-lang.org/rust-by-example/"
|
|
#~ "flow_control/let_else.html) 구성은 디스트럭처링 할당을 실행하거나 실패할 "
|
|
#~ "경우 반환되지 않는 블록 브랜치(panic/return/break/continue)를 보유하도록 "
|
|
#~ "허용합니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"{:?}\", second_word_to_upper(\"foo bar\"));\n"
|
|
#~ "}\n"
|
|
#~ " \n"
|
|
#~ "fn second_word_to_upper(s: &str) -> Option<String> {\n"
|
|
#~ " let mut it = s.split(' ');\n"
|
|
#~ " let (Some(_), Some(item)) = (it.next(), it.next()) else {\n"
|
|
#~ " return None;\n"
|
|
#~ " };\n"
|
|
#~ " Some(item.to_uppercase())\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"{:?}\", second_word_to_upper(\"foo bar\"));\n"
|
|
#~ "}\n"
|
|
#~ " \n"
|
|
#~ "fn second_word_to_upper(s: &str) -> Option<String> {\n"
|
|
#~ " let mut it = s.split(' ');\n"
|
|
#~ " let (Some(_), Some(item)) = (it.next(), it.next()) else {\n"
|
|
#~ " return None;\n"
|
|
#~ " };\n"
|
|
#~ " Some(item.to_uppercase())\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v = vec![10, 20, 30];\n"
|
|
#~ " let mut iter = v.into_iter();\n"
|
|
#~ "\n"
|
|
#~ " while let Some(x) = iter.next() {\n"
|
|
#~ " println!(\"x: {x}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v = vec![10, 20, 30];\n"
|
|
#~ " let mut iter = v.into_iter();\n"
|
|
#~ "\n"
|
|
#~ " while let Some(x) = iter.next() {\n"
|
|
#~ " println!(\"x: {x}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "`for` loops"
|
|
#~ msgstr "`for` 반복문"
|
|
|
|
#~ msgid ""
|
|
#~ "The [`for` loop](https://doc.rust-lang.org/std/keyword.for.html) is "
|
|
#~ "closely related to the [`while let` loop](while-let-expressions.md). It "
|
|
#~ "will automatically call `into_iter()` on the expression and then iterate "
|
|
#~ "over it:"
|
|
#~ msgstr ""
|
|
#~ "`for` 반복문은 `while let` 반복문과 매우 유사합니다. `for` 반복문은 자동으"
|
|
#~ "로 `into_iter()`를 호출한 다음 이를 반복합니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v = vec![10, 20, 30];\n"
|
|
#~ "\n"
|
|
#~ " 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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v = vec![10, 20, 30];\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ "```"
|
|
|
|
#~ msgid "You can use `break` and `continue` here as usual."
|
|
#~ msgstr "다른 언어와 마찬가지로 `break` 와 `continue`를 사용할 수 있습니다."
|
|
|
|
#~ msgid "Index iteration is not a special syntax in Rust for just that case."
|
|
#~ msgstr "러스트는 인덱스 기반의 반복을 위한 별도의 문법을 사용하지 않습니다."
|
|
|
|
#~ msgid "`(0..10)` is a range that implements an `Iterator` trait. "
|
|
#~ msgstr "`(0..10)`은 `Iterator` 트레잇을 구현하는 범위(range) 값입니다. "
|
|
|
|
#~ msgid ""
|
|
#~ "`step_by` is a method that returns another `Iterator` that skips every "
|
|
#~ "other element. "
|
|
#~ msgstr ""
|
|
#~ "`step_by`는 반복자의 요소들을 건너뛰는 또다른 `Iterator`를 반환하는 메서드"
|
|
#~ "입니다. "
|
|
|
|
#~ msgid ""
|
|
#~ "Modify the elements in the vector and explain the compiler errors. Change "
|
|
#~ "vector `v` to be mutable and the for loop to `for x in v.iter_mut()`."
|
|
#~ msgstr ""
|
|
#~ "벡터 요소들을 수정하려고 하면 나오는 컴파일러 에러를 같이 살펴보세요. `v` "
|
|
#~ "벡터를 가변 변수로 변경하고 루프는 `for x in v.iter_mut()`로 수정하세요."
|
|
|
|
#~ msgid "`loop` expressions"
|
|
#~ msgstr "`loop` 표현식"
|
|
|
|
#~ msgid ""
|
|
#~ "Finally, there is a [`loop` keyword](https://doc.rust-lang.org/reference/"
|
|
#~ "expressions/loop-expr.html#infinite-loops) which creates an endless loop."
|
|
#~ msgstr ""
|
|
#~ "마지막으로, 무한 루프를 만드는 [`loop` 키워드](https://doc.rust-lang.org/"
|
|
#~ "reference/expressions/loop-expr.html#infinite-loops)가 있습니다."
|
|
|
|
#~ msgid "Here you must either `break` or `return` to stop the loop:"
|
|
#~ msgstr ""
|
|
#~ "따라서 반드시 `break` 또는 `return`을 사용해서 루프를 정지해야 합니다:"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid "Break the `loop` with a value (e.g. `break 8`) and print it out."
|
|
#~ msgstr "`loop`를 값(예: `break 8`)으로 나누고 출력합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "The [`match` keyword](https://doc.rust-lang.org/reference/expressions/"
|
|
#~ "match-expr.html) is used to match a value against one or more patterns. "
|
|
#~ "In that sense, it works like a series of `if let` expressions:"
|
|
#~ msgstr ""
|
|
#~ "`match`키워드는 어떤 값을 하나 이상의 패턴에 대해 매치하는데 사용합니다. "
|
|
#~ "그런 면에서 `if let` 표현식을 여러개 이어 놓은 것과 같습니다:"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid "Save the match expression to a variable and print it out."
|
|
#~ msgstr "`match` 표현식을 변수에 할당하고 그 값을 출력해보세요."
|
|
|
|
#~ msgid "Remove `.as_deref()` and explain the error."
|
|
#~ msgstr "`.as_deref()`를 지워보고, 이 때 나오는 에러를 설명해주세요."
|
|
|
|
#~ msgid ""
|
|
#~ "`std::env::args().next()` returns an `Option<String>`, but we cannot "
|
|
#~ "match against `String`."
|
|
#~ msgstr ""
|
|
#~ "`std::env::args().next()`는 `Option<String>` 값을 반환하는데, `String`은 "
|
|
#~ "직접 매치할 수 없습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "`as_deref()` transforms an `Option<T>` to `Option<&T::Target>`. In our "
|
|
#~ "case, this turns `Option<String>` into `Option<&str>`."
|
|
#~ msgstr ""
|
|
#~ "`as_deref()`는 `Option<T>`를 `Option<&T::Target>`으로 바꿔줍니다. 이 경우"
|
|
#~ "는 `Option<String>`에서 `Option<&str>`로 바뀝니다."
|
|
|
|
#~ msgid ""
|
|
#~ "We can now use pattern matching to match against the `&str` inside "
|
|
#~ "`Option`."
|
|
#~ msgstr "이제는 패턴 매칭으로 `Option` 안의 `&str`을 매치할 수 있습니다."
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid "The common vocabulary types include:"
|
|
#~ msgstr "일반적인 타입은 아래와 같습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "[`Option` and `Result`](std/option-result.md) types: used for optional "
|
|
#~ "values and [error handling](error-handling.md)."
|
|
#~ msgstr ""
|
|
#~ "[`Option`과 `Result`](std/option-result.md) : 어떤 값이 있거나 없거나 하"
|
|
#~ "는 경우, 그리고 [오류 처리](error-handling.md)에 사용합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "[`String`](std/string.md): the default string type used for owned data."
|
|
#~ msgstr ""
|
|
#~ "[`String`](std/string.md): 기본적인 문자열 타입으로, 문자열 데이터를 소유"
|
|
#~ "하는 경우에 사용합니다."
|
|
|
|
#~ msgid "[`Vec`](std/vec.md): a standard extensible vector."
|
|
#~ msgstr "[`Vec`](std/vec.md): 가변 크기의 표준 벡터 타입입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "[`HashMap`](std/hashmap.md): a hash map type with a configurable hashing "
|
|
#~ "algorithm."
|
|
#~ msgstr ""
|
|
#~ "[`HashMap`](std/hashmap.md): 해시 알고리즘을 따로 지정할 수도 있는 해시맵 "
|
|
#~ "타입입니다."
|
|
|
|
#~ msgid "[`Box`](std/box.md): an owned pointer for heap-allocated data."
|
|
#~ msgstr "[`Box`](std/box.md): 힙 데이터에 대한 소유 포인터입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "[`Rc`](std/rc.md): a shared reference-counted pointer for heap-allocated "
|
|
#~ "data."
|
|
#~ msgstr ""
|
|
#~ "[`Rc`](std/rc.md): 힙에 할당된 데이터에 대한 참조 카운팅 공유 포인터입니"
|
|
#~ "다."
|
|
|
|
#~ msgid "`Option` and `Result`"
|
|
#~ msgstr "`Option`과 `Result`"
|
|
|
|
#~ msgid "The types represent optional data:"
|
|
#~ msgstr "이 타입은 선택적 데이터를 나타냅니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let numbers = vec![10, 20, 30];\n"
|
|
#~ " let first: Option<&i8> = numbers.first();\n"
|
|
#~ " println!(\"first: {first:?}\");\n"
|
|
#~ "\n"
|
|
#~ " let idx: Result<usize, usize> = numbers.binary_search(&10);\n"
|
|
#~ " println!(\"idx: {idx:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let numbers = vec![10, 20, 30];\n"
|
|
#~ " let first: Option<&i8> = numbers.first();\n"
|
|
#~ " println!(\"first: {first:?}\");\n"
|
|
#~ "\n"
|
|
#~ " let idx: Result<usize, usize> = numbers.binary_search(&10);\n"
|
|
#~ " println!(\"idx: {idx:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "`Option<&T>` has zero space overhead compared to `&T`."
|
|
#~ msgstr "`Option<&T>` 는 `&T`에 비해 공간 오버헤드가 없습니다."
|
|
|
|
#~ msgid "`binary_search` returns `Result<usize, usize>`."
|
|
#~ msgstr "`binary_search`는 `Result<usize, usize>`를 반환합니다."
|
|
|
|
#~ msgid "If found, `Result::Ok` holds the index where the element is found."
|
|
#~ msgstr ""
|
|
#~ "요소가 발견된다면, `Result::Ok`는 발견된 요소의 인덱스를 보유합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Otherwise, `Result::Err` contains the index where such an element should "
|
|
#~ "be inserted."
|
|
#~ msgstr ""
|
|
#~ "아니면, `Result::Err`에는 요소가 삽입되야 하는 인덱스가 포함되어 있습니다."
|
|
|
|
#~ 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());\n"
|
|
#~ "\n"
|
|
#~ " 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());\n"
|
|
#~ "\n"
|
|
#~ " let s3 = String::from(\"🇨🇭\");\n"
|
|
#~ " println!(\"s3: len = {}, number of chars = {}\", s3.len(),\n"
|
|
#~ " s3.chars().count());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```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());\n"
|
|
#~ "\n"
|
|
#~ " 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());\n"
|
|
#~ "\n"
|
|
#~ " let s3 = String::from(\"🇨🇭\");\n"
|
|
#~ " println!(\"s3: len = {}, number of chars = {}\", s3.len(),\n"
|
|
#~ " s3.chars().count());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ 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());\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ " // Canonical macro to initialize a vector with elements.\n"
|
|
#~ " let mut v3 = vec![0, 0, 1, 2, 3, 4];\n"
|
|
#~ "\n"
|
|
#~ " // Retain only the even elements.\n"
|
|
#~ " v3.retain(|x| x % 2 == 0);\n"
|
|
#~ " println!(\"{v3:?}\");\n"
|
|
#~ "\n"
|
|
#~ " // Remove consecutive duplicates.\n"
|
|
#~ " v3.dedup();\n"
|
|
#~ " println!(\"{v3:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut v1 = Vec::new();\n"
|
|
#~ " v1.push(42);\n"
|
|
#~ " println!(\"v1: len = {}, capacity = {}\", v1.len(), v1.capacity());\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ " // 요소로 벡터를 초기화하는 표준 매크로입니다.\n"
|
|
#~ " let mut v3 = vec![0, 0, 1, 2, 3, 4];\n"
|
|
#~ "\n"
|
|
#~ " // 짝수 요소만 유지합니다.\n"
|
|
#~ " v3.retain(|x| x % 2 == 0);\n"
|
|
#~ " println!(\"{v3:?}\");\n"
|
|
#~ "\n"
|
|
#~ " // 연속 중복을 삭제합니다.\n"
|
|
#~ " v3.dedup();\n"
|
|
#~ " println!(\"{v3:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Show iterating over a vector and mutating the value: `for e in &mut v "
|
|
#~ "{ *e += 50; }`"
|
|
#~ msgstr ""
|
|
#~ "벡터를 순회하면서 값을 변경할 수도 있음을 보여주세요: `for e in &mut v "
|
|
#~ "{ *e += 50; }`"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::collections::HashMap;\n"
|
|
#~ "\n"
|
|
#~ "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);\n"
|
|
#~ "\n"
|
|
#~ " if !page_counts.contains_key(\"Les Misérables\") {\n"
|
|
#~ " println!(\"We know about {} books, but not Les Misérables.\",\n"
|
|
#~ " page_counts.len());\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ " // Use the .entry() method to insert a value if nothing is found.\n"
|
|
#~ " for book in [\"Pride and Prejudice\", \"Alice's Adventure in "
|
|
#~ "Wonderland\"] {\n"
|
|
#~ " let page_count: &mut i32 = page_counts.entry(book.to_string())."
|
|
#~ "or_insert(0);\n"
|
|
#~ " *page_count += 1;\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"{page_counts:#?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::collections::HashMap;\n"
|
|
#~ "\n"
|
|
#~ "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);\n"
|
|
#~ "\n"
|
|
#~ " if !page_counts.contains_key(\"Les Misérables\") {\n"
|
|
#~ " println!(\"We know about {} books, but not Les Misérables.\",\n"
|
|
#~ " page_counts.len());\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ " // 아무것도 찾을 수 없는 경우 .entry() 메서드를 사용하여 값을 삽입합니"
|
|
#~ "다.\n"
|
|
#~ " for book in [\"Pride and Prejudice\", \"Alice's Adventure in "
|
|
#~ "Wonderland\"] {\n"
|
|
#~ " let page_count: &mut i32 = page_counts.entry(book.to_string())."
|
|
#~ "or_insert(0);\n"
|
|
#~ " *page_count += 1;\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"{page_counts:#?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ " let pc1 = page_counts\n"
|
|
#~ " .get(\"Harry Potter and the Sorcerer's Stone \")\n"
|
|
#~ " .unwrap_or(&336);\n"
|
|
#~ " let pc2 = page_counts\n"
|
|
#~ " .entry(\"The Hunger Games\".to_string())\n"
|
|
#~ " .or_insert(374);\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,ignore\n"
|
|
#~ " let pc1 = page_counts\n"
|
|
#~ " .get(\"Harry Potter and the Sorcerer's Stone \")\n"
|
|
#~ " .unwrap_or(&336);\n"
|
|
#~ " let pc2 = page_counts\n"
|
|
#~ " .entry(\"The Hunger Games\".to_string())\n"
|
|
#~ " .or_insert(374);\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ " let page_counts = HashMap::from([\n"
|
|
#~ " (\"Harry Potter and the Sorcerer's Stone\".to_string(), 336),\n"
|
|
#~ " (\"The Hunger Games\".to_string(), 374),\n"
|
|
#~ " ]);\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,ignore\n"
|
|
#~ " let page_counts = HashMap::from([\n"
|
|
#~ " (\"Harry Potter and the Sorcerer's Stone\".to_string(), 336),\n"
|
|
#~ " (\"The Hunger Games\".to_string(), 374),\n"
|
|
#~ " ]);\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let five = Box::new(5);\n"
|
|
#~ " println!(\"five: {}\", *five);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let five = Box::new(5);\n"
|
|
#~ " println!(\"five: {}\", *five);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```bob\n"
|
|
#~ " Stack Heap\n"
|
|
#~ ".- - - - - - -. .- - - - - - -.\n"
|
|
#~ ": : : :\n"
|
|
#~ ": five : : :\n"
|
|
#~ ": +-----+ : : +-----+ :\n"
|
|
#~ ": | o---|---+-----+-->| 5 | :\n"
|
|
#~ ": +-----+ : : +-----+ :\n"
|
|
#~ ": : : :\n"
|
|
#~ ": : : :\n"
|
|
#~ "`- - - - - - -' `- - - - - - -'\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```bob\n"
|
|
#~ " 스택 힙\n"
|
|
#~ ".- - - - - - -. .- - - - - - -.\n"
|
|
#~ ": : : :\n"
|
|
#~ ": five : : :\n"
|
|
#~ ": +-----+ : : +-----+ :\n"
|
|
#~ ": | o---|---+-----+-->| 5 | :\n"
|
|
#~ ": +-----+ : : +-----+ :\n"
|
|
#~ ": : : :\n"
|
|
#~ ": : : :\n"
|
|
#~ "`- - - - - - -' `- - - - - - -'\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "In the above example, you can even leave out the `*` in the `println!` "
|
|
#~ "statement thanks to `Deref`. "
|
|
#~ msgstr ""
|
|
#~ "`Deref` 덕분에 위 예제의 `println!`문에 사용된 `*`를 빼도 문제가 없습니"
|
|
#~ "다. "
|
|
|
|
#~ msgid "Box with Recursive Data Structures"
|
|
#~ msgstr "재귀자료 구조에서의 `Box`"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "enum List<T> {\n"
|
|
#~ " Cons(T, Box<List<T>>),\n"
|
|
#~ " Nil,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "enum List<T> {\n"
|
|
#~ " Cons(T, Box<List<T>>),\n"
|
|
#~ " Nil,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::"
|
|
#~ "new(List::Nil))));\n"
|
|
#~ " println!(\"{list:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::rc::Rc;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut a = Rc::new(10);\n"
|
|
#~ " let mut b = Rc::clone(&a);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"a: {a}\");\n"
|
|
#~ " println!(\"b: {b}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::rc::Rc;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut a = Rc::new(10);\n"
|
|
#~ " let mut b = Rc::clone(&a);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"a: {a}\");\n"
|
|
#~ " println!(\"b: {b}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::cell::RefCell;\n"
|
|
#~ "use std::rc::Rc;\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug, Default)]\n"
|
|
#~ "struct Node {\n"
|
|
#~ " value: i64,\n"
|
|
#~ " children: Vec<Rc<RefCell<Node>>>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Node {\n"
|
|
#~ " fn new(value: i64) -> Rc<RefCell<Node>> {\n"
|
|
#~ " Rc::new(RefCell::new(Node { value, ..Node::default() }))\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn sum(&self) -> i64 {\n"
|
|
#~ " self.value + self.children.iter().map(|c| c.borrow().sum()).sum::"
|
|
#~ "<i64>()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let root = Node::new(1);\n"
|
|
#~ " root.borrow_mut().children.push(Node::new(5));\n"
|
|
#~ " let subtree = Node::new(10);\n"
|
|
#~ " subtree.borrow_mut().children.push(Node::new(11));\n"
|
|
#~ " subtree.borrow_mut().children.push(Node::new(12));\n"
|
|
#~ " root.borrow_mut().children.push(subtree);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"graph: {root:#?}\");\n"
|
|
#~ " println!(\"graph sum: {}\", root.borrow().sum());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::cell::RefCell;\n"
|
|
#~ "use std::rc::Rc;\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug, Default)]\n"
|
|
#~ "struct Node {\n"
|
|
#~ " value: i64,\n"
|
|
#~ " children: Vec<Rc<RefCell<Node>>>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Node {\n"
|
|
#~ " fn new(value: i64) -> Rc<RefCell<Node>> {\n"
|
|
#~ " Rc::new(RefCell::new(Node { value, ..Node::default() }))\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn sum(&self) -> i64 {\n"
|
|
#~ " self.value + self.children.iter().map(|c| c.borrow().sum()).sum::"
|
|
#~ "<i64>()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let root = Node::new(1);\n"
|
|
#~ " root.borrow_mut().children.push(Node::new(5));\n"
|
|
#~ " let subtree = Node::new(10);\n"
|
|
#~ " subtree.borrow_mut().children.push(Node::new(11));\n"
|
|
#~ " subtree.borrow_mut().children.push(Node::new(12));\n"
|
|
#~ " root.borrow_mut().children.push(subtree);\n"
|
|
#~ "\n"
|
|
#~ " println!(\"graph: {root:#?}\");\n"
|
|
#~ " println!(\"graph sum: {}\", root.borrow().sum());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "mod foo {\n"
|
|
#~ " pub fn do_something() {\n"
|
|
#~ " println!(\"In the foo module\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "mod bar {\n"
|
|
#~ " pub fn do_something() {\n"
|
|
#~ " println!(\"In the bar module\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " foo::do_something();\n"
|
|
#~ " bar::do_something();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "mod foo {\n"
|
|
#~ " pub fn do_something() {\n"
|
|
#~ " println!(\"In the foo module\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "mod bar {\n"
|
|
#~ " pub fn do_something() {\n"
|
|
#~ " println!(\"In the bar module\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " foo::do_something();\n"
|
|
#~ " bar::do_something();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "mod outer {\n"
|
|
#~ " fn private() {\n"
|
|
#~ " println!(\"outer::private\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn public() {\n"
|
|
#~ " println!(\"outer::public\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " mod inner {\n"
|
|
#~ " fn private() {\n"
|
|
#~ " println!(\"outer::inner::private\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn public() {\n"
|
|
#~ " println!(\"outer::inner::public\");\n"
|
|
#~ " super::private();\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " outer::public();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "mod outer {\n"
|
|
#~ " fn private() {\n"
|
|
#~ " println!(\"outer::private\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn public() {\n"
|
|
#~ " println!(\"outer::public\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " mod inner {\n"
|
|
#~ " fn private() {\n"
|
|
#~ " println!(\"outer::inner::private\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " pub fn public() {\n"
|
|
#~ " println!(\"outer::inner::public\");\n"
|
|
#~ " super::private();\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " outer::public();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::collections::HashSet;\n"
|
|
#~ "use std::mem::transmute;\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::collections::HashSet;\n"
|
|
#~ "use std::mem::transmute;\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "mod garden;\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "mod garden;\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "//! This module implements the garden, including a highly performant "
|
|
#~ "germination\n"
|
|
#~ "//! implementation.\n"
|
|
#~ "\n"
|
|
#~ "// Re-export types from this module.\n"
|
|
#~ "pub use seeds::SeedPacket;\n"
|
|
#~ "pub use garden::Garden;\n"
|
|
#~ "\n"
|
|
#~ "/// Sow the given seed packets.\n"
|
|
#~ "pub fn sow(seeds: Vec<SeedPacket>) { todo!() }\n"
|
|
#~ "\n"
|
|
#~ "/// Harvest the produce in the garden that is ready.\n"
|
|
#~ "pub fn harvest(garden: &mut Garden) { todo!() }\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "//! 이 모듈은 높은 성능의 발아 구현을 비롯하여 정원을\n"
|
|
#~ "//! 구현합니다.\n"
|
|
#~ "\n"
|
|
#~ "// 이 모듈에 정의된 타입을 밖으로 공개합니다.\n"
|
|
#~ "pub use seeds::SeedPacket;\n"
|
|
#~ "pub use garden::Garden;\n"
|
|
#~ "\n"
|
|
#~ "/// 지정된 씨앗 패킷을 뿌립니다.\n"
|
|
#~ "pub fn sow(seeds: Vec<SeedPacket>) { todo!() }\n"
|
|
#~ "\n"
|
|
#~ "/// 정원에서 준비된 농산물을 수확합니다.\n"
|
|
#~ "pub fn harvest(garden: &mut Garden) { todo!() }\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```ignore\n"
|
|
#~ "src/\n"
|
|
#~ "├── main.rs\n"
|
|
#~ "├── top_module.rs\n"
|
|
#~ "└── top_module/\n"
|
|
#~ " └── sub_module.rs\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```ignore\n"
|
|
#~ "src/\n"
|
|
#~ "├── main.rs\n"
|
|
#~ "├── top_module.rs\n"
|
|
#~ "└── top_module/\n"
|
|
#~ " └── sub_module.rs\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "#[path = \"some/path.rs\"]\n"
|
|
#~ "mod some_module;\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "#[path = \"some/path.rs\"]\n"
|
|
#~ "mod some_module;\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Day 2: Afternoon Exercises"
|
|
#~ msgstr "2일차 오후 연습문제"
|
|
|
|
#~ msgid ""
|
|
#~ "The exercises for this afternoon will focus on strings and iterators."
|
|
#~ msgstr "이번 연습문제는 문자열과 반복자에 초점을 맞출 것입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Copy the code below to <https://play.rust-lang.org/> and implement the "
|
|
#~ "function."
|
|
#~ msgstr ""
|
|
#~ "아래 코드를 <https://play.rust-lang.org/>에 복사해서 구현하시면 됩니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Try to solve the problem the \"simple\" way first, using `for` loops and "
|
|
#~ "integers. Then, revisit the solution and try to implement it with "
|
|
#~ "iterators."
|
|
#~ msgstr ""
|
|
#~ "`for`반복문과 인덱스를 이용하는 \"쉬운\"방법으로 먼저 풀어 보세요. 그런 다"
|
|
#~ "음 반복자를 이용해서 다시 풀어 보세요."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "pub fn luhn(cc_number: &str) -> bool {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_non_digit_cc_number() {\n"
|
|
#~ " assert!(!luhn(\"foo\"));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_empty_cc_number() {\n"
|
|
#~ " assert!(!luhn(\"\"));\n"
|
|
#~ " assert!(!luhn(\" \"));\n"
|
|
#~ " assert!(!luhn(\" \"));\n"
|
|
#~ " assert!(!luhn(\" \"));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_single_digit_cc_number() {\n"
|
|
#~ " assert!(!luhn(\"0\"));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_two_digit_cc_number() {\n"
|
|
#~ " assert!(luhn(\" 0 0 \"));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[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"
|
|
#~ "\n"
|
|
#~ "#[allow(dead_code)]\n"
|
|
#~ "fn main() {}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "pub fn luhn(cc_number: &str) -> bool {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_non_digit_cc_number() {\n"
|
|
#~ " assert!(!luhn(\"foo\"));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_empty_cc_number() {\n"
|
|
#~ " assert!(!luhn(\"\"));\n"
|
|
#~ " assert!(!luhn(\" \"));\n"
|
|
#~ " assert!(!luhn(\" \"));\n"
|
|
#~ " assert!(!luhn(\" \"));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_single_digit_cc_number() {\n"
|
|
#~ " assert!(!luhn(\"0\"));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_two_digit_cc_number() {\n"
|
|
#~ " assert!(luhn(\" 0 0 \"));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[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"
|
|
#~ "\n"
|
|
#~ "#[allow(dead_code)]\n"
|
|
#~ "fn main() {}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "In this exercise, you are implementing a routing component of a web "
|
|
#~ "server. The server is configured with a number of _path prefixes_ which "
|
|
#~ "are matched against _request paths_. The path prefixes can contain a "
|
|
#~ "wildcard character which matches a full segment. See the unit tests below."
|
|
#~ msgstr ""
|
|
#~ "이번 훈련은 웹 서버의 라우팅 컴포넌트를 구현합니다. 서버는 _요청 경로"
|
|
#~ "(request path)_ 를 처리할 수 있는 여러 개의 _경로 접두사(path prefix)_ 로 "
|
|
#~ "구성됩니다. 경로 접두사는 와일드카드문자를 포함할 수 있습니다. 아래 단위 "
|
|
#~ "테스트 코드를 참조하세요."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "pub fn prefix_matches(prefix: &str, request_path: &str) -> bool {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ "}\n"
|
|
#~ "\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\"));\n"
|
|
#~ "\n"
|
|
#~ " assert!(!prefix_matches(\"/v1/publishers\", \"/v1\"));\n"
|
|
#~ " assert!(!prefix_matches(\"/v1/publishers\", \"/v1/"
|
|
#~ "publishersBooks\"));\n"
|
|
#~ " assert!(!prefix_matches(\"/v1/publishers\", \"/v1/parent/"
|
|
#~ "publishers\"));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[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"
|
|
#~ " ));\n"
|
|
#~ "\n"
|
|
#~ " 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 ""
|
|
#~ "```rust\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "pub fn prefix_matches(prefix: &str, request_path: &str) -> bool {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ "}\n"
|
|
#~ "\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\"));\n"
|
|
#~ "\n"
|
|
#~ " assert!(!prefix_matches(\"/v1/publishers\", \"/v1\"));\n"
|
|
#~ " assert!(!prefix_matches(\"/v1/publishers\", \"/v1/"
|
|
#~ "publishersBooks\"));\n"
|
|
#~ " assert!(!prefix_matches(\"/v1/publishers\", \"/v1/parent/"
|
|
#~ "publishers\"));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[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"
|
|
#~ " ));\n"
|
|
#~ "\n"
|
|
#~ " assert!(!prefix_matches(\"/v1/publishers/*/books\", \"/v1/"
|
|
#~ "publishers\"));\n"
|
|
#~ " assert!(!prefix_matches(\n"
|
|
#~ " \"/v1/publishers/*/books\",\n"
|
|
#~ " \"/v1/publishers/foo/booksByAuthor\"\n"
|
|
#~ " ));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Traits: deriving traits, default methods, and important standard library "
|
|
#~ "traits."
|
|
#~ msgstr ""
|
|
#~ "트레잇: 트레잇 상속(derive), 디폴트 메서드, 표준 라이브러에 있는 중요한 트"
|
|
#~ "레잇들."
|
|
|
|
#~ msgid ""
|
|
#~ "Generics: generic data types, generic methods, monomorphization, and "
|
|
#~ "trait objects."
|
|
#~ msgstr ""
|
|
#~ "제네릭: 제네릭 데이터 타입, 제네릭 메서드, 단형화(monomorphization), 트레"
|
|
#~ "잇 객체."
|
|
|
|
#~ msgid "Testing: unit tests, documentation tests, and integration tests."
|
|
#~ msgstr "테스트: 단위 테스트, 문서 테스트 및 통합 테스트."
|
|
|
|
#~ msgid ""
|
|
#~ "Unsafe Rust: raw pointers, static variables, unsafe functions, and extern "
|
|
#~ "functions."
|
|
#~ msgstr ""
|
|
#~ "안전하지 않은 러스트: 원시(raw) 포인터, 정적 변수, 안전하지 않은 함수, 외"
|
|
#~ "부 함수."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Point<T> {\n"
|
|
#~ " x: T,\n"
|
|
#~ " y: T,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Point<T> {\n"
|
|
#~ " x: T,\n"
|
|
#~ " y: T,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid "Try declaring a new variable `let p = Point { x: 5, y: 10.0 };`."
|
|
#~ msgstr "새 변수 `let p = Point { x: 5, y: 10.0 };`를 선언해 보세요."
|
|
|
|
#~ msgid "Fix the code to allow points that have elements of different types."
|
|
#~ msgstr ""
|
|
#~ "`Point`가 서로 다른 타입의 값들으로 이루어져도 컴파일 되도록 코드를 수정"
|
|
#~ "해 보세요."
|
|
|
|
#~ msgid "You can declare a generic type on your `impl` block:"
|
|
#~ msgstr "`impl` 블록에서도 제네릭 타입을 선언할 수 있습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Point<T>(T, T);\n"
|
|
#~ "\n"
|
|
#~ "impl<T> Point<T> {\n"
|
|
#~ " fn x(&self) -> &T {\n"
|
|
#~ " &self.0 // + 10\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // fn set_x(&mut self, x: T)\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let p = Point(5, 10);\n"
|
|
#~ " println!(\"p.x = {}\", p.x());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Point<T>(T, T);\n"
|
|
#~ "\n"
|
|
#~ "impl<T> Point<T> {\n"
|
|
#~ " fn x(&self) -> &T {\n"
|
|
#~ " &self.0 // + 10\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // fn set_x(&mut self, x: T)\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let p = Point(5, 10);\n"
|
|
#~ " println!(\"p.x = {}\", p.x());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Generic code is turned into non-generic code based on the call sites:"
|
|
#~ msgstr "제네릭 코드는 호출부에서 비 제네릭 코드로 전환됩니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let integer = Some(5);\n"
|
|
#~ " let float = Some(5.0);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let integer = Some(5);\n"
|
|
#~ " let float = Some(5.0);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "behaves as if you wrote"
|
|
#~ msgstr "위 코드는 아래와 같이 동작합니다"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "enum Option_i32 {\n"
|
|
#~ " Some(i32),\n"
|
|
#~ " None,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "enum Option_f64 {\n"
|
|
#~ " Some(f64),\n"
|
|
#~ " None,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let integer = Option_i32::Some(5);\n"
|
|
#~ " let float = Option_f64::Some(5.0);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "enum Option_i32 {\n"
|
|
#~ " Some(i32),\n"
|
|
#~ " None,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "enum Option_f64 {\n"
|
|
#~ " Some(f64),\n"
|
|
#~ " None,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let integer = Option_i32::Some(5);\n"
|
|
#~ " let float = Option_f64::Some(5.0);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "trait Pet {\n"
|
|
#~ " fn name(&self) -> String;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "struct Dog {\n"
|
|
#~ " name: String,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "struct Cat;\n"
|
|
#~ "\n"
|
|
#~ "impl Pet for Dog {\n"
|
|
#~ " fn name(&self) -> String {\n"
|
|
#~ " self.name.clone()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Pet for Cat {\n"
|
|
#~ " fn name(&self) -> String {\n"
|
|
#~ " String::from(\"The cat\") // No name, cats won't respond to it "
|
|
#~ "anyway.\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn greet<P: Pet>(pet: &P) {\n"
|
|
#~ " println!(\"Who's a cutie? {} is!\", pet.name());\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let fido = Dog { name: \"Fido\".into() };\n"
|
|
#~ " greet(&fido);\n"
|
|
#~ "\n"
|
|
#~ " let captain_floof = Cat;\n"
|
|
#~ " greet(&captain_floof);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "trait Pet {\n"
|
|
#~ " fn name(&self) -> String;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "struct Dog {\n"
|
|
#~ " name: String,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "struct Cat;\n"
|
|
#~ "\n"
|
|
#~ "impl Pet for Dog {\n"
|
|
#~ " fn name(&self) -> String {\n"
|
|
#~ " self.name.clone()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Pet for Cat {\n"
|
|
#~ " fn name(&self) -> String {\n"
|
|
#~ " String::from(\"The cat\") // No name, cats won't respond to it "
|
|
#~ "anyway.\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn greet<P: Pet>(pet: &P) {\n"
|
|
#~ " println!(\"Who's a cutie? {} is!\", pet.name());\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let fido = Dog { name: \"Fido\".into() };\n"
|
|
#~ " greet(&fido);\n"
|
|
#~ "\n"
|
|
#~ " let captain_floof = Cat;\n"
|
|
#~ " greet(&captain_floof);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "trait Pet {\n"
|
|
#~ " fn name(&self) -> String;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "struct Dog {\n"
|
|
#~ " name: String,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "struct Cat;\n"
|
|
#~ "\n"
|
|
#~ "impl Pet for Dog {\n"
|
|
#~ " fn name(&self) -> String {\n"
|
|
#~ " self.name.clone()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Pet for Cat {\n"
|
|
#~ " fn name(&self) -> String {\n"
|
|
#~ " String::from(\"The cat\") // No name, cats won't respond to it "
|
|
#~ "anyway.\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let pets: Vec<Box<dyn Pet>> = vec![\n"
|
|
#~ " Box::new(Cat),\n"
|
|
#~ " Box::new(Dog { name: String::from(\"Fido\") }),\n"
|
|
#~ " ];\n"
|
|
#~ " for pet in pets {\n"
|
|
#~ " println!(\"Hello {}!\", pet.name());\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "trait Pet {\n"
|
|
#~ " fn name(&self) -> String;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "struct Dog {\n"
|
|
#~ " name: String,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "struct Cat;\n"
|
|
#~ "\n"
|
|
#~ "impl Pet for Dog {\n"
|
|
#~ " fn name(&self) -> String {\n"
|
|
#~ " self.name.clone()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Pet for Cat {\n"
|
|
#~ " fn name(&self) -> String {\n"
|
|
#~ " String::from(\"The cat\") // No name, cats won't respond to it "
|
|
#~ "anyway.\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let pets: Vec<Box<dyn Pet>> = vec![\n"
|
|
#~ " Box::new(Cat),\n"
|
|
#~ " Box::new(Dog { name: String::from(\"Fido\") }),\n"
|
|
#~ " ];\n"
|
|
#~ " for pet in pets {\n"
|
|
#~ " println!(\"Hello {}!\", pet.name());\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```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 Pet>());\n"
|
|
#~ " println!(\"{}\", std::mem::size_of::<Box<dyn Pet>>());\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```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 Pet>());\n"
|
|
#~ " println!(\"{}\", std::mem::size_of::<Box<dyn Pet>>());\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "Rust derive macros work by automatically generating code that implements "
|
|
#~ "the specified traits for a data structure."
|
|
#~ msgstr ""
|
|
#~ "러스트의 derive 매크로는 데이터 구조체가 특정 트레잇을 구현하는 코드를 자"
|
|
#~ "동으로 만들어 줍니다."
|
|
|
|
#~ msgid "You can let the compiler derive a number of traits as follows:"
|
|
#~ msgstr ""
|
|
#~ "컴파일러가 여러가지 트레잇을 상속(derive)하도록 할 수 있습니다. 이 경우 컴"
|
|
#~ "파일러가 트레잇을 자동으로 구현합니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug, Clone, PartialEq, Eq, Default)]\n"
|
|
#~ "struct Player {\n"
|
|
#~ " name: String,\n"
|
|
#~ " strength: u8,\n"
|
|
#~ " hit_points: u8,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug, Clone, PartialEq, Eq, Default)]\n"
|
|
#~ "struct Player {\n"
|
|
#~ " name: String,\n"
|
|
#~ " strength: u8,\n"
|
|
#~ " hit_points: u8,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid "Traits can implement behavior in terms of other trait methods:"
|
|
#~ msgstr ""
|
|
#~ "트레잇의 디폴트 메서드에서 다른(구현되지 않은) 메소드를 이용할 수 있습니"
|
|
#~ "다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "trait Equals {\n"
|
|
#~ " fn equals(&self, other: &Self) -> bool;\n"
|
|
#~ " fn not_equals(&self, other: &Self) -> bool {\n"
|
|
#~ " !self.equals(other)\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Centimeter(i16);\n"
|
|
#~ "\n"
|
|
#~ "impl Equals for Centimeter {\n"
|
|
#~ " fn equals(&self, other: &Centimeter) -> bool {\n"
|
|
#~ " self.0 == other.0\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let a = Centimeter(10);\n"
|
|
#~ " let b = Centimeter(20);\n"
|
|
#~ " println!(\"{a:?} equals {b:?}: {}\", a.equals(&b));\n"
|
|
#~ " println!(\"{a:?} not_equals {b:?}: {}\", a.not_equals(&b));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "trait Equals {\n"
|
|
#~ " fn equals(&self, other: &Self) -> bool;\n"
|
|
#~ " fn not_equals(&self, other: &Self) -> bool {\n"
|
|
#~ " !self.equals(other)\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Centimeter(i16);\n"
|
|
#~ "\n"
|
|
#~ "impl Equals for Centimeter {\n"
|
|
#~ " fn equals(&self, other: &Centimeter) -> bool {\n"
|
|
#~ " self.0 == other.0\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let a = Centimeter(10);\n"
|
|
#~ " let b = Centimeter(20);\n"
|
|
#~ " println!(\"{a:?} equals {b:?}: {}\", a.equals(&b));\n"
|
|
#~ " println!(\"{a:?} not_equals {b:?}: {}\", a.not_equals(&b));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Move method `not_equals` to a new trait `NotEquals`."
|
|
#~ msgstr "`not_equal` 메서드를 새로운 트레잇인 `NotEqual`로 이동합니다."
|
|
|
|
#~ msgid "Make `Equals` a super trait for `NotEquals`."
|
|
#~ msgstr "`NotEqual`을 `Equal`의 슈퍼 트레잇으로 만듭니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "trait NotEquals: Equals {\n"
|
|
#~ " fn not_equals(&self, other: &Self) -> bool {\n"
|
|
#~ " !self.equals(other)\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "trait NotEquals: Equals {\n"
|
|
#~ " fn not_equals(&self, other: &Self) -> bool {\n"
|
|
#~ " !self.equals(other)\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Provide a blanket implementation of `NotEquals` for `Equals`."
|
|
#~ msgstr "`Equal`에 `NotEqual`의 포괄적 구현을 제공합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "trait NotEquals {\n"
|
|
#~ " fn not_equals(&self, other: &Self) -> bool;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl<T> NotEquals for T where T: Equals {\n"
|
|
#~ " fn not_equals(&self, other: &Self) -> bool {\n"
|
|
#~ " !self.equals(other)\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "trait NotEquals {\n"
|
|
#~ " fn not_equals(&self, other: &Self) -> bool;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl<T> NotEquals for T where T: Equals {\n"
|
|
#~ " fn not_equals(&self, other: &Self) -> bool {\n"
|
|
#~ " !self.equals(other)\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "With the blanket implementation, you no longer need `Equals` as a super "
|
|
#~ "trait for `NotEqual`."
|
|
#~ msgstr ""
|
|
#~ "포괄적 구현을 사용하면 더 이상 `NotEqual`이 `Equal`의 슈퍼 트레잇으로 필요"
|
|
#~ "하지 않습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn duplicate<T: Clone>(a: T) -> (T, T) {\n"
|
|
#~ " (a.clone(), a.clone())\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// Syntactic sugar for:\n"
|
|
#~ "// fn add_42_millions<T: Into<i32>>(x: T) -> i32 {\n"
|
|
#~ "fn add_42_millions(x: impl Into<i32>) -> i32 {\n"
|
|
#~ " x.into() + 42_000_000\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// struct NotClonable;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let foo = String::from(\"foo\");\n"
|
|
#~ " let pair = duplicate(foo);\n"
|
|
#~ " println!(\"{pair:?}\");\n"
|
|
#~ "\n"
|
|
#~ " let many = add_42_millions(42_i8);\n"
|
|
#~ " println!(\"{many}\");\n"
|
|
#~ " let many_more = add_42_millions(10_000_000);\n"
|
|
#~ " println!(\"{many_more}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn duplicate<T: Clone>(a: T) -> (T, T) {\n"
|
|
#~ " (a.clone(), a.clone())\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// 다음에 대한 문법 슈가:\n"
|
|
#~ "// fn add_42_millions<T: Into<i32>>(x: T) -> i32 {\n"
|
|
#~ "fn add_42_millions(x: impl Into<i32>) -> i32 {\n"
|
|
#~ " x.into() + 42_000_000\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// struct NotClonable;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let foo = String::from(\"foo\");\n"
|
|
#~ " let pair = duplicate(foo);\n"
|
|
#~ " println!(\"{pair:?}\");\n"
|
|
#~ "\n"
|
|
#~ " let many = add_42_millions(42_i8);\n"
|
|
#~ " println!(\"{many}\");\n"
|
|
#~ " let many_more = add_42_millions(10_000_000);\n"
|
|
#~ " println!(\"{many_more}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "fn duplicate<T>(a: T) -> (T, T)\n"
|
|
#~ "where\n"
|
|
#~ " T: Clone,\n"
|
|
#~ "{\n"
|
|
#~ " (a.clone(), a.clone())\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "fn duplicate<T>(a: T) -> (T, T)\n"
|
|
#~ "where\n"
|
|
#~ " T: Clone,\n"
|
|
#~ "{\n"
|
|
#~ " (a.clone(), a.clone())\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::fmt::Display;\n"
|
|
#~ "\n"
|
|
#~ "fn get_x(name: impl Display) -> impl Display {\n"
|
|
#~ " format!(\"Hello {name}\")\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let x = get_x(\"foo\");\n"
|
|
#~ " println!(\"{x}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::fmt::Display;\n"
|
|
#~ "\n"
|
|
#~ "fn get_x(name: impl Display) -> impl Display {\n"
|
|
#~ " format!(\"Hello {name}\")\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let x = get_x(\"foo\");\n"
|
|
#~ " println!(\"{x}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "`impl Trait` allows you to work with types which you cannot name."
|
|
#~ msgstr "`impl Trait`를 이용하면 이름이 없는 타입을 다룰 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "This example is great, because it uses `impl Display` twice. It helps to "
|
|
#~ "explain that nothing here enforces that it is _the same_ `impl Display` "
|
|
#~ "type. If we used a single `T: Display`, it would enforce the constraint "
|
|
#~ "that input `T` and return `T` type are the same type. It would not work "
|
|
#~ "for this particular function, as the type we expect as input is likely "
|
|
#~ "not what `format!` returns. If we wanted to do the same via `: Display` "
|
|
#~ "syntax, we'd need two independent generic parameters."
|
|
#~ msgstr ""
|
|
#~ "이 예시는 `impl Display`가 두번 사용 되었다는 점에서 훌륭합니다. 여기서 중"
|
|
#~ "요한 것은 이 두 `impl Display`가 실제로 같은 타입일 필요가 없다는 것입니"
|
|
#~ "다. 만약 `T: Display`로 트레잇 경계를 정하고 입력 파라메터와 리턴 값의 타"
|
|
#~ "입을 모두 `T`로 했다면, 이는 입력과 리턴값이 같은 타입임을 강제합니다. 이"
|
|
#~ "렇게 했다면 위의 예제는 동작하지 않았을 것입니다. 왜냐하면, 입력 값의 타입"
|
|
#~ "이 `format!`이 리턴하는 타입과 같지 않을 가능성이 높기 때문입니다. 만약 "
|
|
#~ "`: Display` 문법을 사용하고 싶다면 독립적인 제네릭 매개변수가 두 개가 필요"
|
|
#~ "합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "We will now look at some of the most common traits of the Rust standard "
|
|
#~ "library:"
|
|
#~ msgstr ""
|
|
#~ "러스트 표준 라이브러리에는 다음과 같은 범용 트레잇들이 정의되어 있습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "[`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html) and "
|
|
#~ "[`IntoIterator`](https://doc.rust-lang.org/std/iter/trait.IntoIterator."
|
|
#~ "html) used in `for` loops,"
|
|
#~ msgstr ""
|
|
#~ "[`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html)와 "
|
|
#~ "[`IntoIterator`](https://doc.rust-lang.org/std/iter/trait.IntoIterator."
|
|
#~ "html) 트레잇은 `for` 반복문에서 사용됩니다,"
|
|
|
|
#~ msgid ""
|
|
#~ "[`From`](https://doc.rust-lang.org/std/convert/trait.From.html) and "
|
|
#~ "[`Into`](https://doc.rust-lang.org/std/convert/trait.Into.html) used to "
|
|
#~ "convert values,"
|
|
#~ msgstr ""
|
|
#~ "[`From`](https://doc.rust-lang.org/std/convert/trait.From.html)과 [`Into`]"
|
|
#~ "(https://doc.rust-lang.org/std/convert/trait.Into.html) 트레잇은 값을 변환"
|
|
#~ "할 때 사용됩니다,"
|
|
|
|
#~ msgid ""
|
|
#~ "[`Read`](https://doc.rust-lang.org/std/io/trait.Read.html) and [`Write`]"
|
|
#~ "(https://doc.rust-lang.org/std/io/trait.Write.html) used for IO,"
|
|
#~ msgstr ""
|
|
#~ "[`Read`](https://doc.rust-lang.org/std/io/trait.Read.html)와 [`Write`]"
|
|
#~ "(https://doc.rust-lang.org/std/io/trait.Write.html) 트레잇은 I/O에 사용됩"
|
|
#~ "니다,"
|
|
|
|
#~ msgid ""
|
|
#~ "[`Add`](https://doc.rust-lang.org/std/ops/trait.Add.html), [`Mul`]"
|
|
#~ "(https://doc.rust-lang.org/std/ops/trait.Mul.html), ... used for operator "
|
|
#~ "overloading, and"
|
|
#~ msgstr ""
|
|
#~ "[`Add`](https://doc.rust-lang.org/std/ops/trait.Add.html), [`Mul`]"
|
|
#~ "(https://doc.rust-lang.org/std/ops/trait.Mul.html) 등의 트레잇들은 연산자 "
|
|
#~ "오버로딩(overloading)에 사용됩니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "struct Fibonacci {\n"
|
|
#~ " curr: u32,\n"
|
|
#~ " next: u32,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Iterator for Fibonacci {\n"
|
|
#~ " type Item = u32;\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "struct Fibonacci {\n"
|
|
#~ " curr: u32,\n"
|
|
#~ " next: u32,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Iterator for Fibonacci {\n"
|
|
#~ " type Item = u32;\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let primes = vec![2, 3, 5, 7];\n"
|
|
#~ " let prime_squares = primes\n"
|
|
#~ " .into_iter()\n"
|
|
#~ " .map(|prime| prime * prime)\n"
|
|
#~ " .collect::<Vec<_>>();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let primes = vec![2, 3, 5, 7];\n"
|
|
#~ " let prime_squares = primes\n"
|
|
#~ " .into_iter()\n"
|
|
#~ " .map(|prime| prime * prime)\n"
|
|
#~ " .collect::<Vec<_>>();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "`Iterator` implements `fn collect<B>(self) -> B where B: "
|
|
#~ "FromIterator<Self::Item>, Self: Sized`"
|
|
#~ msgstr ""
|
|
#~ "`Iterator`에는 다음 함수가 정의되어 있습니다: `fn collect<B>(self) -> B "
|
|
#~ "where B: FromIterator<Self::Item>, Self: Sized`"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::io::{BufRead, BufReader, Read, Result};\n"
|
|
#~ "\n"
|
|
#~ "fn count_lines<R: Read>(reader: R) -> usize {\n"
|
|
#~ " let buf_reader = BufReader::new(reader);\n"
|
|
#~ " buf_reader.lines().count()\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() -> Result<()> {\n"
|
|
#~ " let slice: &[u8] = b\"foo\\nbar\\nbaz\\n\";\n"
|
|
#~ " println!(\"lines in slice: {}\", count_lines(slice));\n"
|
|
#~ "\n"
|
|
#~ " let file = std::fs::File::open(std::env::current_exe()?)?;\n"
|
|
#~ " println!(\"lines in file: {}\", count_lines(file));\n"
|
|
#~ " Ok(())\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::io::{BufRead, BufReader, Read, Result};\n"
|
|
#~ "\n"
|
|
#~ "fn count_lines<R: Read>(reader: R) -> usize {\n"
|
|
#~ " let buf_reader = BufReader::new(reader);\n"
|
|
#~ " buf_reader.lines().count()\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() -> Result<()> {\n"
|
|
#~ " let slice: &[u8] = b\"foo\\nbar\\nbaz\\n\";\n"
|
|
#~ " println!(\"lines in slice: {}\", count_lines(slice));\n"
|
|
#~ "\n"
|
|
#~ " let file = std::fs::File::open(std::env::current_exe()?)?;\n"
|
|
#~ " println!(\"lines in file: {}\", count_lines(file));\n"
|
|
#~ " Ok(())\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::io::{Result, Write};\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::io::{Result, Write};\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "struct Droppable {\n"
|
|
#~ " name: &'static str,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Drop for Droppable {\n"
|
|
#~ " fn drop(&mut self) {\n"
|
|
#~ " println!(\"Dropping {}\", self.name);\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "struct Droppable {\n"
|
|
#~ " name: &'static str,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Drop for Droppable {\n"
|
|
#~ " fn drop(&mut self) {\n"
|
|
#~ " println!(\"Dropping {}\", self.name);\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug, Default)]\n"
|
|
#~ "struct Derived {\n"
|
|
#~ " x: u32,\n"
|
|
#~ " y: String,\n"
|
|
#~ " z: Implemented,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Implemented(String);\n"
|
|
#~ "\n"
|
|
#~ "impl Default for Implemented {\n"
|
|
#~ " fn default() -> Self {\n"
|
|
#~ " Self(\"John Smith\".into())\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let default_struct = Derived::default();\n"
|
|
#~ " println!(\"{default_struct:#?}\");\n"
|
|
#~ "\n"
|
|
#~ " let almost_default_struct = Derived {\n"
|
|
#~ " y: \"Y is set!\".into(),\n"
|
|
#~ " ..Derived::default()\n"
|
|
#~ " };\n"
|
|
#~ " println!(\"{almost_default_struct:#?}\");\n"
|
|
#~ "\n"
|
|
#~ " let nothing: Option<Derived> = None;\n"
|
|
#~ " println!(\"{:#?}\", nothing.unwrap_or_default());\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug, Default)]\n"
|
|
#~ "struct Derived {\n"
|
|
#~ " x: u32,\n"
|
|
#~ " y: String,\n"
|
|
#~ " z: Implemented,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Implemented(String);\n"
|
|
#~ "\n"
|
|
#~ "impl Default for Implemented {\n"
|
|
#~ " fn default() -> Self {\n"
|
|
#~ " Self(\"John Smith\".into())\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let default_struct = Derived::default();\n"
|
|
#~ " println!(\"{default_struct:#?}\");\n"
|
|
#~ "\n"
|
|
#~ " let almost_default_struct = Derived {\n"
|
|
#~ " y: \"Y is set!\".into(),\n"
|
|
#~ " ..Derived::default()\n"
|
|
#~ " };\n"
|
|
#~ " println!(\"{almost_default_struct:#?}\");\n"
|
|
#~ "\n"
|
|
#~ " let nothing: Option<Derived> = None;\n"
|
|
#~ " println!(\"{:#?}\", nothing.unwrap_or_default());\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "`Add`, `Mul`, ..."
|
|
#~ msgstr "`Add`, `Mul`, ..."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug, Copy, Clone)]\n"
|
|
#~ "struct Point { x: i32, y: i32 }\n"
|
|
#~ "\n"
|
|
#~ "impl std::ops::Add for Point {\n"
|
|
#~ " type Output = Self;\n"
|
|
#~ "\n"
|
|
#~ " fn add(self, other: Self) -> Self {\n"
|
|
#~ " Self {x: self.x + other.x, y: self.y + other.y}\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[derive(Debug, Copy, Clone)]\n"
|
|
#~ "struct Point { x: i32, y: i32 }\n"
|
|
#~ "\n"
|
|
#~ "impl std::ops::Add for Point {\n"
|
|
#~ " type Output = Self;\n"
|
|
#~ "\n"
|
|
#~ " fn add(self, other: Self) -> Self {\n"
|
|
#~ " Self {x: self.x + other.x, y: self.y + other.y}\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ 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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let add_3 = |x| x + 3;\n"
|
|
#~ " println!(\"add_3: {}\", apply_with_log(add_3, 10));\n"
|
|
#~ " println!(\"add_3: {}\", apply_with_log(add_3, 20));\n"
|
|
#~ "\n"
|
|
#~ " let mut v = Vec::new();\n"
|
|
#~ " let mut accumulate = |x: i32| {\n"
|
|
#~ " v.push(x);\n"
|
|
#~ " v.iter().sum::<i32>()\n"
|
|
#~ " };\n"
|
|
#~ " println!(\"accumulate: {}\", apply_with_log(&mut accumulate, 4));\n"
|
|
#~ " println!(\"accumulate: {}\", apply_with_log(&mut accumulate, 5));\n"
|
|
#~ "\n"
|
|
#~ " let multiply_sum = |x| x * v.into_iter().sum::<i32>();\n"
|
|
#~ " println!(\"multiply_sum: {}\", apply_with_log(multiply_sum, 3));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let add_3 = |x| x + 3;\n"
|
|
#~ " println!(\"add_3: {}\", apply_with_log(add_3, 10));\n"
|
|
#~ " println!(\"add_3: {}\", apply_with_log(add_3, 20));\n"
|
|
#~ "\n"
|
|
#~ " let mut v = Vec::new();\n"
|
|
#~ " let mut accumulate = |x: i32| {\n"
|
|
#~ " v.push(x);\n"
|
|
#~ " v.iter().sum::<i32>()\n"
|
|
#~ " };\n"
|
|
#~ " println!(\"accumulate: {}\", apply_with_log(&mut accumulate, 4));\n"
|
|
#~ " println!(\"accumulate: {}\", apply_with_log(&mut accumulate, 5));\n"
|
|
#~ "\n"
|
|
#~ " let multiply_sum = |x| x * v.into_iter().sum::<i32>();\n"
|
|
#~ " println!(\"multiply_sum: {}\", apply_with_log(multiply_sum, 3));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn make_greeter(prefix: String) -> impl Fn(&str) {\n"
|
|
#~ " return move |name| println!(\"{} {}\", prefix, name)\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let hi = make_greeter(\"Hi\".to_string());\n"
|
|
#~ " hi(\"there\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn make_greeter(prefix: String) -> impl Fn(&str) {\n"
|
|
#~ " return move |name| println!(\"{} {}\", prefix, name)\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let hi = make_greeter(\"Hi\".to_string());\n"
|
|
#~ " hi(\"there\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Day 3: Morning Exercises"
|
|
#~ msgstr "3일차 오전 연습문제"
|
|
|
|
#~ msgid "We will design a classical GUI library traits and trait objects."
|
|
#~ msgstr ""
|
|
#~ "이번 연습문제에서는 트레잇와 트레잇 객체를 통해 고전적인 GUI 라이브러리를 "
|
|
#~ "설계할 것입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "`Button`: has a `label` and a callback function which is invoked when the "
|
|
#~ "button is pressed."
|
|
#~ msgstr ""
|
|
#~ "`Button`: `label` 속성을 가지고 있으며, 버튼이 눌렸을때 실행되는 콜백 함수"
|
|
#~ "가 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,should_panic\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_imports, unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "pub trait Widget {\n"
|
|
#~ " /// Natural width of `self`.\n"
|
|
#~ " fn width(&self) -> usize;\n"
|
|
#~ "\n"
|
|
#~ " /// Draw the widget into a buffer.\n"
|
|
#~ " fn draw_into(&self, buffer: &mut dyn std::fmt::Write);\n"
|
|
#~ "\n"
|
|
#~ " /// 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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct Label {\n"
|
|
#~ " label: String,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Label {\n"
|
|
#~ " fn new(label: &str) -> Label {\n"
|
|
#~ " Label {\n"
|
|
#~ " label: label.to_owned(),\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct Button {\n"
|
|
#~ " label: Label,\n"
|
|
#~ " callback: Box<dyn FnMut()>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Button {\n"
|
|
#~ " fn new(label: &str, callback: Box<dyn FnMut()>) -> Button {\n"
|
|
#~ " Button {\n"
|
|
#~ " label: Label::new(label),\n"
|
|
#~ " callback,\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct Window {\n"
|
|
#~ " title: String,\n"
|
|
#~ " widgets: Vec<Box<dyn Widget>>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Window {\n"
|
|
#~ " fn new(title: &str) -> Window {\n"
|
|
#~ " Window {\n"
|
|
#~ " title: title.to_owned(),\n"
|
|
#~ " widgets: Vec::new(),\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn add_widget(&mut self, widget: Box<dyn Widget>) {\n"
|
|
#~ " self.widgets.push(widget);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn inner_width(&self) -> usize {\n"
|
|
#~ " std::cmp::max(\n"
|
|
#~ " self.title.chars().count(),\n"
|
|
#~ " self.widgets.iter().map(|w| w.width()).max().unwrap_or(0),\n"
|
|
#~ " )\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "\n"
|
|
#~ "impl Widget for Label {\n"
|
|
#~ " fn width(&self) -> usize {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Widget for Button {\n"
|
|
#~ " fn width(&self) -> usize {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Widget for Window {\n"
|
|
#~ " fn width(&self) -> usize {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\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"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,should_panic\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_imports, unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "pub trait Widget {\n"
|
|
#~ " /// Natural width of `self`.\n"
|
|
#~ " fn width(&self) -> usize;\n"
|
|
#~ "\n"
|
|
#~ " /// Draw the widget into a buffer.\n"
|
|
#~ " fn draw_into(&self, buffer: &mut dyn std::fmt::Write);\n"
|
|
#~ "\n"
|
|
#~ " /// 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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct Label {\n"
|
|
#~ " label: String,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Label {\n"
|
|
#~ " fn new(label: &str) -> Label {\n"
|
|
#~ " Label {\n"
|
|
#~ " label: label.to_owned(),\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct Button {\n"
|
|
#~ " label: Label,\n"
|
|
#~ " callback: Box<dyn FnMut()>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Button {\n"
|
|
#~ " fn new(label: &str, callback: Box<dyn FnMut()>) -> Button {\n"
|
|
#~ " Button {\n"
|
|
#~ " label: Label::new(label),\n"
|
|
#~ " callback,\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub struct Window {\n"
|
|
#~ " title: String,\n"
|
|
#~ " widgets: Vec<Box<dyn Widget>>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Window {\n"
|
|
#~ " fn new(title: &str) -> Window {\n"
|
|
#~ " Window {\n"
|
|
#~ " title: title.to_owned(),\n"
|
|
#~ " widgets: Vec::new(),\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn add_widget(&mut self, widget: Box<dyn Widget>) {\n"
|
|
#~ " self.widgets.push(widget);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn inner_width(&self) -> usize {\n"
|
|
#~ " std::cmp::max(\n"
|
|
#~ " self.title.chars().count(),\n"
|
|
#~ " self.widgets.iter().map(|w| w.width()).max().unwrap_or(0),\n"
|
|
#~ " )\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "\n"
|
|
#~ "impl Widget for Label {\n"
|
|
#~ " fn width(&self) -> usize {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Widget for Button {\n"
|
|
#~ " fn width(&self) -> usize {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Widget for Window {\n"
|
|
#~ " fn width(&self) -> usize {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```text\n"
|
|
#~ "========\n"
|
|
#~ "Rust GUI Demo 1.23\n"
|
|
#~ "========\n"
|
|
#~ "\n"
|
|
#~ "This is a small text GUI demo.\n"
|
|
#~ "\n"
|
|
#~ "| Click me! |\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```text\n"
|
|
#~ "========\n"
|
|
#~ "Rust GUI Demo 1.23\n"
|
|
#~ "========\n"
|
|
#~ "\n"
|
|
#~ "This is a small text GUI demo.\n"
|
|
#~ "\n"
|
|
#~ "| Click me! |\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```text\n"
|
|
#~ "+--------------------------------+\n"
|
|
#~ "| Rust GUI Demo 1.23 |\n"
|
|
#~ "+================================+\n"
|
|
#~ "| This is a small text GUI demo. |\n"
|
|
#~ "| +-----------+ |\n"
|
|
#~ "| | Click me! | |\n"
|
|
#~ "| +-----------+ |\n"
|
|
#~ "+--------------------------------+\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Error handling in Rust is done using explicit control flow:"
|
|
#~ msgstr "러스트에서 오류는 명시적인 흐름을 따라 처리가 됩니다:"
|
|
|
|
#~ msgid "Functions that can have errors list this in their return type,"
|
|
#~ msgstr "오류를 발생할 수 있는 함수는 반환 타입에 이를 명시해야 합니다,"
|
|
|
|
#~ msgid "There are no exceptions."
|
|
#~ msgstr "예외(exception) 기능은 없습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,should_panic\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v = vec![10, 20, 30];\n"
|
|
#~ " println!(\"v[100]: {}\", v[100]);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,should_panic\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v = vec![10, 20, 30];\n"
|
|
#~ " println!(\"v[100]: {}\", v[100]);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Catching the Stack Unwinding"
|
|
#~ msgstr "스택 되감기"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::panic;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let result = panic::catch_unwind(|| {\n"
|
|
#~ " println!(\"hello!\");\n"
|
|
#~ " });\n"
|
|
#~ " assert!(result.is_ok());\n"
|
|
#~ " \n"
|
|
#~ " let result = panic::catch_unwind(|| {\n"
|
|
#~ " panic!(\"oh no!\");\n"
|
|
#~ " });\n"
|
|
#~ " assert!(result.is_err());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::panic;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let result = panic::catch_unwind(|| {\n"
|
|
#~ " println!(\"hello!\");\n"
|
|
#~ " });\n"
|
|
#~ " assert!(result.is_ok());\n"
|
|
#~ " \n"
|
|
#~ " let result = panic::catch_unwind(|| {\n"
|
|
#~ " panic!(\"oh no!\");\n"
|
|
#~ " });\n"
|
|
#~ " assert!(result.is_err());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "We have already seen the `Result` enum. This is used pervasively when "
|
|
#~ "errors are expected as part of normal operation:"
|
|
#~ msgstr ""
|
|
#~ "여러분은 이미 `Result` 열거형을 몇 번 봤습니다. 이 타입은 프로그램의 정상"
|
|
#~ "적인 수행 중에 발생할 수 있는 오류값들을 나타내기 위해 사용됩니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::fs;\n"
|
|
#~ "use std::io::Read;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let file = fs::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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::fs;\n"
|
|
#~ "use std::io::Read;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let file = fs::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"
|
|
#~ "```"
|
|
|
|
#~ msgid "Propagating Errors with `?`"
|
|
#~ msgstr "`?`를 이용한 오류 전파"
|
|
|
|
#~ msgid ""
|
|
#~ "The try-operator `?` is used to return errors to the caller. It lets you "
|
|
#~ "turn the common"
|
|
#~ msgstr ""
|
|
#~ "연산자 `?`는 호출자에게 오류를 반환할 때 사용합니다. 이를 이용하면 이런 코"
|
|
#~ "드를"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "match some_expression {\n"
|
|
#~ " Ok(value) => value,\n"
|
|
#~ " Err(err) => return Err(err),\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "match some_expression {\n"
|
|
#~ " Ok(value) => value,\n"
|
|
#~ " Err(err) => return Err(err),\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "some_expression?\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "some_expression?\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::{fs, io};\n"
|
|
#~ "use std::io::Read;\n"
|
|
#~ "\n"
|
|
#~ "fn read_username(path: &str) -> Result<String, io::Error> {\n"
|
|
#~ " let username_file_result = fs::File::open(path);\n"
|
|
#~ " let mut username_file = match username_file_result {\n"
|
|
#~ " Ok(file) => file,\n"
|
|
#~ " Err(err) => return Err(err),\n"
|
|
#~ " };\n"
|
|
#~ "\n"
|
|
#~ " let mut username = String::new();\n"
|
|
#~ " match username_file.read_to_string(&mut username) {\n"
|
|
#~ " Ok(_) => Ok(username),\n"
|
|
#~ " Err(err) => Err(err),\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::{fs, io};\n"
|
|
#~ "use std::io::Read;\n"
|
|
#~ "\n"
|
|
#~ "fn read_username(path: &str) -> Result<String, io::Error> {\n"
|
|
#~ " let username_file_result = fs::File::open(path);\n"
|
|
#~ " let mut username_file = match username_file_result {\n"
|
|
#~ " Ok(file) => file,\n"
|
|
#~ " Err(err) => return Err(err),\n"
|
|
#~ " };\n"
|
|
#~ "\n"
|
|
#~ " let mut username = String::new();\n"
|
|
#~ " match username_file.read_to_string(&mut username) {\n"
|
|
#~ " Ok(_) => Ok(username),\n"
|
|
#~ " Err(err) => Err(err),\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " //fs::write(\"config.dat\", \"alice\").unwrap();\n"
|
|
#~ " let username = read_username(\"config.dat\");\n"
|
|
#~ " println!(\"username or error: {username:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "The return type of the function has to be compatible with the nested "
|
|
#~ "functions it calls. For instance, a function returning a `Result<T, Err>` "
|
|
#~ "can only apply the `?` operator on a function returning a `Result<AnyT, "
|
|
#~ "Err>`. It cannot apply the `?` operator on a function returning an "
|
|
#~ "`Option<AnyT>` or `Result<T, OtherErr>` unless `OtherErr` implements "
|
|
#~ "`From<Err>`. Reciprocally, a function returning an `Option<T>` can only "
|
|
#~ "apply the `?` operator on a function returning an `Option<AnyT>`."
|
|
#~ msgstr ""
|
|
#~ "함수의 리턴 타입은 네스팅 되어 호출되는 함수의 리턴 타입과 호환되어야 합니"
|
|
#~ "다. 예를 들어 `Result<T, Err>`를 리턴하는 함수는 `Result<AnyT, Err>`를 리"
|
|
#~ "턴하는 함수를 호출할 때에만`?`를 사용할 수 있습니다. `Option<AnyT>`나 "
|
|
#~ "`Result<T, OtherErr>` (`OtherError`가 `From<Err>`를 구현하지 않는 다고 가"
|
|
#~ "정할 때)와 같은 타입을 리턴하는 함수를 호출할 때에는 `?`를 사용할 수 없습"
|
|
#~ "니다. 동일한 이유로, `Option<T>`를 리턴하는 함수는 `Option<AnyT>`를 리턴하"
|
|
#~ "는 함수를 호출할 때에만 `?`를 사용할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "You can convert incompatible types into one another with the different "
|
|
#~ "`Option` and `Result` methods such as `Option::ok_or`, `Result::ok`, "
|
|
#~ "`Result::err`."
|
|
#~ msgstr ""
|
|
#~ "`Option`과 `Result`간의 변환을 위해 `Option::ok_or`, `Result::ok`, "
|
|
#~ "`Result::err`와 같은 함수들을 사용할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "expression?\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "expression?\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "match expression {\n"
|
|
#~ " Ok(value) => value,\n"
|
|
#~ " Err(err) => return Err(From::from(err)),\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "match expression {\n"
|
|
#~ " Ok(value) => value,\n"
|
|
#~ " Err(err) => return Err(From::from(err)),\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::error::Error;\n"
|
|
#~ "use std::fmt::{self, Display, Formatter};\n"
|
|
#~ "use std::fs::{self, File};\n"
|
|
#~ "use std::io::{self, Read};\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "enum ReadUsernameError {\n"
|
|
#~ " IoError(io::Error),\n"
|
|
#~ " EmptyUsername(String),\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Error for ReadUsernameError {}\n"
|
|
#~ "\n"
|
|
#~ "impl Display for ReadUsernameError {\n"
|
|
#~ " fn fmt(&self, f: &mut Formatter) -> fmt::Result {\n"
|
|
#~ " match self {\n"
|
|
#~ " Self::IoError(e) => write!(f, \"IO error: {e}\"),\n"
|
|
#~ " Self::EmptyUsername(filename) => write!(f, \"Found no "
|
|
#~ "username in {filename}\"),\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl From<io::Error> for ReadUsernameError {\n"
|
|
#~ " fn from(err: io::Error) -> ReadUsernameError {\n"
|
|
#~ " ReadUsernameError::IoError(err)\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn read_username(path: &str) -> Result<String, ReadUsernameError> {\n"
|
|
#~ " let mut username = String::with_capacity(100);\n"
|
|
#~ " 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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " //fs::write(\"config.dat\", \"\").unwrap();\n"
|
|
#~ " let username = read_username(\"config.dat\");\n"
|
|
#~ " println!(\"username or error: {username:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::error::Error;\n"
|
|
#~ "use std::fmt::{self, Display, Formatter};\n"
|
|
#~ "use std::fs::{self, File};\n"
|
|
#~ "use std::io::{self, Read};\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "enum ReadUsernameError {\n"
|
|
#~ " IoError(io::Error),\n"
|
|
#~ " EmptyUsername(String),\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Error for ReadUsernameError {}\n"
|
|
#~ "\n"
|
|
#~ "impl Display for ReadUsernameError {\n"
|
|
#~ " fn fmt(&self, f: &mut Formatter) -> fmt::Result {\n"
|
|
#~ " match self {\n"
|
|
#~ " Self::IoError(e) => write!(f, \"IO error: {e}\"),\n"
|
|
#~ " Self::EmptyUsername(filename) => write!(f, \"Found no "
|
|
#~ "username in {filename}\"),\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl From<io::Error> for ReadUsernameError {\n"
|
|
#~ " fn from(err: io::Error) -> ReadUsernameError {\n"
|
|
#~ " ReadUsernameError::IoError(err)\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn read_username(path: &str) -> Result<String, ReadUsernameError> {\n"
|
|
#~ " let mut username = String::with_capacity(100);\n"
|
|
#~ " 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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " //fs::write(\"config.dat\", \"\").unwrap();\n"
|
|
#~ " let username = read_username(\"config.dat\");\n"
|
|
#~ " println!(\"username or error: {username:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "It is good practice for all error types that don't need to be `no_std` to "
|
|
#~ "implement `std::error::Error`, which requires `Debug` and `Display`. The "
|
|
#~ "`Error` crate for `core` is only available in [nightly](https://github."
|
|
#~ "com/rust-lang/rust/issues/103765), so not fully `no_std` compatible yet."
|
|
#~ msgstr ""
|
|
#~ "모든 에러 타입 (`no_std`이어야 하는 에러 타입을 제외하고)에 대해 `std::"
|
|
#~ "error::Error`를 구현하는 것은 좋은 습관입니다. `std::error::Error`를 구현"
|
|
#~ "한다는 것은 `Debug`와 `Display`도 구현한다는 것입니다. `core`를 위한 "
|
|
#~ "`Error`크레이크는 [나이틀리](https://github.com/rust-lang/rust/"
|
|
#~ "issues/103765)에만 제공이 됩니다. 그래서 아직 `no_std`환경에서 사용할 수"
|
|
#~ "는 없습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "It's generally helpful for them to implement `Clone` and `Eq` too where "
|
|
#~ "possible, to make life easier for tests and consumers of your library. In "
|
|
#~ "this case we can't easily do so, because `io::Error` doesn't implement "
|
|
#~ "them."
|
|
#~ msgstr ""
|
|
#~ "가능하다면 `Clone`과 `Eq` 트레잇도 구현하도록 하세요. 여러분의 라이브러리"
|
|
#~ "가 테스트 하기 쉬워지고, 사용하기 좋아질 겁니다. 다만, 이 예제에서는 그렇"
|
|
#~ "게 하기 힘듭니다. 왜냐하면 `io::Error`는 이 트레잇들을 구현하고 있지 않기 "
|
|
#~ "때문입니다."
|
|
|
|
#~ msgid ""
|
|
#~ "The [thiserror](https://docs.rs/thiserror/) crate is a popular way to "
|
|
#~ "create an error enum like we did on the previous page:"
|
|
#~ msgstr ""
|
|
#~ "[thiserror](https://docs.rs/thiserror/)는, 이전 페이지에서 보았던 것과 같"
|
|
#~ "은 에러 열거형을 쉽게 만들 수 있게 해 주는 유명한 크레이트 입니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use std::{fs, io};\n"
|
|
#~ "use std::io::Read;\n"
|
|
#~ "use thiserror::Error;\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug, Error)]\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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn read_username(path: &str) -> Result<String, ReadUsernameError> {\n"
|
|
#~ " let mut username = String::new();\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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use std::{fs, io};\n"
|
|
#~ "use std::io::Read;\n"
|
|
#~ "use thiserror::Error;\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug, Error)]\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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn read_username(path: &str) -> Result<String, ReadUsernameError> {\n"
|
|
#~ " let mut username = String::new();\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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "`thiserror`'s derive macro automatically implements `std::error::Error`, "
|
|
#~ "and optionally `Display` (if the `#[error(...)]` attributes are provided) "
|
|
#~ "and `From` (if the `#[from]` attribute is added). It also works for "
|
|
#~ "structs."
|
|
#~ msgstr ""
|
|
#~ "`thiserror`의 derive 매크로를 이용하면 `std::error::Error`과 `Display`(만"
|
|
#~ "약 `#[error(...)]` 어트리뷰트를 추가했을 경우), `From`(만약 `#[from]` 어트"
|
|
#~ "리뷰트를 추가했을 경우) 트레잇들이 자동으로 구현이 됩니다. 구조체에 대해서"
|
|
#~ "도 사용 가능합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "It doesn't affect your public API, which makes it good for libraries."
|
|
#~ msgstr ""
|
|
#~ "이 매크로를 사용해도 밖으로 노출되는 API가 변경되지는 않습니다. 라이브러리"
|
|
#~ "를 만들 경우에는 이게 중요하죠."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use std::fs;\n"
|
|
#~ "use std::io::Read;\n"
|
|
#~ "use thiserror::Error;\n"
|
|
#~ "use std::error::Error;\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Clone, Debug, Eq, Error, PartialEq)]\n"
|
|
#~ "#[error(\"Found no username in {0}\")]\n"
|
|
#~ "struct EmptyUsernameError(String);\n"
|
|
#~ "\n"
|
|
#~ "fn read_username(path: &str) -> Result<String, Box<dyn Error>> {\n"
|
|
#~ " let mut username = String::new();\n"
|
|
#~ " fs::File::open(path)?.read_to_string(&mut username)?;\n"
|
|
#~ " if username.is_empty() {\n"
|
|
#~ " return Err(EmptyUsernameError(String::from(path)).into());\n"
|
|
#~ " }\n"
|
|
#~ " Ok(username)\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use std::fs;\n"
|
|
#~ "use std::io::Read;\n"
|
|
#~ "use thiserror::Error;\n"
|
|
#~ "use std::error::Error;\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Clone, Debug, Eq, Error, PartialEq)]\n"
|
|
#~ "#[error(\"Found no username in {0}\")]\n"
|
|
#~ "struct EmptyUsernameError(String);\n"
|
|
#~ "\n"
|
|
#~ "fn read_username(path: &str) -> Result<String, Box<dyn Error>> {\n"
|
|
#~ " let mut username = String::new();\n"
|
|
#~ " fs::File::open(path)?.read_to_string(&mut username)?;\n"
|
|
#~ " if username.is_empty() {\n"
|
|
#~ " return Err(EmptyUsernameError(String::from(path)).into());\n"
|
|
#~ " }\n"
|
|
#~ " Ok(username)\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "The widely used [anyhow](https://docs.rs/anyhow/) crate can help you add "
|
|
#~ "contextual information to your errors and allows you to have fewer custom "
|
|
#~ "error types:"
|
|
#~ msgstr ""
|
|
#~ "[anyhow](https://docs.rs/anyhow/) 크레이트는 에러에 에러가 발생한 문맥에 "
|
|
#~ "대한 정보를 추가하기 위해 널리 사용되며, 이를 이용하면 서로 다른 문맥을 나"
|
|
#~ "타내기 사용자 정의 오류 타입을 많이 만들어야 하는 불편함을 피할 수 있습니"
|
|
#~ "다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use std::{fs, io};\n"
|
|
#~ "use std::io::Read;\n"
|
|
#~ "use anyhow::{Context, Result, bail};\n"
|
|
#~ "\n"
|
|
#~ "fn read_username(path: &str) -> Result<String> {\n"
|
|
#~ " let mut username = String::with_capacity(100);\n"
|
|
#~ " fs::File::open(path)\n"
|
|
#~ " .with_context(|| format!(\"Failed to open {path}\"))?\n"
|
|
#~ " .read_to_string(&mut username)\n"
|
|
#~ " .context(\"Failed to read\")?;\n"
|
|
#~ " if username.is_empty() {\n"
|
|
#~ " bail!(\"Found no username in {path}\");\n"
|
|
#~ " }\n"
|
|
#~ " Ok(username)\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use std::{fs, io};\n"
|
|
#~ "use std::io::Read;\n"
|
|
#~ "use anyhow::{Context, Result, bail};\n"
|
|
#~ "\n"
|
|
#~ "fn read_username(path: &str) -> Result<String> {\n"
|
|
#~ " let mut username = String::with_capacity(100);\n"
|
|
#~ " fs::File::open(path)\n"
|
|
#~ " .with_context(|| format!(\"Failed to open {path}\"))?\n"
|
|
#~ " .read_to_string(&mut username)\n"
|
|
#~ " .context(\"Failed to read\")?;\n"
|
|
#~ " if username.is_empty() {\n"
|
|
#~ " bail!(\"Found no username in {path}\");\n"
|
|
#~ " }\n"
|
|
#~ " Ok(username)\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ msgid "Mark unit tests with `#[test]`:"
|
|
#~ msgstr "단위 테스트는 `#[test]` 로 표시합니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,ignore\n"
|
|
#~ "fn first_word(text: &str) -> &str {\n"
|
|
#~ " match text.find(' ') {\n"
|
|
#~ " Some(idx) => &text[..idx],\n"
|
|
#~ " None => &text,\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_empty() {\n"
|
|
#~ " assert_eq!(first_word(\"\"), \"\");\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_single_word() {\n"
|
|
#~ " assert_eq!(first_word(\"Hello\"), \"Hello\");\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_multiple_words() {\n"
|
|
#~ " assert_eq!(first_word(\"Hello World\"), \"Hello\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,ignore\n"
|
|
#~ "fn first_word(text: &str) -> &str {\n"
|
|
#~ " match text.find(' ') {\n"
|
|
#~ " Some(idx) => &text[..idx],\n"
|
|
#~ " None => &text,\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_empty() {\n"
|
|
#~ " assert_eq!(first_word(\"\"), \"\");\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_single_word() {\n"
|
|
#~ " assert_eq!(first_word(\"Hello\"), \"Hello\");\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_multiple_words() {\n"
|
|
#~ " assert_eq!(first_word(\"Hello World\"), \"Hello\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Use `cargo test` to find and run the unit tests."
|
|
#~ msgstr "`cargo test` 커맨드를 사용하면 단위 테스트를 찾아서 실행합니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Unit tests are often put in a nested module (run tests on the [Playground]"
|
|
#~ "(https://play.rust-lang.org/)):"
|
|
#~ msgstr ""
|
|
#~ "단위 테스트는 원래 모듈 밑에 서브 모듈로 만드는 경우가 많습니다. ([플레이"
|
|
#~ "그라운드](https://play.rust-lang.org/)에서 다음 테스트를 수행해 보세요):"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn helper(a: &str, b: &str) -> String {\n"
|
|
#~ " format!(\"{a} {b}\")\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub fn main() {\n"
|
|
#~ " println!(\"{}\", helper(\"Hello\", \"World\"));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[cfg(test)]\n"
|
|
#~ "mod tests {\n"
|
|
#~ " use super::*;\n"
|
|
#~ "\n"
|
|
#~ " #[test]\n"
|
|
#~ " fn test_helper() {\n"
|
|
#~ " assert_eq!(helper(\"foo\", \"bar\"), \"foo bar\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn helper(a: &str, b: &str) -> String {\n"
|
|
#~ " format!(\"{a} {b}\")\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub fn main() {\n"
|
|
#~ " println!(\"{}\", helper(\"Hello\", \"World\"));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[cfg(test)]\n"
|
|
#~ "mod tests {\n"
|
|
#~ " use super::*;\n"
|
|
#~ "\n"
|
|
#~ " #[test]\n"
|
|
#~ " fn test_helper() {\n"
|
|
#~ " assert_eq!(helper(\"foo\", \"bar\"), \"foo bar\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "use my_library::init;\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_init() {\n"
|
|
#~ " assert!(init().is_ok());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "use my_library::init;\n"
|
|
#~ "\n"
|
|
#~ "#[test]\n"
|
|
#~ "fn test_init() {\n"
|
|
#~ " assert!(init().is_ok());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Useful crates for writing tests"
|
|
#~ msgstr "테스트 작성에 유용한 크레이트"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "static HELLO_WORLD: &str = \"Hello, world!\";\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"HELLO_WORLD: {HELLO_WORLD}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "static HELLO_WORLD: &str = \"Hello, world!\";\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"HELLO_WORLD: {HELLO_WORLD}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "static mut COUNTER: u32 = 0;\n"
|
|
#~ "\n"
|
|
#~ "fn add_to_counter(inc: u32) {\n"
|
|
#~ " unsafe { COUNTER += inc; } // Potential data race!\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " add_to_counter(42);\n"
|
|
#~ "\n"
|
|
#~ " unsafe { println!(\"COUNTER: {COUNTER}\"); } // Potential data "
|
|
#~ "race!\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "static mut COUNTER: u32 = 0;\n"
|
|
#~ "\n"
|
|
#~ "fn add_to_counter(inc: u32) {\n"
|
|
#~ " unsafe { COUNTER += inc; } // 잠재적 데이터 경합!\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " add_to_counter(42);\n"
|
|
#~ "\n"
|
|
#~ " unsafe { println!(\"COUNTER: {COUNTER}\"); } // 잠재적 데이터 경합!\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[repr(C)]\n"
|
|
#~ "union MyUnion {\n"
|
|
#~ " i: u8,\n"
|
|
#~ " b: bool,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "#[repr(C)]\n"
|
|
#~ "union MyUnion {\n"
|
|
#~ " i: u8,\n"
|
|
#~ " b: bool,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let u = MyUnion { i: 42 };\n"
|
|
#~ " println!(\"int: {}\", unsafe { u.i });\n"
|
|
#~ " println!(\"bool: {}\", unsafe { u.b }); // Undefined behavior!\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let emojis = \"🗻∈🌏\";\n"
|
|
#~ "\n"
|
|
#~ " // Safe because the indices are in the correct order, within the "
|
|
#~ "bounds of\n"
|
|
#~ " // the string slice, and lie on UTF-8 sequence boundaries.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " println!(\"emoji: {}\", emojis.get_unchecked(0..4));\n"
|
|
#~ " println!(\"emoji: {}\", emojis.get_unchecked(4..7));\n"
|
|
#~ " println!(\"emoji: {}\", emojis.get_unchecked(7..11));\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"char count: {}\", count_chars(unsafe { emojis."
|
|
#~ "get_unchecked(0..7) }));\n"
|
|
#~ "\n"
|
|
#~ " // Not upholding the UTF-8 encoding requirement breaks memory "
|
|
#~ "safety!\n"
|
|
#~ " // println!(\"emoji: {}\", unsafe { emojis.get_unchecked(0..3) });\n"
|
|
#~ " // println!(\"char count: {}\", count_chars(unsafe { emojis."
|
|
#~ "get_unchecked(0..3) }));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn count_chars(s: &str) -> usize {\n"
|
|
#~ " s.chars().map(|_| 1).sum()\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let emojis = \"🗻∈🌏\";\n"
|
|
#~ "\n"
|
|
#~ " // Safe because the indices are in the correct order, within the "
|
|
#~ "bounds of\n"
|
|
#~ " // the string slice, and lie on UTF-8 sequence boundaries.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " println!(\"emoji: {}\", emojis.get_unchecked(0..4));\n"
|
|
#~ " println!(\"emoji: {}\", emojis.get_unchecked(4..7));\n"
|
|
#~ " println!(\"emoji: {}\", emojis.get_unchecked(7..11));\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"char count: {}\", count_chars(unsafe { emojis."
|
|
#~ "get_unchecked(0..7) }));\n"
|
|
#~ "\n"
|
|
#~ " // Not upholding the UTF-8 encoding requirement breaks memory "
|
|
#~ "safety!\n"
|
|
#~ " // println!(\"emoji: {}\", unsafe { emojis.get_unchecked(0..3) });\n"
|
|
#~ " // println!(\"char count: {}\", count_chars(unsafe { emojis."
|
|
#~ "get_unchecked(0..3) }));\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn count_chars(s: &str) -> usize {\n"
|
|
#~ " s.chars().map(|_| 1).sum()\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "/// Swaps the values pointed to by the given pointers.\n"
|
|
#~ "///\n"
|
|
#~ "/// # Safety\n"
|
|
#~ "///\n"
|
|
#~ "/// The pointers must be valid and properly aligned.\n"
|
|
#~ "unsafe fn swap(a: *mut u8, b: *mut u8) {\n"
|
|
#~ " let temp = *a;\n"
|
|
#~ " *a = *b;\n"
|
|
#~ " *b = temp;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut a = 42;\n"
|
|
#~ " let mut b = 66;\n"
|
|
#~ "\n"
|
|
#~ " // Safe because ...\n"
|
|
#~ " unsafe {\n"
|
|
#~ " swap(&mut a, &mut b);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"a = {}, b = {}\", a, b);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "/// Swaps the values pointed to by the given pointers.\n"
|
|
#~ "///\n"
|
|
#~ "/// # Safety\n"
|
|
#~ "///\n"
|
|
#~ "/// The pointers must be valid and properly aligned.\n"
|
|
#~ "unsafe fn swap(a: *mut u8, b: *mut u8) {\n"
|
|
#~ " let temp = *a;\n"
|
|
#~ " *a = *b;\n"
|
|
#~ " *b = temp;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut a = 42;\n"
|
|
#~ " let mut b = 66;\n"
|
|
#~ "\n"
|
|
#~ " // Safe because ...\n"
|
|
#~ " unsafe {\n"
|
|
#~ " swap(&mut a, &mut b);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"a = {}, b = {}\", a, b);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Calling External Code"
|
|
#~ msgstr "외부 코드 호출"
|
|
|
|
#~ msgid ""
|
|
#~ "Functions from other languages might violate the guarantees of Rust. "
|
|
#~ "Calling them is thus unsafe:"
|
|
#~ msgstr ""
|
|
#~ "다른 언어의 함수는 러스트의 보증을 위반할 수 있습니다. 따라서 이를 호출하"
|
|
#~ "는 것은 안전하지 않습니다:"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "extern \"C\" {\n"
|
|
#~ " fn abs(input: i32) -> i32;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,editable\n"
|
|
#~ "extern \"C\" {\n"
|
|
#~ " fn abs(input: i32) -> i32;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " unsafe {\n"
|
|
#~ " // Undefined behavior if abs misbehaves.\n"
|
|
#~ " println!(\"Absolute value of -3 according to C: {}\", abs(-3));\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::mem::size_of_val;\n"
|
|
#~ "use std::slice;\n"
|
|
#~ "\n"
|
|
#~ "/// ...\n"
|
|
#~ "/// # Safety\n"
|
|
#~ "/// The type must have a defined representation and no padding.\n"
|
|
#~ "pub unsafe trait AsBytes {\n"
|
|
#~ " fn as_bytes(&self) -> &[u8] {\n"
|
|
#~ " unsafe {\n"
|
|
#~ " slice::from_raw_parts(self as *const Self as *const u8, "
|
|
#~ "size_of_val(self))\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// Safe because u32 has a defined representation and no padding.\n"
|
|
#~ "unsafe impl AsBytes for u32 {}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::mem::size_of_val;\n"
|
|
#~ "use std::slice;\n"
|
|
#~ "\n"
|
|
#~ "/// ...\n"
|
|
#~ "/// # Safety\n"
|
|
#~ "/// The type must have a defined representation and no padding.\n"
|
|
#~ "pub unsafe trait AsBytes {\n"
|
|
#~ " fn as_bytes(&self) -> &[u8] {\n"
|
|
#~ " unsafe {\n"
|
|
#~ " slice::from_raw_parts(self as *const Self as *const u8, "
|
|
#~ "size_of_val(self))\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// Safe because u32 has a defined representation and no padding.\n"
|
|
#~ "unsafe impl AsBytes for u32 {}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "Day 3: Afternoon Exercises"
|
|
#~ msgstr "3일차 오후 연습문제"
|
|
|
|
#~ msgid "Let us build a safe wrapper for reading directory content!"
|
|
#~ msgstr "디렉터리의 내용을 읽는 안전한 래퍼 코드를 작성해 봅시다!"
|
|
|
|
#~ msgid ""
|
|
#~ "For this exercise, we suggest using a local dev environment instead of "
|
|
#~ "the Playground. This will allow you to run your binary on your own "
|
|
#~ "machine."
|
|
#~ msgstr ""
|
|
#~ "이번 연습에서는, 플레이그라운드 대신 로컬 개발 환경을 사용해서, 여러분의 "
|
|
#~ "컴퓨터에서 바이너리를 직접 수행해 보세요."
|
|
|
|
#~ msgid ""
|
|
#~ "To get started, follow the [running locally](../../cargo/running-locally."
|
|
#~ "md) instructions."
|
|
#~ msgstr ""
|
|
#~ "시작하기 위해, [로컬 환경에서 수행하기](../../cargo/running-locally.md)를 "
|
|
#~ "따르세요."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,should_panic\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_imports, unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "mod ffi {\n"
|
|
#~ " use std::os::raw::{c_char, c_int};\n"
|
|
#~ " #[cfg(not(target_os = \"macos\"))]\n"
|
|
#~ " use std::os::raw::{c_long, c_ulong, c_ushort, c_uchar};\n"
|
|
#~ "\n"
|
|
#~ " // 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"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // Layout according to the Linux man page for readdir(3), where ino_t "
|
|
#~ "and\n"
|
|
#~ " // off_t are resolved according to the definitions in\n"
|
|
#~ " // /usr/include/x86_64-linux-gnu/{sys/types.h, bits/typesizes.h}.\n"
|
|
#~ " #[cfg(not(target_os = \"macos\"))]\n"
|
|
#~ " #[repr(C)]\n"
|
|
#~ " pub struct dirent {\n"
|
|
#~ " pub d_ino: c_ulong,\n"
|
|
#~ " pub d_off: c_long,\n"
|
|
#~ " pub d_reclen: c_ushort,\n"
|
|
#~ " pub d_type: c_uchar,\n"
|
|
#~ " pub d_name: [c_char; 256],\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // Layout according to the macOS man page for dir(5).\n"
|
|
#~ " #[cfg(all(target_os = \"macos\"))]\n"
|
|
#~ " #[repr(C)]\n"
|
|
#~ " pub struct dirent {\n"
|
|
#~ " pub d_fileno: u64,\n"
|
|
#~ " pub d_seekoff: u64,\n"
|
|
#~ " pub d_reclen: u16,\n"
|
|
#~ " pub d_namlen: u16,\n"
|
|
#~ " pub d_type: u8,\n"
|
|
#~ " pub d_name: [c_char; 1024],\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " extern \"C\" {\n"
|
|
#~ " pub fn opendir(s: *const c_char) -> *mut DIR;\n"
|
|
#~ "\n"
|
|
#~ " #[cfg(not(all(target_os = \"macos\", target_arch = "
|
|
#~ "\"x86_64\")))]\n"
|
|
#~ " pub fn readdir(s: *mut DIR) -> *const dirent;\n"
|
|
#~ "\n"
|
|
#~ " // See https://github.com/rust-lang/libc/issues/414 and the "
|
|
#~ "section on\n"
|
|
#~ " // _DARWIN_FEATURE_64_BIT_INODE in the macOS man page for "
|
|
#~ "stat(2).\n"
|
|
#~ " //\n"
|
|
#~ " // \"Platforms that existed before these updates were available\" "
|
|
#~ "refers\n"
|
|
#~ " // to macOS (as opposed to iOS / wearOS / etc.) on Intel and "
|
|
#~ "PowerPC.\n"
|
|
#~ " #[cfg(all(target_os = \"macos\", target_arch = \"x86_64\"))]\n"
|
|
#~ " #[link_name = \"readdir$INODE64\"]\n"
|
|
#~ " pub fn readdir(s: *mut DIR) -> *const dirent;\n"
|
|
#~ "\n"
|
|
#~ " pub fn closedir(s: *mut DIR) -> c_int;\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "use std::ffi::{CStr, CString, OsStr, OsString};\n"
|
|
#~ "use std::os::unix::ffi::OsStrExt;\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct DirectoryIterator {\n"
|
|
#~ " path: CString,\n"
|
|
#~ " dir: *mut ffi::DIR,\n"
|
|
#~ "}\n"
|
|
#~ "\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"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\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"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Drop for DirectoryIterator {\n"
|
|
#~ " fn drop(&mut self) {\n"
|
|
#~ " // Call closedir as needed.\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() -> Result<(), String> {\n"
|
|
#~ " let iter = DirectoryIterator::new(\".\")?;\n"
|
|
#~ " println!(\"files: {:#?}\", iter.collect::<Vec<_>>());\n"
|
|
#~ " Ok(())\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,should_panic\n"
|
|
#~ "// TODO: remove this when you're done with your implementation.\n"
|
|
#~ "#![allow(unused_imports, unused_variables, dead_code)]\n"
|
|
#~ "\n"
|
|
#~ "mod ffi {\n"
|
|
#~ " use std::os::raw::{c_char, c_int};\n"
|
|
#~ " #[cfg(not(target_os = \"macos\"))]\n"
|
|
#~ " use std::os::raw::{c_long, c_ulong, c_ushort, c_uchar};\n"
|
|
#~ "\n"
|
|
#~ " // 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"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // Layout according to the Linux man page for readdir(3), where ino_t "
|
|
#~ "and\n"
|
|
#~ " // off_t are resolved according to the definitions in\n"
|
|
#~ " // /usr/include/x86_64-linux-gnu/{sys/types.h, bits/typesizes.h}.\n"
|
|
#~ " #[cfg(not(target_os = \"macos\"))]\n"
|
|
#~ " #[repr(C)]\n"
|
|
#~ " pub struct dirent {\n"
|
|
#~ " pub d_ino: c_ulong,\n"
|
|
#~ " pub d_off: c_long,\n"
|
|
#~ " pub d_reclen: c_ushort,\n"
|
|
#~ " pub d_type: c_uchar,\n"
|
|
#~ " pub d_name: [c_char; 256],\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // Layout according to the macOS man page for dir(5).\n"
|
|
#~ " #[cfg(all(target_os = \"macos\"))]\n"
|
|
#~ " #[repr(C)]\n"
|
|
#~ " pub struct dirent {\n"
|
|
#~ " pub d_fileno: u64,\n"
|
|
#~ " pub d_seekoff: u64,\n"
|
|
#~ " pub d_reclen: u16,\n"
|
|
#~ " pub d_namlen: u16,\n"
|
|
#~ " pub d_type: u8,\n"
|
|
#~ " pub d_name: [c_char; 1024],\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " extern \"C\" {\n"
|
|
#~ " pub fn opendir(s: *const c_char) -> *mut DIR;\n"
|
|
#~ "\n"
|
|
#~ " #[cfg(not(all(target_os = \"macos\", target_arch = "
|
|
#~ "\"x86_64\")))]\n"
|
|
#~ " pub fn readdir(s: *mut DIR) -> *const dirent;\n"
|
|
#~ "\n"
|
|
#~ " // See https://github.com/rust-lang/libc/issues/414 and the "
|
|
#~ "section on\n"
|
|
#~ " // _DARWIN_FEATURE_64_BIT_INODE in the macOS man page for "
|
|
#~ "stat(2).\n"
|
|
#~ " //\n"
|
|
#~ " // \"Platforms that existed before these updates were available\" "
|
|
#~ "refers\n"
|
|
#~ " // to macOS (as opposed to iOS / wearOS / etc.) on Intel and "
|
|
#~ "PowerPC.\n"
|
|
#~ " #[cfg(all(target_os = \"macos\", target_arch = \"x86_64\"))]\n"
|
|
#~ " #[link_name = \"readdir$INODE64\"]\n"
|
|
#~ " pub fn readdir(s: *mut DIR) -> *const dirent;\n"
|
|
#~ "\n"
|
|
#~ " pub fn closedir(s: *mut DIR) -> c_int;\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "use std::ffi::{CStr, CString, OsStr, OsString};\n"
|
|
#~ "use std::os::unix::ffi::OsStrExt;\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct DirectoryIterator {\n"
|
|
#~ " path: CString,\n"
|
|
#~ " dir: *mut ffi::DIR,\n"
|
|
#~ "}\n"
|
|
#~ "\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"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\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"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Drop for DirectoryIterator {\n"
|
|
#~ " fn drop(&mut self) {\n"
|
|
#~ " // Call closedir as needed.\n"
|
|
#~ " unimplemented!()\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() -> Result<(), String> {\n"
|
|
#~ " let iter = DirectoryIterator::new(\".\")?;\n"
|
|
#~ " println!(\"files: {:#?}\", iter.collect::<Vec<_>>());\n"
|
|
#~ " Ok(())\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "source build/envsetup.sh\n"
|
|
#~ "lunch aosp_cf_x86_64_phone-userdebug\n"
|
|
#~ "acloud create\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```shell\n"
|
|
#~ "$ source build/envsetup.sh\n"
|
|
#~ "$ lunch aosp_cf_x86_64_phone-userdebug\n"
|
|
#~ "$ acloud create\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```javascript\n"
|
|
#~ "rust_binary {\n"
|
|
#~ " name: \"hello_rust\",\n"
|
|
#~ " crate_name: \"hello_rust\",\n"
|
|
#~ " srcs: [\"src/main.rs\"],\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```javascript\n"
|
|
#~ "rust_binary {\n"
|
|
#~ " name: \"hello_rust\",\n"
|
|
#~ " crate_name: \"hello_rust\",\n"
|
|
#~ " srcs: [\"src/main.rs\"],\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust\n"
|
|
#~ "//! Rust demo.\n"
|
|
#~ "\n"
|
|
#~ "/// Prints a greeting to standard output.\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"Hello from Rust!\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust\n"
|
|
#~ "//! Rust 데모입니다.\n"
|
|
#~ "\n"
|
|
#~ "/// 인사말을 표준 출력으로 인쇄합니다.\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"Hello from Rust!\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ 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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "rust_library {\n"
|
|
#~ " name: \"libgreetings\",\n"
|
|
#~ " crate_name: \"greetings\",\n"
|
|
#~ " srcs: [\"src/lib.rs\"],\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```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"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "rust_library {\n"
|
|
#~ " name: \"libgreetings\",\n"
|
|
#~ " crate_name: \"greetings\",\n"
|
|
#~ " srcs: [\"src/lib.rs\"],\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "//! Rust demo.\n"
|
|
#~ "\n"
|
|
#~ "use greetings::greeting;\n"
|
|
#~ "use textwrap::fill;\n"
|
|
#~ "\n"
|
|
#~ "/// Prints a greeting to standard output.\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"{}\", fill(&greeting(\"Bob\"), 24));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "//! Rust 데모입니다.\n"
|
|
#~ "\n"
|
|
#~ "use greetings::greeting;\n"
|
|
#~ "use textwrap::fill;\n"
|
|
#~ "\n"
|
|
#~ "/// 인사말을 표준 출력으로 인쇄합니다.\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"{}\", fill(&greeting(\"Bob\"), 24));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "//! Greeting library.\n"
|
|
#~ "\n"
|
|
#~ "/// Greet `name`.\n"
|
|
#~ "pub fn greeting(name: &str) -> String {\n"
|
|
#~ " format!(\"Hello {name}, it is very nice to meet you!\")\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "//! 인사말 라이브러리입니다.\n"
|
|
#~ "\n"
|
|
#~ "/// `이름`에게 인사합니다.\n"
|
|
#~ "pub fn greeting(name: &str) -> String {\n"
|
|
#~ " format!(\"Hello {name}, it is very nice to meet you!\")\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```java\n"
|
|
#~ "package com.example.birthdayservice;\n"
|
|
#~ "\n"
|
|
#~ "/** Birthday service interface. */\n"
|
|
#~ "interface IBirthdayService {\n"
|
|
#~ " /** Generate a Happy Birthday message. */\n"
|
|
#~ " String wishHappyBirthday(String name, int years);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```java\n"
|
|
#~ "package com.example.birthdayservice;\n"
|
|
#~ "\n"
|
|
#~ "/** 생일 서비스 인터페이스입니다. */\n"
|
|
#~ "interface IBirthdayService {\n"
|
|
#~ " /** Generate a Happy Birthday message. */\n"
|
|
#~ " String wishHappyBirthday(String name, int years);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ 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;\n"
|
|
#~ "\n"
|
|
#~ "/// The `IBirthdayService` implementation.\n"
|
|
#~ "pub struct BirthdayService;\n"
|
|
#~ "\n"
|
|
#~ "impl binder::Interface for BirthdayService {}\n"
|
|
#~ "\n"
|
|
#~ "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 ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "//! `IBirthdayService` AIDL 인터페이스의 구현입니다.\n"
|
|
#~ "use com_example_birthdayservice::aidl::com::example::birthdayservice::"
|
|
#~ "IBirthdayService::IBirthdayService;\n"
|
|
#~ "use com_example_birthdayservice::binder;\n"
|
|
#~ "\n"
|
|
#~ "/// `IBirthdayService` 구현입니다.\n"
|
|
#~ "pub struct BirthdayService;\n"
|
|
#~ "\n"
|
|
#~ "impl binder::Interface for BirthdayService {}\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ 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;\n"
|
|
#~ "\n"
|
|
#~ "const SERVICE_IDENTIFIER: &str = \"birthdayservice\";\n"
|
|
#~ "\n"
|
|
#~ "/// 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 ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "//! 생일 서비스입니다.\n"
|
|
#~ "use birthdayservice::BirthdayService;\n"
|
|
#~ "use com_example_birthdayservice::aidl::com::example::birthdayservice::"
|
|
#~ "IBirthdayService::BnBirthdayService;\n"
|
|
#~ "use com_example_birthdayservice::binder;\n"
|
|
#~ "\n"
|
|
#~ "const SERVICE_IDENTIFIER: &str = \"birthdayservice\";\n"
|
|
#~ "\n"
|
|
#~ "/// 생일 서비스의 진입점입니다.\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"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "adb shell service check birthdayservice\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```shell\n"
|
|
#~ "$ adb shell service check birthdayservice\n"
|
|
#~ "Service birthdayservice: found\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```text\n"
|
|
#~ "Service birthdayservice: found\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```shell\n"
|
|
#~ "$ adb shell service check birthdayservice\n"
|
|
#~ "Service birthdayservice: found\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "adb shell service call birthdayservice 1 s16 Bob i32 24\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```shell\n"
|
|
#~ "$ adb shell service check birthdayservice\n"
|
|
#~ "Service birthdayservice: found\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```text\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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "//! Birthday service.\n"
|
|
#~ "use com_example_birthdayservice::aidl::com::example::birthdayservice::"
|
|
#~ "IBirthdayService::IBirthdayService;\n"
|
|
#~ "use com_example_birthdayservice::binder;\n"
|
|
#~ "\n"
|
|
#~ "const SERVICE_IDENTIFIER: &str = \"birthdayservice\";\n"
|
|
#~ "\n"
|
|
#~ "/// Connect to the BirthdayService.\n"
|
|
#~ "pub fn connect() -> Result<binder::Strong<dyn IBirthdayService>, binder::"
|
|
#~ "StatusCode> {\n"
|
|
#~ " binder::get_interface(SERVICE_IDENTIFIER)\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "/// 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);\n"
|
|
#~ "\n"
|
|
#~ " 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 ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "//! 생일 서비스입니다.\n"
|
|
#~ "use com_example_birthdayservice::aidl::com::example::birthdayservice::"
|
|
#~ "IBirthdayService::IBirthdayService;\n"
|
|
#~ "use com_example_birthdayservice::binder;\n"
|
|
#~ "\n"
|
|
#~ "const SERVICE_IDENTIFIER: &str = \"birthdayservice\";\n"
|
|
#~ "\n"
|
|
#~ "/// BirthdayService에 연결합니다.\n"
|
|
#~ "pub fn connect() -> Result<binder::Strong<dyn IBirthdayService>, binder::"
|
|
#~ "StatusCode> {\n"
|
|
#~ " binder::get_interface(SERVICE_IDENTIFIER)\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "/// 생일 서비스를 호출합니다.\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);\n"
|
|
#~ "\n"
|
|
#~ " 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"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```java\n"
|
|
#~ "package com.example.birthdayservice;\n"
|
|
#~ "\n"
|
|
#~ "/** 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 ""
|
|
#~ "```java\n"
|
|
#~ "package com.example.birthdayservice;\n"
|
|
#~ "\n"
|
|
#~ "/** 생일 서비스 인터페이스입니다. */\n"
|
|
#~ "interface IBirthdayService {\n"
|
|
#~ " /** Generate a Happy Birthday message. */\n"
|
|
#~ " String wishHappyBirthday(String name, int years, in String[] text);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "//! Rust logging demo.\n"
|
|
#~ "\n"
|
|
#~ "use log::{debug, error, info};\n"
|
|
#~ "\n"
|
|
#~ "/// 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 ""
|
|
#~ "```rust,ignore\n"
|
|
#~ "//! Rust 로깅 데모입니다.\n"
|
|
#~ "\n"
|
|
#~ "use log::{debug, error, info};\n"
|
|
#~ "\n"
|
|
#~ "/// 인사말을 기록합니다.\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"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "adb logcat -s rust\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```shell\n"
|
|
#~ "$ sudo apt install cargo rust-src rustfmt\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```text\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 ""
|
|
#~ "```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"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust\n"
|
|
#~ "extern \"C\" {\n"
|
|
#~ " fn abs(x: i32) -> i32;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let x = -42;\n"
|
|
#~ " let abs_x = unsafe { abs(x) };\n"
|
|
#~ " println!(\"{x}, {abs_x}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust\n"
|
|
#~ "extern \"C\" {\n"
|
|
#~ " fn abs(x: i32) -> i32;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let x = -42;\n"
|
|
#~ " let abs_x = unsafe { abs(x) };\n"
|
|
#~ " println!(\"{x}, {abs_x}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,compile_fail\n"
|
|
#~ "//! Rust <-> Java FFI demo.\n"
|
|
#~ "\n"
|
|
#~ "use jni::objects::{JClass, JString};\n"
|
|
#~ "use jni::sys::jstring;\n"
|
|
#~ "use jni::JNIEnv;\n"
|
|
#~ "\n"
|
|
#~ "/// 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 ""
|
|
#~ "```rust,compile_fail\n"
|
|
#~ "//! Rust <-> Java FFI 데모입니다.\n"
|
|
#~ "\n"
|
|
#~ "use jni::objects::{JClass, JString};\n"
|
|
#~ "use jni::sys::jstring;\n"
|
|
#~ "use jni::JNIEnv;\n"
|
|
#~ "\n"
|
|
#~ "/// HelloWorld::hello 메서드 구현입니다.\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"
|
|
#~ "```"
|
|
|
|
#~ 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 ""
|
|
#~ "```javascript\n"
|
|
#~ "rust_ffi_shared {\n"
|
|
#~ " name: \"libhello_jni\",\n"
|
|
#~ " crate_name: \"hello_jni\",\n"
|
|
#~ " srcs: [\"src/lib.rs\"],\n"
|
|
#~ " rustlibs: [\"libjni\"],\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```java\n"
|
|
#~ "class HelloWorld {\n"
|
|
#~ " private static native String hello(String name);\n"
|
|
#~ "\n"
|
|
#~ " static {\n"
|
|
#~ " System.loadLibrary(\"hello_jni\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " public static void main(String[] args) {\n"
|
|
#~ " String output = HelloWorld.hello(\"Alice\");\n"
|
|
#~ " System.out.println(output);\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```java\n"
|
|
#~ "class HelloWorld {\n"
|
|
#~ " private static native String hello(String name);\n"
|
|
#~ "\n"
|
|
#~ " static {\n"
|
|
#~ " System.loadLibrary(\"hello_jni\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " public static void main(String[] args) {\n"
|
|
#~ " String output = HelloWorld.hello(\"Alice\");\n"
|
|
#~ " System.out.println(output);\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```javascript\n"
|
|
#~ "java_binary {\n"
|
|
#~ " name: \"helloworld_jni\",\n"
|
|
#~ " srcs: [\"HelloWorld.java\"],\n"
|
|
#~ " main_class: \"HelloWorld\",\n"
|
|
#~ " required: [\"libhello_jni\"],\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```javascript\n"
|
|
#~ "java_binary {\n"
|
|
#~ " name: \"helloworld_jni\",\n"
|
|
#~ " srcs: [\"HelloWorld.java\"],\n"
|
|
#~ " main_class: \"HelloWorld\",\n"
|
|
#~ " required: [\"libhello_jni\"],\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "m helloworld_jni\n"
|
|
#~ "adb sync # requires adb root && adb remount\n"
|
|
#~ "adb shell /system/bin/helloworld_jni\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```shell\n"
|
|
#~ "$ m helloworld_jni\n"
|
|
#~ "$ adb sync # requires adb root && adb remount\n"
|
|
#~ "$ adb shell /system/bin/helloworld_jni\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```bash\n"
|
|
#~ "sudo apt install gcc-aarch64-linux-gnu gdb-multiarch libudev-dev picocom "
|
|
#~ "pkg-config qemu-system-arm\n"
|
|
#~ "rustup update\n"
|
|
#~ "rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n"
|
|
#~ "rustup component add llvm-tools-preview\n"
|
|
#~ "cargo install cargo-binutils cargo-embed\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```bash\n"
|
|
#~ "sudo apt install gcc-aarch64-linux-gnu gdb-multiarch libudev-dev picocom "
|
|
#~ "pkg-config qemu-system-arm\n"
|
|
#~ "rustup update\n"
|
|
#~ "rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n"
|
|
#~ "rustup component add llvm-tools-preview\n"
|
|
#~ "cargo install cargo-binutils cargo-embed\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```bash\n"
|
|
#~ "echo 'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0d28\", MODE=\"0664\", "
|
|
#~ "GROUP=\"plugdev\"' |\\\n"
|
|
#~ " sudo tee /etc/udev/rules.d/50-microbit.rules\n"
|
|
#~ "sudo udevadm control --reload-rules\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```bash\n"
|
|
#~ "echo 'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0d28\", MODE=\"0664\", "
|
|
#~ "GROUP=\"plugdev\"' |\\\n"
|
|
#~ " sudo tee /etc/udev/rules.d/50-microbit.rules\n"
|
|
#~ "sudo udevadm control --reload-rules\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```bash\n"
|
|
#~ "xcode-select --install\n"
|
|
#~ "brew install gdb picocom qemu\n"
|
|
#~ "brew install --cask gcc-aarch64-embedded\n"
|
|
#~ "rustup update\n"
|
|
#~ "rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n"
|
|
#~ "rustup component add llvm-tools-preview\n"
|
|
#~ "cargo install cargo-binutils cargo-embed\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```bash\n"
|
|
#~ "xcode-select --install\n"
|
|
#~ "brew install gdb picocom qemu\n"
|
|
#~ "brew install --cask gcc-aarch64-embedded\n"
|
|
#~ "rustup update\n"
|
|
#~ "rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n"
|
|
#~ "rustup component add llvm-tools-preview\n"
|
|
#~ "cargo install cargo-binutils cargo-embed\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "use core::panic::PanicInfo;\n"
|
|
#~ "\n"
|
|
#~ "#[panic_handler]\n"
|
|
#~ "fn panic(_panic: &PanicInfo) -> ! {\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "use core::panic::PanicInfo;\n"
|
|
#~ "\n"
|
|
#~ "#[panic_handler]\n"
|
|
#~ "fn panic(_panic: &PanicInfo) -> ! {\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "extern crate alloc;\n"
|
|
#~ "extern crate panic_halt as _;\n"
|
|
#~ "\n"
|
|
#~ "use alloc::string::ToString;\n"
|
|
#~ "use alloc::vec::Vec;\n"
|
|
#~ "use buddy_system_allocator::LockedHeap;\n"
|
|
#~ "\n"
|
|
#~ "#[global_allocator]\n"
|
|
#~ "static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new();\n"
|
|
#~ "\n"
|
|
#~ "static mut HEAP: [u8; 65536] = [0; 65536];\n"
|
|
#~ "\n"
|
|
#~ "pub fn entry() {\n"
|
|
#~ " // Safe because `HEAP` is only used here and `entry` is only called "
|
|
#~ "once.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " // Give the allocator some memory to allocate.\n"
|
|
#~ " HEAP_ALLOCATOR\n"
|
|
#~ " .lock()\n"
|
|
#~ " .init(HEAP.as_mut_ptr() as usize, HEAP.len());\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // Now we can do things that require heap allocation.\n"
|
|
#~ " let mut v = Vec::new();\n"
|
|
#~ " v.push(\"A string\".to_string());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "extern crate alloc;\n"
|
|
#~ "extern crate panic_halt as _;\n"
|
|
#~ "\n"
|
|
#~ "use alloc::string::ToString;\n"
|
|
#~ "use alloc::vec::Vec;\n"
|
|
#~ "use buddy_system_allocator::LockedHeap;\n"
|
|
#~ "\n"
|
|
#~ "#[global_allocator]\n"
|
|
#~ "static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new();\n"
|
|
#~ "\n"
|
|
#~ "static mut HEAP: [u8; 65536] = [0; 65536];\n"
|
|
#~ "\n"
|
|
#~ "pub fn entry() {\n"
|
|
#~ " // Safe because `HEAP` is only used here and `entry` is only called "
|
|
#~ "once.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " // Give the allocator some memory to allocate.\n"
|
|
#~ " HEAP_ALLOCATOR\n"
|
|
#~ " .lock()\n"
|
|
#~ " .init(HEAP.as_mut_ptr() as usize, HEAP.len());\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // 이제 힙 할당이 필요한 작업을 실행할 수 있습니다.\n"
|
|
#~ " let mut v = Vec::new();\n"
|
|
#~ " v.push(\"A string\".to_string());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "extern crate panic_halt as _;\n"
|
|
#~ "\n"
|
|
#~ "mod interrupts;\n"
|
|
#~ "\n"
|
|
#~ "use cortex_m_rt::entry;\n"
|
|
#~ "\n"
|
|
#~ "#[entry]\n"
|
|
#~ "fn main() -> ! {\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "extern crate panic_halt as _;\n"
|
|
#~ "\n"
|
|
#~ "mod interrupts;\n"
|
|
#~ "\n"
|
|
#~ "use cortex_m_rt::entry;\n"
|
|
#~ "\n"
|
|
#~ "#[entry]\n"
|
|
#~ "fn main() -> ! {\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "extern crate panic_halt as _;\n"
|
|
#~ "\n"
|
|
#~ "mod interrupts;\n"
|
|
#~ "\n"
|
|
#~ "use core::mem::size_of;\n"
|
|
#~ "use cortex_m_rt::entry;\n"
|
|
#~ "\n"
|
|
#~ "/// GPIO port 0 peripheral address\n"
|
|
#~ "const GPIO_P0: usize = 0x5000_0000;\n"
|
|
#~ "\n"
|
|
#~ "// GPIO peripheral offsets\n"
|
|
#~ "const PIN_CNF: usize = 0x700;\n"
|
|
#~ "const OUTSET: usize = 0x508;\n"
|
|
#~ "const OUTCLR: usize = 0x50c;\n"
|
|
#~ "\n"
|
|
#~ "// PIN_CNF fields\n"
|
|
#~ "const DIR_OUTPUT: u32 = 0x1;\n"
|
|
#~ "const INPUT_DISCONNECT: u32 = 0x1 << 1;\n"
|
|
#~ "const PULL_DISABLED: u32 = 0x0 << 2;\n"
|
|
#~ "const DRIVE_S0S1: u32 = 0x0 << 8;\n"
|
|
#~ "const SENSE_DISABLED: u32 = 0x0 << 16;\n"
|
|
#~ "\n"
|
|
#~ "#[entry]\n"
|
|
#~ "fn main() -> ! {\n"
|
|
#~ " // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n"
|
|
#~ " let pin_cnf_21 = (GPIO_P0 + PIN_CNF + 21 * size_of::<u32>()) as *mut "
|
|
#~ "u32;\n"
|
|
#~ " let pin_cnf_28 = (GPIO_P0 + PIN_CNF + 28 * size_of::<u32>()) as *mut "
|
|
#~ "u32;\n"
|
|
#~ " // Safe because the pointers are to valid peripheral control "
|
|
#~ "registers, and\n"
|
|
#~ " // no aliases exist.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " pin_cnf_21.write_volatile(\n"
|
|
#~ " DIR_OUTPUT | INPUT_DISCONNECT | PULL_DISABLED | DRIVE_S0S1 | "
|
|
#~ "SENSE_DISABLED,\n"
|
|
#~ " );\n"
|
|
#~ " pin_cnf_28.write_volatile(\n"
|
|
#~ " DIR_OUTPUT | INPUT_DISCONNECT | PULL_DISABLED | DRIVE_S0S1 | "
|
|
#~ "SENSE_DISABLED,\n"
|
|
#~ " );\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // Set pin 28 low and pin 21 high to turn the LED on.\n"
|
|
#~ " let gpio0_outset = (GPIO_P0 + OUTSET) as *mut u32;\n"
|
|
#~ " let gpio0_outclr = (GPIO_P0 + OUTCLR) as *mut u32;\n"
|
|
#~ " // Safe because the pointers are to valid peripheral control "
|
|
#~ "registers, and\n"
|
|
#~ " // no aliases exist.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " gpio0_outclr.write_volatile(1 << 28);\n"
|
|
#~ " gpio0_outset.write_volatile(1 << 21);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "extern crate panic_halt as _;\n"
|
|
#~ "\n"
|
|
#~ "mod interrupts;\n"
|
|
#~ "\n"
|
|
#~ "use core::mem::size_of;\n"
|
|
#~ "use cortex_m_rt::entry;\n"
|
|
#~ "\n"
|
|
#~ "/// GPIO 포트 0 주변기기 주소입니다.\n"
|
|
#~ "const GPIO_P0: usize = 0x5000_0000;\n"
|
|
#~ "\n"
|
|
#~ "// GPIO 주변기기 오프셋입니다.\n"
|
|
#~ "const PIN_CNF: usize = 0x700;\n"
|
|
#~ "const OUTSET: usize = 0x508;\n"
|
|
#~ "const OUTCLR: usize = 0x50c;\n"
|
|
#~ "\n"
|
|
#~ "// PIN_CNF 필드입니다.\n"
|
|
#~ "const DIR_OUTPUT: u32 = 0x1;\n"
|
|
#~ "const INPUT_DISCONNECT: u32 = 0x1 << 1;\n"
|
|
#~ "const PULL_DISABLED: u32 = 0x0 << 2;\n"
|
|
#~ "const DRIVE_S0S1: u32 = 0x0 << 8;\n"
|
|
#~ "const SENSE_DISABLED: u32 = 0x0 << 16;\n"
|
|
#~ "\n"
|
|
#~ "#[entry]\n"
|
|
#~ "fn main() -> ! {\n"
|
|
#~ " // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n"
|
|
#~ " let pin_cnf_21 = (GPIO_P0 + PIN_CNF + 21 * size_of::<u32>()) as *mut "
|
|
#~ "u32;\n"
|
|
#~ " let pin_cnf_28 = (GPIO_P0 + PIN_CNF + 28 * size_of::<u32>()) as *mut "
|
|
#~ "u32;\n"
|
|
#~ " // Safe because the pointers are to valid peripheral control "
|
|
#~ "registers, and\n"
|
|
#~ " // no aliases exist.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " pin_cnf_21.write_volatile(\n"
|
|
#~ " DIR_OUTPUT | INPUT_DISCONNECT | PULL_DISABLED | DRIVE_S0S1 | "
|
|
#~ "SENSE_DISABLED,\n"
|
|
#~ " );\n"
|
|
#~ " pin_cnf_28.write_volatile(\n"
|
|
#~ " DIR_OUTPUT | INPUT_DISCONNECT | PULL_DISABLED | DRIVE_S0S1 | "
|
|
#~ "SENSE_DISABLED,\n"
|
|
#~ " );\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // 핀 28을 low로, 핀 21을 high로 설정하여 LED을 켭니다.\n"
|
|
#~ " let gpio0_outset = (GPIO_P0 + OUTSET) as *mut u32;\n"
|
|
#~ " let gpio0_outclr = (GPIO_P0 + OUTCLR) as *mut u32;\n"
|
|
#~ " // 포인터가 유효한 주변기기 컨트롤 레지스터에 관한 것이므로 안전하고\n"
|
|
#~ " // 별칭이 없습니다.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " gpio0_outclr.write_volatile(1 << 28);\n"
|
|
#~ " gpio0_outset.write_volatile(1 << 21);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin mmio\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin mmio\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "extern crate panic_halt as _;\n"
|
|
#~ "\n"
|
|
#~ "use cortex_m_rt::entry;\n"
|
|
#~ "use nrf52833_pac::Peripherals;\n"
|
|
#~ "\n"
|
|
#~ "#[entry]\n"
|
|
#~ "fn main() -> ! {\n"
|
|
#~ " let p = Peripherals::take().unwrap();\n"
|
|
#~ " let gpio0 = p.P0;\n"
|
|
#~ "\n"
|
|
#~ " // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n"
|
|
#~ " gpio0.pin_cnf[21].write(|w| {\n"
|
|
#~ " w.dir().output();\n"
|
|
#~ " w.input().disconnect();\n"
|
|
#~ " w.pull().disabled();\n"
|
|
#~ " w.drive().s0s1();\n"
|
|
#~ " w.sense().disabled();\n"
|
|
#~ " w\n"
|
|
#~ " });\n"
|
|
#~ " gpio0.pin_cnf[28].write(|w| {\n"
|
|
#~ " w.dir().output();\n"
|
|
#~ " w.input().disconnect();\n"
|
|
#~ " w.pull().disabled();\n"
|
|
#~ " w.drive().s0s1();\n"
|
|
#~ " w.sense().disabled();\n"
|
|
#~ " w\n"
|
|
#~ " });\n"
|
|
#~ "\n"
|
|
#~ " // Set pin 28 low and pin 21 high to turn the LED on.\n"
|
|
#~ " gpio0.outclr.write(|w| w.pin28().clear());\n"
|
|
#~ " gpio0.outset.write(|w| w.pin21().set());\n"
|
|
#~ "\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "extern crate panic_halt as _;\n"
|
|
#~ "\n"
|
|
#~ "use cortex_m_rt::entry;\n"
|
|
#~ "use nrf52833_pac::Peripherals;\n"
|
|
#~ "\n"
|
|
#~ "#[entry]\n"
|
|
#~ "fn main() -> ! {\n"
|
|
#~ " let p = Peripherals::take().unwrap();\n"
|
|
#~ " let gpio0 = p.P0;\n"
|
|
#~ "\n"
|
|
#~ " // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n"
|
|
#~ " gpio0.pin_cnf[21].write(|w| {\n"
|
|
#~ " w.dir().output();\n"
|
|
#~ " w.input().disconnect();\n"
|
|
#~ " w.pull().disabled();\n"
|
|
#~ " w.drive().s0s1();\n"
|
|
#~ " w.sense().disabled();\n"
|
|
#~ " w\n"
|
|
#~ " });\n"
|
|
#~ " gpio0.pin_cnf[28].write(|w| {\n"
|
|
#~ " w.dir().output();\n"
|
|
#~ " w.input().disconnect();\n"
|
|
#~ " w.pull().disabled();\n"
|
|
#~ " w.drive().s0s1();\n"
|
|
#~ " w.sense().disabled();\n"
|
|
#~ " w\n"
|
|
#~ " });\n"
|
|
#~ "\n"
|
|
#~ " // 핀 28을 low로, 핀 21을 high로 설정하여 LED를 켭니다.\n"
|
|
#~ " gpio0.outclr.write(|w| w.pin28().clear());\n"
|
|
#~ " gpio0.outset.write(|w| w.pin21().set());\n"
|
|
#~ "\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin pac\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin pac\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "extern crate panic_halt as _;\n"
|
|
#~ "\n"
|
|
#~ "use cortex_m_rt::entry;\n"
|
|
#~ "use nrf52833_hal::gpio::{p0, Level};\n"
|
|
#~ "use nrf52833_hal::pac::Peripherals;\n"
|
|
#~ "use nrf52833_hal::prelude::*;\n"
|
|
#~ "\n"
|
|
#~ "#[entry]\n"
|
|
#~ "fn main() -> ! {\n"
|
|
#~ " let p = Peripherals::take().unwrap();\n"
|
|
#~ "\n"
|
|
#~ " // Create HAL wrapper for GPIO port 0.\n"
|
|
#~ " let gpio0 = p0::Parts::new(p.P0);\n"
|
|
#~ "\n"
|
|
#~ " // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n"
|
|
#~ " let mut col1 = gpio0.p0_28.into_push_pull_output(Level::High);\n"
|
|
#~ " let mut row1 = gpio0.p0_21.into_push_pull_output(Level::Low);\n"
|
|
#~ "\n"
|
|
#~ " // Set pin 28 low and pin 21 high to turn the LED on.\n"
|
|
#~ " col1.set_low().unwrap();\n"
|
|
#~ " row1.set_high().unwrap();\n"
|
|
#~ "\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "extern crate panic_halt as _;\n"
|
|
#~ "\n"
|
|
#~ "use cortex_m_rt::entry;\n"
|
|
#~ "use nrf52833_hal::gpio::{p0, Level};\n"
|
|
#~ "use nrf52833_hal::pac::Peripherals;\n"
|
|
#~ "use nrf52833_hal::prelude::*;\n"
|
|
#~ "\n"
|
|
#~ "#[entry]\n"
|
|
#~ "fn main() -> ! {\n"
|
|
#~ " let p = Peripherals::take().unwrap();\n"
|
|
#~ "\n"
|
|
#~ " // Create HAL wrapper for GPIO port 0.\n"
|
|
#~ " let gpio0 = p0::Parts::new(p.P0);\n"
|
|
#~ "\n"
|
|
#~ " // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n"
|
|
#~ " let mut col1 = gpio0.p0_28.into_push_pull_output(Level::High);\n"
|
|
#~ " let mut row1 = gpio0.p0_21.into_push_pull_output(Level::Low);\n"
|
|
#~ "\n"
|
|
#~ " // Set pin 28 low and pin 21 high to turn the LED on.\n"
|
|
#~ " col1.set_low().unwrap();\n"
|
|
#~ " row1.set_high().unwrap();\n"
|
|
#~ "\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin hal\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin hal\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "extern crate panic_halt as _;\n"
|
|
#~ "\n"
|
|
#~ "use cortex_m_rt::entry;\n"
|
|
#~ "use microbit::hal::prelude::*;\n"
|
|
#~ "use microbit::Board;\n"
|
|
#~ "\n"
|
|
#~ "#[entry]\n"
|
|
#~ "fn main() -> ! {\n"
|
|
#~ " let mut board = Board::take().unwrap();\n"
|
|
#~ "\n"
|
|
#~ " board.display_pins.col1.set_low().unwrap();\n"
|
|
#~ " board.display_pins.row1.set_high().unwrap();\n"
|
|
#~ "\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "extern crate panic_halt as _;\n"
|
|
#~ "\n"
|
|
#~ "use cortex_m_rt::entry;\n"
|
|
#~ "use microbit::hal::prelude::*;\n"
|
|
#~ "use microbit::Board;\n"
|
|
#~ "\n"
|
|
#~ "#[entry]\n"
|
|
#~ "fn main() -> ! {\n"
|
|
#~ " let mut board = Board::take().unwrap();\n"
|
|
#~ "\n"
|
|
#~ " board.display_pins.col1.set_low().unwrap();\n"
|
|
#~ " board.display_pins.row1.set_high().unwrap();\n"
|
|
#~ "\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin board_support\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin board_support\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#[entry]\n"
|
|
#~ "fn main() -> ! {\n"
|
|
#~ " let p = Peripherals::take().unwrap();\n"
|
|
#~ " let gpio0 = p0::Parts::new(p.P0);\n"
|
|
#~ "\n"
|
|
#~ " let pin: P0_01<Disconnected> = gpio0.p0_01;\n"
|
|
#~ "\n"
|
|
#~ " // let gpio0_01_again = gpio0.p0_01; // Error, moved.\n"
|
|
#~ " let pin_input: P0_01<Input<Floating>> = pin.into_floating_input();\n"
|
|
#~ " if pin_input.is_high().unwrap() {\n"
|
|
#~ " // ...\n"
|
|
#~ " }\n"
|
|
#~ " let mut pin_output: P0_01<Output<OpenDrain>> = pin_input\n"
|
|
#~ " .into_open_drain_output(OpenDrainConfig::Disconnect0Standard1, "
|
|
#~ "Level::Low);\n"
|
|
#~ " pin_output.set_high().unwrap();\n"
|
|
#~ " // pin_input.is_high(); // Error, moved.\n"
|
|
#~ "\n"
|
|
#~ " let _pin2: P0_02<Output<OpenDrain>> = gpio0\n"
|
|
#~ " .p0_02\n"
|
|
#~ " .into_open_drain_output(OpenDrainConfig::Disconnect0Standard1, "
|
|
#~ "Level::Low);\n"
|
|
#~ " let _pin3: P0_03<Output<PushPull>> = gpio0.p0_03."
|
|
#~ "into_push_pull_output(Level::Low);\n"
|
|
#~ "\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#[entry]\n"
|
|
#~ "fn main() -> ! {\n"
|
|
#~ " let p = Peripherals::take().unwrap();\n"
|
|
#~ " let gpio0 = p0::Parts::new(p.P0);\n"
|
|
#~ "\n"
|
|
#~ " let pin: P0_01<Disconnected> = gpio0.p0_01;\n"
|
|
#~ "\n"
|
|
#~ " // let gpio0_01_again = gpio0.p0_01; // Error, moved.\n"
|
|
#~ " let pin_input: P0_01<Input<Floating>> = pin.into_floating_input();\n"
|
|
#~ " if pin_input.is_high().unwrap() {\n"
|
|
#~ " // ...\n"
|
|
#~ " }\n"
|
|
#~ " let mut pin_output: P0_01<Output<OpenDrain>> = pin_input\n"
|
|
#~ " .into_open_drain_output(OpenDrainConfig::Disconnect0Standard1, "
|
|
#~ "Level::Low);\n"
|
|
#~ " pin_output.set_high().unwrap();\n"
|
|
#~ " // pin_input.is_high(); // 오류, 이동했습니다.\n"
|
|
#~ "\n"
|
|
#~ " let _pin2: P0_02<Output<OpenDrain>> = gpio0\n"
|
|
#~ " .p0_02\n"
|
|
#~ " .into_open_drain_output(OpenDrainConfig::Disconnect0Standard1, "
|
|
#~ "Level::Low);\n"
|
|
#~ " let _pin3: P0_03<Output<PushPull>> = gpio0.p0_03."
|
|
#~ "into_push_pull_output(Level::Low);\n"
|
|
#~ "\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "SWD"
|
|
#~ msgstr "SWD"
|
|
|
|
#~ msgid "GDB stub and Microsoft "
|
|
#~ msgstr "GDB 스텁 및 Microsoft "
|
|
|
|
#~ msgid "DAP"
|
|
#~ msgstr "DAP"
|
|
|
|
#~ msgid " server"
|
|
#~ msgstr " 서버"
|
|
|
|
#~ msgid ""
|
|
#~ "`cargo-embed` is a cargo subcommand to build and flash binaries, log "
|
|
#~ msgstr ""
|
|
#~ "`cargo-embed`는 cargo의 서브 커맨트로써, 바이너리를 빌드하고 플래시하며, "
|
|
|
|
#~ msgid "RTT"
|
|
#~ msgstr "RTT"
|
|
|
|
#~ msgid ""
|
|
#~ "```toml\n"
|
|
#~ "[default.general]\n"
|
|
#~ "chip = \"nrf52833_xxAA\"\n"
|
|
#~ "\n"
|
|
#~ "[debug.gdb]\n"
|
|
#~ "enabled = true\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```toml\n"
|
|
#~ "[default.general]\n"
|
|
#~ "chip = \"nrf52833_xxAA\"\n"
|
|
#~ "\n"
|
|
#~ "[debug.gdb]\n"
|
|
#~ "enabled = true\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin board_support debug\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin board_support debug\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```sh\n"
|
|
#~ "gdb-multiarch target/thumbv7em-none-eabihf/debug/board_support --eval-"
|
|
#~ "command=\"target remote :1337\"\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```sh\n"
|
|
#~ "gdb-multiarch target/thumbv7em-none-eabihf/debug/board_support --eval-"
|
|
#~ "command=\"target remote :1337\"\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```gdb\n"
|
|
#~ "b src/bin/board_support.rs:29\n"
|
|
#~ "b src/bin/board_support.rs:30\n"
|
|
#~ "b src/bin/board_support.rs:32\n"
|
|
#~ "c\n"
|
|
#~ "c\n"
|
|
#~ "c\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```gdb\n"
|
|
#~ "b src/bin/board_support.rs:29\n"
|
|
#~ "b src/bin/board_support.rs:30\n"
|
|
#~ "b src/bin/board_support.rs:32\n"
|
|
#~ "c\n"
|
|
#~ "c\n"
|
|
#~ "c\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```toml\n"
|
|
#~ "[default.general]\n"
|
|
#~ "chip = \"nrf52833_xxAA\"\n"
|
|
#~ "\n"
|
|
#~ "[debug.gdb]\n"
|
|
#~ "enabled = true\n"
|
|
#~ "\n"
|
|
#~ "[debug.reset]\n"
|
|
#~ "halt_afterwards = true\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```toml\n"
|
|
#~ "[default.general]\n"
|
|
#~ "chip = \"nrf52833_xxAA\"\n"
|
|
#~ "\n"
|
|
#~ "[debug.gdb]\n"
|
|
#~ "enabled = true\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "HVC"
|
|
#~ msgstr "HVC"
|
|
|
|
#~ msgid " to tell the firmware to power off the system:"
|
|
#~ msgstr "를 호출하는 방법은 다음과 같습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "use core::arch::asm;\n"
|
|
#~ "use core::panic::PanicInfo;\n"
|
|
#~ "\n"
|
|
#~ "mod exceptions;\n"
|
|
#~ "\n"
|
|
#~ "const PSCI_SYSTEM_OFF: u32 = 0x84000008;\n"
|
|
#~ "\n"
|
|
#~ "#[no_mangle]\n"
|
|
#~ "extern \"C\" fn main(_x0: u64, _x1: u64, _x2: u64, _x3: u64) {\n"
|
|
#~ " // Safe because this only uses the declared registers and doesn't do\n"
|
|
#~ " // anything with memory.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " asm!(\"hvc #0\",\n"
|
|
#~ " inout(\"w0\") PSCI_SYSTEM_OFF => _,\n"
|
|
#~ " inout(\"w1\") 0 => _,\n"
|
|
#~ " inout(\"w2\") 0 => _,\n"
|
|
#~ " inout(\"w3\") 0 => _,\n"
|
|
#~ " inout(\"w4\") 0 => _,\n"
|
|
#~ " inout(\"w5\") 0 => _,\n"
|
|
#~ " inout(\"w6\") 0 => _,\n"
|
|
#~ " inout(\"w7\") 0 => _,\n"
|
|
#~ " options(nomem, nostack)\n"
|
|
#~ " );\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "use core::arch::asm;\n"
|
|
#~ "use core::panic::PanicInfo;\n"
|
|
#~ "\n"
|
|
#~ "mod exceptions;\n"
|
|
#~ "\n"
|
|
#~ "const PSCI_SYSTEM_OFF: u32 = 0x84000008;\n"
|
|
#~ "\n"
|
|
#~ "#[no_mangle]\n"
|
|
#~ "extern \"C\" fn main(_x0: u64, _x1: u64, _x2: u64, _x3: u64) {\n"
|
|
#~ " // Safe because this only uses the declared registers and doesn't do\n"
|
|
#~ " // anything with memory.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " asm!(\"hvc #0\",\n"
|
|
#~ " inout(\"w0\") PSCI_SYSTEM_OFF => _,\n"
|
|
#~ " inout(\"w1\") 0 => _,\n"
|
|
#~ " inout(\"w2\") 0 => _,\n"
|
|
#~ " inout(\"w3\") 0 => _,\n"
|
|
#~ " inout(\"w4\") 0 => _,\n"
|
|
#~ " inout(\"w5\") 0 => _,\n"
|
|
#~ " inout(\"w6\") 0 => _,\n"
|
|
#~ " inout(\"w7\") 0 => _,\n"
|
|
#~ " options(nomem, nostack)\n"
|
|
#~ " );\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " loop {}\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "const FLAG_REGISTER_OFFSET: usize = 0x18;\n"
|
|
#~ "const FR_BUSY: u8 = 1 << 3;\n"
|
|
#~ "const FR_TXFF: u8 = 1 << 5;\n"
|
|
#~ "\n"
|
|
#~ "/// Minimal driver for a PL011 UART.\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "pub struct Uart {\n"
|
|
#~ " base_address: *mut u8,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Uart {\n"
|
|
#~ " /// Constructs a new instance of the UART driver for a PL011 device "
|
|
#~ "at the\n"
|
|
#~ " /// given base address.\n"
|
|
#~ " ///\n"
|
|
#~ " /// # Safety\n"
|
|
#~ " ///\n"
|
|
#~ " /// The given base address must point to the 8 MMIO control registers "
|
|
#~ "of a\n"
|
|
#~ " /// PL011 device, which must be mapped into the address space of the "
|
|
#~ "process\n"
|
|
#~ " /// as device memory and not have any other aliases.\n"
|
|
#~ " pub unsafe fn new(base_address: *mut u8) -> Self {\n"
|
|
#~ " Self { base_address }\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " /// Writes a single byte to the UART.\n"
|
|
#~ " pub fn write_byte(&self, byte: u8) {\n"
|
|
#~ " // Wait until there is room in the TX buffer.\n"
|
|
#~ " while self.read_flag_register() & FR_TXFF != 0 {}\n"
|
|
#~ "\n"
|
|
#~ " // Safe because we know that the base address points to the "
|
|
#~ "control\n"
|
|
#~ " // registers of a PL011 device which is appropriately mapped.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " // Write to the TX buffer.\n"
|
|
#~ " self.base_address.write_volatile(byte);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // Wait until the UART is no longer busy.\n"
|
|
#~ " while self.read_flag_register() & FR_BUSY != 0 {}\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn read_flag_register(&self) -> u8 {\n"
|
|
#~ " // Safe because we know that the base address points to the "
|
|
#~ "control\n"
|
|
#~ " // registers of a PL011 device which is appropriately mapped.\n"
|
|
#~ " unsafe { self.base_address.add(FLAG_REGISTER_OFFSET)."
|
|
#~ "read_volatile() }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "const FLAG_REGISTER_OFFSET: usize = 0x18;\n"
|
|
#~ "const FR_BUSY: u8 = 1 << 3;\n"
|
|
#~ "const FR_TXFF: u8 = 1 << 5;\n"
|
|
#~ "\n"
|
|
#~ "/// PL011 UART용 최소 드라이버입니다.\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "pub struct Uart {\n"
|
|
#~ " base_address: *mut u8,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Uart {\n"
|
|
#~ " /// Constructs a new instance of the UART driver for a PL011 device "
|
|
#~ "at the\n"
|
|
#~ " /// given base address.\n"
|
|
#~ " ///\n"
|
|
#~ " /// # Safety\n"
|
|
#~ " ///\n"
|
|
#~ " /// The given base address must point to the 8 MMIO control registers "
|
|
#~ "of a\n"
|
|
#~ " /// PL011 device, which must be mapped into the address space of the "
|
|
#~ "process\n"
|
|
#~ " /// as device memory and not have any other aliases.\n"
|
|
#~ " pub unsafe fn new(base_address: *mut u8) -> Self {\n"
|
|
#~ " Self { base_address }\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " /// UART에 한 바이트를 씁니다.\n"
|
|
#~ " pub fn write_byte(&self, byte: u8) {\n"
|
|
#~ " // Wait until there is room in the TX buffer.\n"
|
|
#~ " while self.read_flag_register() & FR_TXFF != 0 {}\n"
|
|
#~ "\n"
|
|
#~ " // `base_address`가 PL011의 컨트롤 레지스터가 매핑된 주소를 가리"
|
|
#~ "키고\n"
|
|
#~ " // 있으므로 안전합니다.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " // Write to the TX buffer.\n"
|
|
#~ " self.base_address.write_volatile(byte);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // UART가 더 이상 사용 중이 아닐 때까지 기다립니다.\n"
|
|
#~ " while self.read_flag_register() & FR_BUSY != 0 {}\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn read_flag_register(&self) -> u8 {\n"
|
|
#~ " // Safe because we know that the base address points to the "
|
|
#~ "control\n"
|
|
#~ " // registers of a PL011 device which is appropriately mapped.\n"
|
|
#~ " unsafe { self.base_address.add(FLAG_REGISTER_OFFSET)."
|
|
#~ "read_volatile() }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "/// Driver for a PL011 UART.\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "pub struct Uart {\n"
|
|
#~ " registers: *mut Registers,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Uart {\n"
|
|
#~ " /// Constructs a new instance of the UART driver for a PL011 device "
|
|
#~ "at the\n"
|
|
#~ " /// given base address.\n"
|
|
#~ " ///\n"
|
|
#~ " /// # Safety\n"
|
|
#~ " ///\n"
|
|
#~ " /// The given base address must point to the 8 MMIO control registers "
|
|
#~ "of a\n"
|
|
#~ " /// PL011 device, which must be mapped into the address space of the "
|
|
#~ "process\n"
|
|
#~ " /// as device memory and not have any other aliases.\n"
|
|
#~ " pub unsafe fn new(base_address: *mut u32) -> Self {\n"
|
|
#~ " Self {\n"
|
|
#~ " registers: base_address as *mut Registers,\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " /// Writes a single byte to the UART.\n"
|
|
#~ " pub fn write_byte(&self, byte: u8) {\n"
|
|
#~ " // Wait until there is room in the TX buffer.\n"
|
|
#~ " while self.read_flag_register().contains(Flags::TXFF) {}\n"
|
|
#~ "\n"
|
|
#~ " // Safe because we know that self.registers points to the "
|
|
#~ "control\n"
|
|
#~ " // registers of a PL011 device which is appropriately mapped.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " // Write to the TX buffer.\n"
|
|
#~ " addr_of_mut!((*self.registers).dr).write_volatile(byte."
|
|
#~ "into());\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // Wait until the UART is no longer busy.\n"
|
|
#~ " while self.read_flag_register().contains(Flags::BUSY) {}\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " /// Reads and returns a pending byte, or `None` if nothing has been "
|
|
#~ "received.\n"
|
|
#~ " pub fn read_byte(&self) -> Option<u8> {\n"
|
|
#~ " if self.read_flag_register().contains(Flags::RXFE) {\n"
|
|
#~ " None\n"
|
|
#~ " } else {\n"
|
|
#~ " let data = unsafe { addr_of!((*self.registers).dr)."
|
|
#~ "read_volatile() };\n"
|
|
#~ " // TODO: Check for error conditions in bits 8-11.\n"
|
|
#~ " Some(data as u8)\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn read_flag_register(&self) -> Flags {\n"
|
|
#~ " // Safe because we know that self.registers points to the "
|
|
#~ "control\n"
|
|
#~ " // registers of a PL011 device which is appropriately mapped.\n"
|
|
#~ " unsafe { addr_of!((*self.registers).fr).read_volatile() }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "const FLAG_REGISTER_OFFSET: usize = 0x18;\n"
|
|
#~ "const FR_BUSY: u8 = 1 << 3;\n"
|
|
#~ "const FR_TXFF: u8 = 1 << 5;\n"
|
|
#~ "\n"
|
|
#~ "/// PL011 UART용 최소 드라이버입니다.\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "pub struct Uart {\n"
|
|
#~ " base_address: *mut u8,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Uart {\n"
|
|
#~ " /// Constructs a new instance of the UART driver for a PL011 device "
|
|
#~ "at the\n"
|
|
#~ " /// given base address.\n"
|
|
#~ " ///\n"
|
|
#~ " /// # Safety\n"
|
|
#~ " ///\n"
|
|
#~ " /// The given base address must point to the 8 MMIO control registers "
|
|
#~ "of a\n"
|
|
#~ " /// PL011 device, which must be mapped into the address space of the "
|
|
#~ "process\n"
|
|
#~ " /// as device memory and not have any other aliases.\n"
|
|
#~ " pub unsafe fn new(base_address: *mut u8) -> Self {\n"
|
|
#~ " Self { base_address }\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " /// UART에 한 바이트를 씁니다.\n"
|
|
#~ " pub fn write_byte(&self, byte: u8) {\n"
|
|
#~ " // Wait until there is room in the TX buffer.\n"
|
|
#~ " while self.read_flag_register() & FR_TXFF != 0 {}\n"
|
|
#~ "\n"
|
|
#~ " // `base_address`가 PL011의 컨트롤 레지스터가 매핑된 주소를 가리"
|
|
#~ "키고\n"
|
|
#~ " // 있으므로 안전합니다.\n"
|
|
#~ " unsafe {\n"
|
|
#~ " // Write to the TX buffer.\n"
|
|
#~ " self.base_address.write_volatile(byte);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " // UART가 더 이상 사용 중이 아닐 때까지 기다립니다.\n"
|
|
#~ " while self.read_flag_register() & FR_BUSY != 0 {}\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn read_flag_register(&self) -> u8 {\n"
|
|
#~ " // Safe because we know that the base address points to the "
|
|
#~ "control\n"
|
|
#~ " // registers of a PL011 device which is appropriately mapped.\n"
|
|
#~ " unsafe { self.base_address.add(FLAG_REGISTER_OFFSET)."
|
|
#~ "read_volatile() }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use crate::pl011::Uart;\n"
|
|
#~ "use core::fmt::Write;\n"
|
|
#~ "use log::{LevelFilter, Log, Metadata, Record, SetLoggerError};\n"
|
|
#~ "use spin::mutex::SpinMutex;\n"
|
|
#~ "\n"
|
|
#~ "static LOGGER: Logger = Logger {\n"
|
|
#~ " uart: SpinMutex::new(None),\n"
|
|
#~ "};\n"
|
|
#~ "\n"
|
|
#~ "struct Logger {\n"
|
|
#~ " uart: SpinMutex<Option<Uart>>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Log for Logger {\n"
|
|
#~ " fn enabled(&self, _metadata: &Metadata) -> bool {\n"
|
|
#~ " true\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn log(&self, record: &Record) {\n"
|
|
#~ " writeln!(\n"
|
|
#~ " self.uart.lock().as_mut().unwrap(),\n"
|
|
#~ " \"[{}] {}\",\n"
|
|
#~ " record.level(),\n"
|
|
#~ " record.args()\n"
|
|
#~ " )\n"
|
|
#~ " .unwrap();\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn flush(&self) {}\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "/// Initialises UART logger.\n"
|
|
#~ "pub fn init(uart: Uart, max_level: LevelFilter) -> Result<(), "
|
|
#~ "SetLoggerError> {\n"
|
|
#~ " LOGGER.uart.lock().replace(uart);\n"
|
|
#~ "\n"
|
|
#~ " log::set_logger(&LOGGER)?;\n"
|
|
#~ " log::set_max_level(max_level);\n"
|
|
#~ " Ok(())\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use crate::pl011::Uart;\n"
|
|
#~ "use core::fmt::Write;\n"
|
|
#~ "use log::{LevelFilter, Log, Metadata, Record, SetLoggerError};\n"
|
|
#~ "use spin::mutex::SpinMutex;\n"
|
|
#~ "\n"
|
|
#~ "static LOGGER: Logger = Logger {\n"
|
|
#~ " uart: SpinMutex::new(None),\n"
|
|
#~ "};\n"
|
|
#~ "\n"
|
|
#~ "struct Logger {\n"
|
|
#~ " uart: SpinMutex<Option<Uart>>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Log for Logger {\n"
|
|
#~ " fn enabled(&self, _metadata: &Metadata) -> bool {\n"
|
|
#~ " true\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn log(&self, record: &Record) {\n"
|
|
#~ " writeln!(\n"
|
|
#~ " self.uart.lock().as_mut().unwrap(),\n"
|
|
#~ " \"[{}] {}\",\n"
|
|
#~ " record.level(),\n"
|
|
#~ " record.args()\n"
|
|
#~ " )\n"
|
|
#~ " .unwrap();\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn flush(&self) {}\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "/// UART 로거를 초기화합니다.\n"
|
|
#~ "pub fn init(uart: Uart, max_level: LevelFilter) -> Result<(), "
|
|
#~ "SetLoggerError> {\n"
|
|
#~ " LOGGER.uart.lock().replace(uart);\n"
|
|
#~ "\n"
|
|
#~ " log::set_logger(&LOGGER)?;\n"
|
|
#~ " log::set_max_level(max_level);\n"
|
|
#~ " Ok(())\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use zerocopy::AsBytes;\n"
|
|
#~ "\n"
|
|
#~ "#[repr(u32)]\n"
|
|
#~ "#[derive(AsBytes, Debug, Default)]\n"
|
|
#~ "enum RequestType {\n"
|
|
#~ " #[default]\n"
|
|
#~ " In = 0,\n"
|
|
#~ " Out = 1,\n"
|
|
#~ " Flush = 4,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[repr(C)]\n"
|
|
#~ "#[derive(AsBytes, Debug, Default)]\n"
|
|
#~ "struct VirtioBlockRequest {\n"
|
|
#~ " request_type: RequestType,\n"
|
|
#~ " reserved: u32,\n"
|
|
#~ " sector: u64,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let request = VirtioBlockRequest {\n"
|
|
#~ " request_type: RequestType::Flush,\n"
|
|
#~ " sector: 42,\n"
|
|
#~ " ..Default::default()\n"
|
|
#~ " };\n"
|
|
#~ "\n"
|
|
#~ " assert_eq!(\n"
|
|
#~ " request.as_bytes(),\n"
|
|
#~ " &[4, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0]\n"
|
|
#~ " );\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use zerocopy::AsBytes;\n"
|
|
#~ "\n"
|
|
#~ "#[repr(u32)]\n"
|
|
#~ "#[derive(AsBytes, Debug, Default)]\n"
|
|
#~ "enum RequestType {\n"
|
|
#~ " #[default]\n"
|
|
#~ " In = 0,\n"
|
|
#~ " Out = 1,\n"
|
|
#~ " Flush = 4,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[repr(C)]\n"
|
|
#~ "#[derive(AsBytes, Debug, Default)]\n"
|
|
#~ "struct VirtioBlockRequest {\n"
|
|
#~ " request_type: RequestType,\n"
|
|
#~ " reserved: u32,\n"
|
|
#~ " sector: u64,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let request = VirtioBlockRequest {\n"
|
|
#~ " request_type: RequestType::Flush,\n"
|
|
#~ " sector: 42,\n"
|
|
#~ " ..Default::default()\n"
|
|
#~ " };\n"
|
|
#~ "\n"
|
|
#~ " assert_eq!(\n"
|
|
#~ " request.as_bytes(),\n"
|
|
#~ " &[4, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0]\n"
|
|
#~ " );\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use aarch64_paging::{\n"
|
|
#~ " idmap::IdMap,\n"
|
|
#~ " paging::{Attributes, MemoryRegion},\n"
|
|
#~ "};\n"
|
|
#~ "\n"
|
|
#~ "const ASID: usize = 1;\n"
|
|
#~ "const ROOT_LEVEL: usize = 1;\n"
|
|
#~ "\n"
|
|
#~ "// Create a new page table with identity mapping.\n"
|
|
#~ "let mut idmap = IdMap::new(ASID, ROOT_LEVEL);\n"
|
|
#~ "// Map a 2 MiB region of memory as read-only.\n"
|
|
#~ "idmap.map_range(\n"
|
|
#~ " &MemoryRegion::new(0x80200000, 0x80400000),\n"
|
|
#~ " Attributes::NORMAL | Attributes::NON_GLOBAL | Attributes::READ_ONLY,\n"
|
|
#~ ").unwrap();\n"
|
|
#~ "// Set `TTBR0_EL1` to activate the page table.\n"
|
|
#~ "idmap.activate();\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use aarch64_paging::{\n"
|
|
#~ " idmap::IdMap,\n"
|
|
#~ " paging::{Attributes, MemoryRegion},\n"
|
|
#~ "};\n"
|
|
#~ "\n"
|
|
#~ "const ASID: usize = 1;\n"
|
|
#~ "const ROOT_LEVEL: usize = 1;\n"
|
|
#~ "\n"
|
|
#~ "// 상동(identity) 매핑으로 새로운 페이지 테이블을 만듭니다.\n"
|
|
#~ "let mut idmap = IdMap::new(ASID, ROOT_LEVEL);\n"
|
|
#~ "// 2MiB 메모리 영역을 읽기 전용으로 매핑합니다.\n"
|
|
#~ "idmap.map_range(\n"
|
|
#~ " &MemoryRegion::new(0x80200000, 0x80400000),\n"
|
|
#~ " Attributes::NORMAL | Attributes::NON_GLOBAL | Attributes::READ_ONLY,\n"
|
|
#~ ").unwrap();\n"
|
|
#~ "// 페이지 테이블을 활성화하도록 `TTBR0_EL1`을 설정합니다.\n"
|
|
#~ "idmap.activate();\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use buddy_system_allocator::FrameAllocator;\n"
|
|
#~ "use core::alloc::Layout;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut allocator = FrameAllocator::<32>::new();\n"
|
|
#~ " allocator.add_frame(0x200_0000, 0x400_0000);\n"
|
|
#~ "\n"
|
|
#~ " let layout = Layout::from_size_align(0x100, 0x100).unwrap();\n"
|
|
#~ " let bar = allocator\n"
|
|
#~ " .alloc_aligned(layout)\n"
|
|
#~ " .expect(\"Failed to allocate 0x100 byte MMIO region\");\n"
|
|
#~ " println!(\"Allocated 0x100 byte MMIO region at {:#x}\", bar);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use buddy_system_allocator::FrameAllocator;\n"
|
|
#~ "use core::alloc::Layout;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut allocator = FrameAllocator::<32>::new();\n"
|
|
#~ " allocator.add_frame(0x200_0000, 0x400_0000);\n"
|
|
#~ "\n"
|
|
#~ " let layout = Layout::from_size_align(0x100, 0x100).unwrap();\n"
|
|
#~ " let bar = allocator\n"
|
|
#~ " .alloc_aligned(layout)\n"
|
|
#~ " .expect(\"Failed to allocate 0x100 byte MMIO region\");\n"
|
|
#~ " println!(\"Allocated 0x100 byte MMIO region at {:#x}\", bar);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use tinyvec::{array_vec, ArrayVec};\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut numbers: ArrayVec<[u32; 5]> = array_vec!(42, 66);\n"
|
|
#~ " println!(\"{numbers:?}\");\n"
|
|
#~ " numbers.push(7);\n"
|
|
#~ " println!(\"{numbers:?}\");\n"
|
|
#~ " numbers.remove(1);\n"
|
|
#~ " println!(\"{numbers:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use tinyvec::{array_vec, ArrayVec};\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let mut numbers: ArrayVec<[u32; 5]> = array_vec!(42, 66);\n"
|
|
#~ " println!(\"{numbers:?}\");\n"
|
|
#~ " numbers.push(7);\n"
|
|
#~ " println!(\"{numbers:?}\");\n"
|
|
#~ " numbers.remove(1);\n"
|
|
#~ " println!(\"{numbers:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use spin::mutex::SpinMutex;\n"
|
|
#~ "\n"
|
|
#~ "static counter: SpinMutex<u32> = SpinMutex::new(0);\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"count: {}\", counter.lock());\n"
|
|
#~ " *counter.lock() += 2;\n"
|
|
#~ " println!(\"count: {}\", counter.lock());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use spin::mutex::SpinMutex;\n"
|
|
#~ "\n"
|
|
#~ "static counter: SpinMutex<u32> = SpinMutex::new(0);\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " println!(\"count: {}\", counter.lock());\n"
|
|
#~ " *counter.lock() += 2;\n"
|
|
#~ " println!(\"count: {}\", counter.lock());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```soong\n"
|
|
#~ "rust_ffi_static {\n"
|
|
#~ " name: \"libvmbase_example\",\n"
|
|
#~ " defaults: [\"vmbase_ffi_defaults\"],\n"
|
|
#~ " crate_name: \"vmbase_example\",\n"
|
|
#~ " srcs: [\"src/main.rs\"],\n"
|
|
#~ " rustlibs: [\n"
|
|
#~ " \"libvmbase\",\n"
|
|
#~ " ],\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "cc_binary {\n"
|
|
#~ " name: \"vmbase_example\",\n"
|
|
#~ " defaults: [\"vmbase_elf_defaults\"],\n"
|
|
#~ " srcs: [\n"
|
|
#~ " \"idmap.S\",\n"
|
|
#~ " ],\n"
|
|
#~ " static_libs: [\n"
|
|
#~ " \"libvmbase_example\",\n"
|
|
#~ " ],\n"
|
|
#~ " linker_scripts: [\n"
|
|
#~ " \"image.ld\",\n"
|
|
#~ " \":vmbase_sections\",\n"
|
|
#~ " ],\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "raw_binary {\n"
|
|
#~ " name: \"vmbase_example_bin\",\n"
|
|
#~ " stem: \"vmbase_example.bin\",\n"
|
|
#~ " src: \":vmbase_example\",\n"
|
|
#~ " enabled: false,\n"
|
|
#~ " target: {\n"
|
|
#~ " android_arm64: {\n"
|
|
#~ " enabled: true,\n"
|
|
#~ " },\n"
|
|
#~ " },\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```soong\n"
|
|
#~ "rust_ffi_static {\n"
|
|
#~ " name: \"libvmbase_example\",\n"
|
|
#~ " defaults: [\"vmbase_ffi_defaults\"],\n"
|
|
#~ " crate_name: \"vmbase_example\",\n"
|
|
#~ " srcs: [\"src/main.rs\"],\n"
|
|
#~ " rustlibs: [\n"
|
|
#~ " \"libvmbase\",\n"
|
|
#~ " ],\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "cc_binary {\n"
|
|
#~ " name: \"vmbase_example\",\n"
|
|
#~ " defaults: [\"vmbase_elf_defaults\"],\n"
|
|
#~ " srcs: [\n"
|
|
#~ " \"idmap.S\",\n"
|
|
#~ " ],\n"
|
|
#~ " static_libs: [\n"
|
|
#~ " \"libvmbase_example\",\n"
|
|
#~ " ],\n"
|
|
#~ " linker_scripts: [\n"
|
|
#~ " \"image.ld\",\n"
|
|
#~ " \":vmbase_sections\",\n"
|
|
#~ " ],\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "raw_binary {\n"
|
|
#~ " name: \"vmbase_example_bin\",\n"
|
|
#~ " stem: \"vmbase_example.bin\",\n"
|
|
#~ " src: \":vmbase_example\",\n"
|
|
#~ " enabled: false,\n"
|
|
#~ " target: {\n"
|
|
#~ " android_arm64: {\n"
|
|
#~ " enabled: true,\n"
|
|
#~ " },\n"
|
|
#~ " },\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "use vmbase::{main, println};\n"
|
|
#~ "\n"
|
|
#~ "main!(main);\n"
|
|
#~ "\n"
|
|
#~ "pub fn main(arg0: u64, arg1: u64, arg2: u64, arg3: u64) {\n"
|
|
#~ " println!(\"Hello world\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,compile_fail\n"
|
|
#~ "#![no_main]\n"
|
|
#~ "#![no_std]\n"
|
|
#~ "\n"
|
|
#~ "use vmbase::{main, println};\n"
|
|
#~ "\n"
|
|
#~ "main!(main);\n"
|
|
#~ "\n"
|
|
#~ "pub fn main(arg0: u64, arg1: u64, arg2: u64, arg3: u64) {\n"
|
|
#~ " println!(\"Hello world\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```rust,compile_fail\n"
|
|
#~ "// Copyright 2023 Google LLC\n"
|
|
#~ "//\n"
|
|
#~ "// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
|
|
#~ "// you may not use this file except in compliance with the License.\n"
|
|
#~ "// You may obtain a copy of the License at\n"
|
|
#~ "//\n"
|
|
#~ "// http://www.apache.org/licenses/LICENSE-2.0\n"
|
|
#~ "//\n"
|
|
#~ "// Unless required by applicable law or agreed to in writing, software\n"
|
|
#~ "// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
|
#~ "// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
|
|
#~ "implied.\n"
|
|
#~ "// See the License for the specific language governing permissions and\n"
|
|
#~ "// limitations under the License.\n"
|
|
#~ "\n"
|
|
#~ "// ANCHOR: main\n"
|
|
#~ "use crate::pl011::Uart;\n"
|
|
#~ "use core::fmt::Write;\n"
|
|
#~ "use log::{LevelFilter, Log, Metadata, Record, SetLoggerError};\n"
|
|
#~ "use spin::mutex::SpinMutex;\n"
|
|
#~ "\n"
|
|
#~ "static LOGGER: Logger = Logger {\n"
|
|
#~ " uart: SpinMutex::new(None),\n"
|
|
#~ "};\n"
|
|
#~ "\n"
|
|
#~ "struct Logger {\n"
|
|
#~ " uart: SpinMutex<Option<Uart>>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Log for Logger {\n"
|
|
#~ " fn enabled(&self, _metadata: &Metadata) -> bool {\n"
|
|
#~ " true\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn log(&self, record: &Record) {\n"
|
|
#~ " writeln!(\n"
|
|
#~ " self.uart.lock().as_mut().unwrap(),\n"
|
|
#~ " \"[{}] {}\",\n"
|
|
#~ " record.level(),\n"
|
|
#~ " record.args()\n"
|
|
#~ " )\n"
|
|
#~ " .unwrap();\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn flush(&self) {}\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "/// Initialises UART logger.\n"
|
|
#~ "pub fn init(uart: Uart, max_level: LevelFilter) -> Result<(), "
|
|
#~ "SetLoggerError> {\n"
|
|
#~ " LOGGER.uart.lock().replace(uart);\n"
|
|
#~ "\n"
|
|
#~ " log::set_logger(&LOGGER)?;\n"
|
|
#~ " log::set_max_level(max_level);\n"
|
|
#~ " Ok(())\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use crate::pl011::Uart;\n"
|
|
#~ "use core::fmt::Write;\n"
|
|
#~ "use log::{LevelFilter, Log, Metadata, Record, SetLoggerError};\n"
|
|
#~ "use spin::mutex::SpinMutex;\n"
|
|
#~ "\n"
|
|
#~ "static LOGGER: Logger = Logger {\n"
|
|
#~ " uart: SpinMutex::new(None),\n"
|
|
#~ "};\n"
|
|
#~ "\n"
|
|
#~ "struct Logger {\n"
|
|
#~ " uart: SpinMutex<Option<Uart>>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "impl Log for Logger {\n"
|
|
#~ " fn enabled(&self, _metadata: &Metadata) -> bool {\n"
|
|
#~ " true\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn log(&self, record: &Record) {\n"
|
|
#~ " writeln!(\n"
|
|
#~ " self.uart.lock().as_mut().unwrap(),\n"
|
|
#~ " \"[{}] {}\",\n"
|
|
#~ " record.level(),\n"
|
|
#~ " record.args()\n"
|
|
#~ " )\n"
|
|
#~ " .unwrap();\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " fn flush(&self) {}\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "/// UART 로거를 초기화합니다.\n"
|
|
#~ "pub fn init(uart: Uart, max_level: LevelFilter) -> Result<(), "
|
|
#~ "SetLoggerError> {\n"
|
|
#~ " LOGGER.uart.lock().replace(uart);\n"
|
|
#~ "\n"
|
|
#~ " log::set_logger(&LOGGER)?;\n"
|
|
#~ " log::set_max_level(max_level);\n"
|
|
#~ " Ok(())\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "use std::time::Duration;\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ " });\n"
|
|
#~ "\n"
|
|
#~ " for i in 1..5 {\n"
|
|
#~ " println!(\"Main thread: {i}\");\n"
|
|
#~ " thread::sleep(Duration::from_millis(5));\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "use std::time::Duration;\n"
|
|
#~ "\n"
|
|
#~ "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"
|
|
#~ " });\n"
|
|
#~ "\n"
|
|
#~ " for i in 1..5 {\n"
|
|
#~ " println!(\"Main thread: {i}\");\n"
|
|
#~ " thread::sleep(Duration::from_millis(5));\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "\n"
|
|
#~ "fn foo() {\n"
|
|
#~ " let s = String::from(\"Hello\");\n"
|
|
#~ " thread::spawn(|| {\n"
|
|
#~ " println!(\"Length: {}\", s.len());\n"
|
|
#~ " });\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " foo();\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let s = String::from(\"Hello\");\n"
|
|
#~ "\n"
|
|
#~ " thread::spawn(|| {\n"
|
|
#~ " println!(\"Length: {}\", s.len());\n"
|
|
#~ " });\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let s = String::from(\"Hello\");\n"
|
|
#~ "\n"
|
|
#~ " thread::scope(|scope| {\n"
|
|
#~ " scope.spawn(|| {\n"
|
|
#~ " println!(\"Length: {}\", s.len());\n"
|
|
#~ " });\n"
|
|
#~ " });\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let s = String::from(\"Hello\");\n"
|
|
#~ "\n"
|
|
#~ " thread::scope(|scope| {\n"
|
|
#~ " scope.spawn(|| {\n"
|
|
#~ " println!(\"Length: {}\", s.len());\n"
|
|
#~ " });\n"
|
|
#~ " });\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::sync::mpsc;\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let (tx, rx) = mpsc::channel();\n"
|
|
#~ "\n"
|
|
#~ " tx.send(10).unwrap();\n"
|
|
#~ " tx.send(20).unwrap();\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Received: {:?}\", rx.recv());\n"
|
|
#~ " println!(\"Received: {:?}\", rx.recv());\n"
|
|
#~ "\n"
|
|
#~ " let tx2 = tx.clone();\n"
|
|
#~ " tx2.send(30).unwrap();\n"
|
|
#~ " println!(\"Received: {:?}\", rx.recv());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::sync::mpsc;\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let (tx, rx) = mpsc::channel();\n"
|
|
#~ "\n"
|
|
#~ " tx.send(10).unwrap();\n"
|
|
#~ " tx.send(20).unwrap();\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Received: {:?}\", rx.recv());\n"
|
|
#~ " println!(\"Received: {:?}\", rx.recv());\n"
|
|
#~ "\n"
|
|
#~ " let tx2 = tx.clone();\n"
|
|
#~ " tx2.send(30).unwrap();\n"
|
|
#~ " println!(\"Received: {:?}\", rx.recv());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::sync::mpsc;\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "use std::time::Duration;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let (tx, rx) = mpsc::channel();\n"
|
|
#~ "\n"
|
|
#~ " 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));\n"
|
|
#~ "\n"
|
|
#~ " for msg in rx.iter() {\n"
|
|
#~ " println!(\"Main: got {msg}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::sync::mpsc;\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "use std::time::Duration;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let (tx, rx) = mpsc::channel();\n"
|
|
#~ "\n"
|
|
#~ " 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));\n"
|
|
#~ "\n"
|
|
#~ " for msg in rx.iter() {\n"
|
|
#~ " println!(\"Main: got {msg}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::sync::mpsc;\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "use std::time::Duration;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let (tx, rx) = mpsc::sync_channel(3);\n"
|
|
#~ "\n"
|
|
#~ " 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));\n"
|
|
#~ "\n"
|
|
#~ " for msg in rx.iter() {\n"
|
|
#~ " println!(\"Main: got {msg}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::sync::mpsc;\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "use std::time::Duration;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let (tx, rx) = mpsc::sync_channel(3);\n"
|
|
#~ "\n"
|
|
#~ " 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));\n"
|
|
#~ "\n"
|
|
#~ " for msg in rx.iter() {\n"
|
|
#~ " println!(\"Main: got {msg}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "use std::sync::Arc;\n"
|
|
#~ "\n"
|
|
#~ "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 = Arc::clone(&v);\n"
|
|
#~ " handles.push(thread::spawn(move || {\n"
|
|
#~ " let thread_id = thread::current().id();\n"
|
|
#~ " println!(\"{thread_id:?}: {v:?}\");\n"
|
|
#~ " }));\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " handles.into_iter().for_each(|h| h.join().unwrap());\n"
|
|
#~ " println!(\"v: {v:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "use std::sync::Arc;\n"
|
|
#~ "\n"
|
|
#~ "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 = Arc::clone(&v);\n"
|
|
#~ " handles.push(thread::spawn(move || {\n"
|
|
#~ " let thread_id = thread::current().id();\n"
|
|
#~ " println!(\"{thread_id:?}: {v:?}\");\n"
|
|
#~ " }));\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " handles.into_iter().for_each(|h| h.join().unwrap());\n"
|
|
#~ " println!(\"v: {v:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::sync::Mutex;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v = Mutex::new(vec![10, 20, 30]);\n"
|
|
#~ " println!(\"v: {:?}\", v.lock().unwrap());\n"
|
|
#~ "\n"
|
|
#~ " {\n"
|
|
#~ " let mut guard = v.lock().unwrap();\n"
|
|
#~ " guard.push(40);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"v: {:?}\", v.lock().unwrap());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::sync::Mutex;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v = Mutex::new(vec![10, 20, 30]);\n"
|
|
#~ " println!(\"v: {:?}\", v.lock().unwrap());\n"
|
|
#~ "\n"
|
|
#~ " {\n"
|
|
#~ " let mut guard = v.lock().unwrap();\n"
|
|
#~ " guard.push(40);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"v: {:?}\", v.lock().unwrap());\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "// use std::sync::{Arc, Mutex};\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v = vec![10, 20, 30];\n"
|
|
#~ " let handle = thread::spawn(|| {\n"
|
|
#~ " v.push(10);\n"
|
|
#~ " });\n"
|
|
#~ " v.push(1000);\n"
|
|
#~ "\n"
|
|
#~ " handle.join().unwrap();\n"
|
|
#~ " println!(\"v: {v:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::sync::{Arc, Mutex};\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v = Arc::new(Mutex::new(vec![10, 20, 30]));\n"
|
|
#~ "\n"
|
|
#~ " let v2 = Arc::clone(&v);\n"
|
|
#~ " let handle = thread::spawn(move || {\n"
|
|
#~ " let mut v2 = v2.lock().unwrap();\n"
|
|
#~ " v2.push(10);\n"
|
|
#~ " });\n"
|
|
#~ "\n"
|
|
#~ " {\n"
|
|
#~ " let mut v = v.lock().unwrap();\n"
|
|
#~ " v.push(1000);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " handle.join().unwrap();\n"
|
|
#~ "\n"
|
|
#~ " println!(\"v: {v:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::sync::{Arc, Mutex};\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v = Arc::new(Mutex::new(vec![10, 20, 30]));\n"
|
|
#~ "\n"
|
|
#~ " let v2 = Arc::clone(&v);\n"
|
|
#~ " let handle = thread::spawn(move || {\n"
|
|
#~ " let mut v2 = v2.lock().unwrap();\n"
|
|
#~ " v2.push(10);\n"
|
|
#~ " });\n"
|
|
#~ "\n"
|
|
#~ " {\n"
|
|
#~ " let mut v = v.lock().unwrap();\n"
|
|
#~ " v.push(1000);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " handle.join().unwrap();\n"
|
|
#~ "\n"
|
|
#~ " println!(\"v: {v:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable\n"
|
|
#~ "use std::sync::{Arc, Mutex};\n"
|
|
#~ "use std::thread;\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " let v = Arc::new(Mutex::new(vec![10, 20, 30]));\n"
|
|
#~ "\n"
|
|
#~ " let v2 = Arc::clone(&v);\n"
|
|
#~ " let handle = thread::spawn(move || {\n"
|
|
#~ " let mut v2 = v2.lock().unwrap();\n"
|
|
#~ " v2.push(10);\n"
|
|
#~ " });\n"
|
|
#~ "\n"
|
|
#~ " {\n"
|
|
#~ " let mut v = v.lock().unwrap();\n"
|
|
#~ " v.push(1000);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " handle.join().unwrap();\n"
|
|
#~ "\n"
|
|
#~ " println!(\"v: {v:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "cargo new link-checker\n"
|
|
#~ "cd link-checker\n"
|
|
#~ "cargo add --features blocking,rustls-tls reqwest\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```shell\n"
|
|
#~ "cargo init concurrency\n"
|
|
#~ "cd concurrency\n"
|
|
#~ "cargo add tokio --features full\n"
|
|
#~ "cargo run\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "cargo add scraper\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin pac\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "cargo add thiserror\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin mmio\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "cargo run\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin pac\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use futures::executor::block_on;\n"
|
|
#~ "\n"
|
|
#~ "async fn count_to(count: i32) {\n"
|
|
#~ " for i in 1..=count {\n"
|
|
#~ " println!(\"Count is: {i}!\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "async fn async_main(count: i32) {\n"
|
|
#~ " count_to(count).await;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " block_on(async_main(10));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use futures::executor::block_on;\n"
|
|
#~ "\n"
|
|
#~ "async fn count_to(count: i32) {\n"
|
|
#~ " for i in 1..=count {\n"
|
|
#~ " println!(\"Count is: {i}!\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "async fn async_main(count: i32) {\n"
|
|
#~ " count_to(count).await;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "fn main() {\n"
|
|
#~ " block_on(async_main(10));\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust\n"
|
|
#~ "use std::pin::Pin;\n"
|
|
#~ "use std::task::Context;\n"
|
|
#~ "\n"
|
|
#~ "pub trait Future {\n"
|
|
#~ " type Output;\n"
|
|
#~ " fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::"
|
|
#~ "Output>;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub enum Poll<T> {\n"
|
|
#~ " Ready(T),\n"
|
|
#~ " Pending,\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust\n"
|
|
#~ "use std::pin::Pin;\n"
|
|
#~ "use std::task::Context;\n"
|
|
#~ "\n"
|
|
#~ "pub trait Future {\n"
|
|
#~ " type Output;\n"
|
|
#~ " fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::"
|
|
#~ "Output>;\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "pub enum Poll<T> {\n"
|
|
#~ " Ready(T),\n"
|
|
#~ " Pending,\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use tokio::time;\n"
|
|
#~ "\n"
|
|
#~ "async fn count_to(count: i32) {\n"
|
|
#~ " for i in 1..=count {\n"
|
|
#~ " println!(\"Count in task: {i}!\");\n"
|
|
#~ " time::sleep(time::Duration::from_millis(5)).await;\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " tokio::spawn(count_to(10));\n"
|
|
#~ "\n"
|
|
#~ " for i in 1..5 {\n"
|
|
#~ " println!(\"Main task: {i}\");\n"
|
|
#~ " time::sleep(time::Duration::from_millis(5)).await;\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use tokio::time;\n"
|
|
#~ "\n"
|
|
#~ "async fn count_to(count: i32) {\n"
|
|
#~ " for i in 1..=count {\n"
|
|
#~ " println!(\"Count in task: {i}!\");\n"
|
|
#~ " time::sleep(time::Duration::from_millis(5)).await;\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " tokio::spawn(count_to(10));\n"
|
|
#~ "\n"
|
|
#~ " for i in 1..5 {\n"
|
|
#~ " println!(\"Main task: {i}\");\n"
|
|
#~ " time::sleep(time::Duration::from_millis(5)).await;\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,compile_fail\n"
|
|
#~ "use tokio::io::{self, AsyncReadExt, AsyncWriteExt};\n"
|
|
#~ "use tokio::net::TcpListener;\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() -> io::Result<()> {\n"
|
|
#~ " let listener = TcpListener::bind(\"127.0.0.1:6142\").await?;\n"
|
|
#~ "\tprintln!(\"listening on port 6142\");\n"
|
|
#~ "\n"
|
|
#~ " loop {\n"
|
|
#~ " let (mut socket, addr) = listener.accept().await?;\n"
|
|
#~ "\n"
|
|
#~ " println!(\"connection from {addr:?}\");\n"
|
|
#~ "\n"
|
|
#~ " tokio::spawn(async move {\n"
|
|
#~ " if let Err(e) = socket.write_all(b\"Who are you?\\n\").await "
|
|
#~ "{\n"
|
|
#~ " println!(\"socket error: {e:?}\");\n"
|
|
#~ " return;\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " let mut buf = vec![0; 1024];\n"
|
|
#~ " let reply = match socket.read(&mut buf).await {\n"
|
|
#~ " Ok(n) => {\n"
|
|
#~ " let name = std::str::from_utf8(&buf[..n]).unwrap()."
|
|
#~ "trim();\n"
|
|
#~ " format!(\"Thanks for dialing in, {name}!\\n\")\n"
|
|
#~ " }\n"
|
|
#~ " Err(e) => {\n"
|
|
#~ " println!(\"socket error: {e:?}\");\n"
|
|
#~ " return;\n"
|
|
#~ " }\n"
|
|
#~ " };\n"
|
|
#~ "\n"
|
|
#~ " if let Err(e) = socket.write_all(reply.as_bytes()).await {\n"
|
|
#~ " println!(\"socket error: {e:?}\");\n"
|
|
#~ " }\n"
|
|
#~ " });\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,compile_fail\n"
|
|
#~ "use tokio::io::{self, AsyncReadExt, AsyncWriteExt};\n"
|
|
#~ "use tokio::net::TcpListener;\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() -> io::Result<()> {\n"
|
|
#~ " let listener = TcpListener::bind(\"127.0.0.1:6142\").await?;\n"
|
|
#~ "\tprintln!(\"listening on port 6142\");\n"
|
|
#~ "\n"
|
|
#~ " loop {\n"
|
|
#~ " let (mut socket, addr) = listener.accept().await?;\n"
|
|
#~ "\n"
|
|
#~ " println!(\"connection from {addr:?}\");\n"
|
|
#~ "\n"
|
|
#~ " tokio::spawn(async move {\n"
|
|
#~ " if let Err(e) = socket.write_all(b\"Who are you?\\n\").await "
|
|
#~ "{\n"
|
|
#~ " println!(\"socket error: {e:?}\");\n"
|
|
#~ " return;\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " let mut buf = vec![0; 1024];\n"
|
|
#~ " let reply = match socket.read(&mut buf).await {\n"
|
|
#~ " Ok(n) => {\n"
|
|
#~ " let name = std::str::from_utf8(&buf[..n]).unwrap()."
|
|
#~ "trim();\n"
|
|
#~ " format!(\"Thanks for dialing in, {name}!\\n\")\n"
|
|
#~ " }\n"
|
|
#~ " Err(e) => {\n"
|
|
#~ " println!(\"socket error: {e:?}\");\n"
|
|
#~ " return;\n"
|
|
#~ " }\n"
|
|
#~ " };\n"
|
|
#~ "\n"
|
|
#~ " if let Err(e) = socket.write_all(reply.as_bytes()).await {\n"
|
|
#~ " println!(\"socket error: {e:?}\");\n"
|
|
#~ " }\n"
|
|
#~ " });\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use tokio::sync::mpsc::{self, Receiver};\n"
|
|
#~ "\n"
|
|
#~ "async fn ping_handler(mut input: Receiver<()>) {\n"
|
|
#~ " let mut count: usize = 0;\n"
|
|
#~ "\n"
|
|
#~ " while let Some(_) = input.recv().await {\n"
|
|
#~ " count += 1;\n"
|
|
#~ " println!(\"Received {count} pings so far.\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"ping_handler complete\");\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " let (sender, receiver) = mpsc::channel(32);\n"
|
|
#~ " let ping_handler_task = tokio::spawn(ping_handler(receiver));\n"
|
|
#~ " for i in 0..10 {\n"
|
|
#~ " sender.send(()).await.expect(\"Failed to send ping.\");\n"
|
|
#~ " println!(\"Sent {} pings so far.\", i + 1);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " drop(sender);\n"
|
|
#~ " ping_handler_task.await.expect(\"Something went wrong in ping handler "
|
|
#~ "task.\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use tokio::sync::mpsc::{self, Receiver};\n"
|
|
#~ "\n"
|
|
#~ "async fn ping_handler(mut input: Receiver<()>) {\n"
|
|
#~ " let mut count: usize = 0;\n"
|
|
#~ "\n"
|
|
#~ " while let Some(_) = input.recv().await {\n"
|
|
#~ " count += 1;\n"
|
|
#~ " println!(\"Received {count} pings so far.\");\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " println!(\"ping_handler complete\");\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " let (sender, receiver) = mpsc::channel(32);\n"
|
|
#~ " let ping_handler_task = tokio::spawn(ping_handler(receiver));\n"
|
|
#~ " for i in 0..10 {\n"
|
|
#~ " sender.send(()).await.expect(\"Failed to send ping.\");\n"
|
|
#~ " println!(\"Sent {} pings so far.\", i + 1);\n"
|
|
#~ " }\n"
|
|
#~ "\n"
|
|
#~ " std::mem::drop(sender);\n"
|
|
#~ " ping_handler_task.await.expect(\"Something went wrong in ping handler "
|
|
#~ "task.\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use anyhow::Result;\n"
|
|
#~ "use futures::future;\n"
|
|
#~ "use reqwest;\n"
|
|
#~ "use std::collections::HashMap;\n"
|
|
#~ "\n"
|
|
#~ "async fn size_of_page(url: &str) -> Result<usize> {\n"
|
|
#~ " let resp = reqwest::get(url).await?;\n"
|
|
#~ " Ok(resp.text().await?.len())\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " let urls: [&str; 4] = [\n"
|
|
#~ " \"https://google.com\",\n"
|
|
#~ " \"https://httpbin.org/ip\",\n"
|
|
#~ " \"https://play.rust-lang.org/\",\n"
|
|
#~ " \"BAD_URL\",\n"
|
|
#~ " ];\n"
|
|
#~ " let futures_iter = urls.into_iter().map(size_of_page);\n"
|
|
#~ " let results = future::join_all(futures_iter).await;\n"
|
|
#~ " let page_sizes_dict: HashMap<&str, Result<usize>> =\n"
|
|
#~ " urls.into_iter().zip(results.into_iter()).collect();\n"
|
|
#~ " println!(\"{:?}\", page_sizes_dict);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use anyhow::Result;\n"
|
|
#~ "use futures::future;\n"
|
|
#~ "use reqwest;\n"
|
|
#~ "use std::collections::HashMap;\n"
|
|
#~ "\n"
|
|
#~ "async fn size_of_page(url: &str) -> Result<usize> {\n"
|
|
#~ " let resp = reqwest::get(url).await?;\n"
|
|
#~ " Ok(resp.text().await?.len())\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " let urls: [&str; 4] = [\n"
|
|
#~ " \"https://google.com\",\n"
|
|
#~ " \"https://httpbin.org/ip\",\n"
|
|
#~ " \"https://play.rust-lang.org/\",\n"
|
|
#~ " \"BAD_URL\",\n"
|
|
#~ " ];\n"
|
|
#~ " let futures_iter = urls.into_iter().map(size_of_page);\n"
|
|
#~ " let results = future::join_all(futures_iter).await;\n"
|
|
#~ " let page_sizes_dict: HashMap<&str, Result<usize>> =\n"
|
|
#~ " urls.into_iter().zip(results.into_iter()).collect();\n"
|
|
#~ " println!(\"{:?}\", page_sizes_dict);\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use tokio::sync::mpsc::{self, Receiver};\n"
|
|
#~ "use tokio::time::{sleep, Duration};\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug, PartialEq)]\n"
|
|
#~ "enum Animal {\n"
|
|
#~ " Cat { name: String },\n"
|
|
#~ " Dog { name: String },\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "async fn first_animal_to_finish_race(\n"
|
|
#~ " mut cat_rcv: Receiver<String>,\n"
|
|
#~ " mut dog_rcv: Receiver<String>,\n"
|
|
#~ ") -> Option<Animal> {\n"
|
|
#~ " tokio::select! {\n"
|
|
#~ " cat_name = cat_rcv.recv() => Some(Animal::Cat { name: "
|
|
#~ "cat_name? }),\n"
|
|
#~ " dog_name = dog_rcv.recv() => Some(Animal::Dog { name: "
|
|
#~ "dog_name? })\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " let (cat_sender, cat_receiver) = mpsc::channel(32);\n"
|
|
#~ " let (dog_sender, dog_receiver) = mpsc::channel(32);\n"
|
|
#~ " tokio::spawn(async move {\n"
|
|
#~ " sleep(Duration::from_millis(500)).await;\n"
|
|
#~ " cat_sender\n"
|
|
#~ " .send(String::from(\"Felix\"))\n"
|
|
#~ " .await\n"
|
|
#~ " .expect(\"Failed to send cat.\");\n"
|
|
#~ " });\n"
|
|
#~ " tokio::spawn(async move {\n"
|
|
#~ " sleep(Duration::from_millis(50)).await;\n"
|
|
#~ " dog_sender\n"
|
|
#~ " .send(String::from(\"Rex\"))\n"
|
|
#~ " .await\n"
|
|
#~ " .expect(\"Failed to send dog.\");\n"
|
|
#~ " });\n"
|
|
#~ "\n"
|
|
#~ " let winner = first_animal_to_finish_race(cat_receiver, dog_receiver)\n"
|
|
#~ " .await\n"
|
|
#~ " .expect(\"Failed to receive winner\");\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Winner is {winner:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use tokio::sync::mpsc::{self, Receiver};\n"
|
|
#~ "use tokio::time::{sleep, Duration};\n"
|
|
#~ "\n"
|
|
#~ "#[derive(Debug, PartialEq)]\n"
|
|
#~ "enum Animal {\n"
|
|
#~ " Cat { name: String },\n"
|
|
#~ " Dog { name: String },\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "async fn first_animal_to_finish_race(\n"
|
|
#~ " mut cat_rcv: Receiver<String>,\n"
|
|
#~ " mut dog_rcv: Receiver<String>,\n"
|
|
#~ ") -> Option<Animal> {\n"
|
|
#~ " tokio::select! {\n"
|
|
#~ " cat_name = cat_rcv.recv() => Some(Animal::Cat { name: "
|
|
#~ "cat_name? }),\n"
|
|
#~ " dog_name = dog_rcv.recv() => Some(Animal::Dog { name: "
|
|
#~ "dog_name? })\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " let (cat_sender, cat_receiver) = mpsc::channel(32);\n"
|
|
#~ " let (dog_sender, dog_receiver) = mpsc::channel(32);\n"
|
|
#~ " tokio::spawn(async move {\n"
|
|
#~ " sleep(Duration::from_millis(500)).await;\n"
|
|
#~ " cat_sender\n"
|
|
#~ " .send(String::from(\"Felix\"))\n"
|
|
#~ " .await\n"
|
|
#~ " .expect(\"Failed to send cat.\");\n"
|
|
#~ " });\n"
|
|
#~ " tokio::spawn(async move {\n"
|
|
#~ " sleep(Duration::from_millis(50)).await;\n"
|
|
#~ " dog_sender\n"
|
|
#~ " .send(String::from(\"Rex\"))\n"
|
|
#~ " .await\n"
|
|
#~ " .expect(\"Failed to send dog.\");\n"
|
|
#~ " });\n"
|
|
#~ "\n"
|
|
#~ " let winner = first_animal_to_finish_race(cat_receiver, dog_receiver)\n"
|
|
#~ " .await\n"
|
|
#~ " .expect(\"Failed to receive winner\");\n"
|
|
#~ "\n"
|
|
#~ " println!(\"Winner is {winner:?}\");\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use futures::future::join_all;\n"
|
|
#~ "use std::time::Instant;\n"
|
|
#~ "\n"
|
|
#~ "async fn sleep_ms(start: &Instant, id: u64, duration_ms: u64) {\n"
|
|
#~ " std::thread::sleep(std::time::Duration::from_millis(duration_ms));\n"
|
|
#~ " println!(\n"
|
|
#~ " \"future {id} slept for {duration_ms}ms, finished after {}ms\",\n"
|
|
#~ " start.elapsed().as_millis()\n"
|
|
#~ " );\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main(flavor = \"current_thread\")]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " let start = Instant::now();\n"
|
|
#~ " let sleep_futures = (1..=10).map(|t| sleep_ms(&start, t, t * 10));\n"
|
|
#~ " join_all(sleep_futures).await;\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use futures::future::join_all;\n"
|
|
#~ "use std::time::Instant;\n"
|
|
#~ "\n"
|
|
#~ "async fn sleep_ms(start: &Instant, id: u64, duration_ms: u64) {\n"
|
|
#~ " std::thread::sleep(std::time::Duration::from_millis(duration_ms));\n"
|
|
#~ " println!(\n"
|
|
#~ " \"future {id} slept for {duration_ms}ms, finished after {}ms\",\n"
|
|
#~ " start.elapsed().as_millis()\n"
|
|
#~ " );\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main(flavor = \"current_thread\")]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " let start = Instant::now();\n"
|
|
#~ " let sleep_futures = (1..=10).map(|t| sleep_ms(&start, t, t * 10));\n"
|
|
#~ " join_all(sleep_futures).await;\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use tokio::sync::{mpsc, oneshot};\n"
|
|
#~ "use tokio::task::spawn;\n"
|
|
#~ "use tokio::time::{sleep, Duration};\n"
|
|
#~ "\n"
|
|
#~ "// A work item. In this case, just sleep for the given time and respond\n"
|
|
#~ "// with a message on the `respond_on` channel.\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Work {\n"
|
|
#~ " input: u32,\n"
|
|
#~ " respond_on: oneshot::Sender<u32>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// A worker which listens for work on a queue and performs it.\n"
|
|
#~ "async fn worker(mut work_queue: mpsc::Receiver<Work>) {\n"
|
|
#~ " let mut iterations = 0;\n"
|
|
#~ " loop {\n"
|
|
#~ " tokio::select! {\n"
|
|
#~ " Some(work) = work_queue.recv() => {\n"
|
|
#~ " sleep(Duration::from_millis(10)).await; // Pretend to "
|
|
#~ "work.\n"
|
|
#~ " work.respond_on\n"
|
|
#~ " .send(work.input * 1000)\n"
|
|
#~ " .expect(\"failed to send response\");\n"
|
|
#~ " iterations += 1;\n"
|
|
#~ " }\n"
|
|
#~ " // TODO: report number of iterations every 100ms\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// A requester which requests work and waits for it to complete.\n"
|
|
#~ "async fn do_work(work_queue: &mpsc::Sender<Work>, input: u32) -> u32 {\n"
|
|
#~ " let (tx, rx) = oneshot::channel();\n"
|
|
#~ " work_queue\n"
|
|
#~ " .send(Work {\n"
|
|
#~ " input,\n"
|
|
#~ " respond_on: tx,\n"
|
|
#~ " })\n"
|
|
#~ " .await\n"
|
|
#~ " .expect(\"failed to send on work queue\");\n"
|
|
#~ " rx.await.expect(\"failed waiting for response\")\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " let (tx, rx) = mpsc::channel(10);\n"
|
|
#~ " spawn(worker(rx));\n"
|
|
#~ " for i in 0..100 {\n"
|
|
#~ " let resp = do_work(&tx, i).await;\n"
|
|
#~ " println!(\"work result for iteration {i}: {resp}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use tokio::sync::{mpsc, oneshot};\n"
|
|
#~ "use tokio::task::spawn;\n"
|
|
#~ "use tokio::time::{sleep, Duration};\n"
|
|
#~ "\n"
|
|
#~ "// 작업 항목. 이 경우 지정된 시간 동안 절전 모드로 있다가\n"
|
|
#~ "// `respond_on` 채널의 메시지로 응답합니다.\n"
|
|
#~ "#[derive(Debug)]\n"
|
|
#~ "struct Work {\n"
|
|
#~ " input: u32,\n"
|
|
#~ " respond_on: oneshot::Sender<u32>,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// 대기열에서 작업을 리슨하고 실행하는 worker입니다.\n"
|
|
#~ "async fn worker(mut work_queue: mpsc::Receiver<Work>) {\n"
|
|
#~ " let mut iterations = 0;\n"
|
|
#~ " loop {\n"
|
|
#~ " tokio::select! {\n"
|
|
#~ " Some(work) = work_queue.recv() => {\n"
|
|
#~ " sleep(Duration::from_millis(10)).await; // Pretend to "
|
|
#~ "work.\n"
|
|
#~ " work.respond_on\n"
|
|
#~ " .send(work.input * 1000)\n"
|
|
#~ " .expect(\"failed to send response\");\n"
|
|
#~ " iterations += 1;\n"
|
|
#~ " }\n"
|
|
#~ " // TODO: 100ms마다 반복 횟수를 보고합니다.\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "// 작업을 요청하고 작업이 완료될 때까지 기다리는 요청자입니다.\n"
|
|
#~ "async fn do_work(work_queue: &mpsc::Sender<Work>, input: u32) -> u32 {\n"
|
|
#~ " let (tx, rx) = oneshot::channel();\n"
|
|
#~ " work_queue\n"
|
|
#~ " .send(Work {\n"
|
|
#~ " input,\n"
|
|
#~ " respond_on: tx,\n"
|
|
#~ " })\n"
|
|
#~ " .await\n"
|
|
#~ " .expect(\"failed to send on work queue\");\n"
|
|
#~ " rx.await.expect(\"failed waiting for response\")\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " let (tx, rx) = mpsc::channel(10);\n"
|
|
#~ " spawn(worker(rx));\n"
|
|
#~ " for i in 0..100 {\n"
|
|
#~ " let resp = do_work(&tx, i).await;\n"
|
|
#~ " println!(\"work result for iteration {i}: {resp}\");\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,compile_fail\n"
|
|
#~ "let mut timeout_fut = sleep(Duration::from_millis(100));\n"
|
|
#~ "loop {\n"
|
|
#~ " select! {\n"
|
|
#~ " ..,\n"
|
|
#~ " _ = timeout_fut => { println!(..); },\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,compile_fail\n"
|
|
#~ "let mut timeout_fut = sleep(Duration::from_millis(100));\n"
|
|
#~ "loop {\n"
|
|
#~ " select! {\n"
|
|
#~ " ..,\n"
|
|
#~ " _ = timeout_fut => { println!(..); },\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,compile_fail\n"
|
|
#~ "let mut timeout_fut = Box::pin(sleep(Duration::from_millis(100)));\n"
|
|
#~ "loop {\n"
|
|
#~ " select! {\n"
|
|
#~ " ..,\n"
|
|
#~ " _ = &mut timeout_fut => { println!(..); },\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,compile_fail\n"
|
|
#~ "let mut timeout_fut = Box::pin(sleep(Duration::from_millis(100)));\n"
|
|
#~ "loop {\n"
|
|
#~ " select! {\n"
|
|
#~ " ..,\n"
|
|
#~ " _ = &mut timeout_fut => { println!(..); },\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#~ msgid ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use async_trait::async_trait;\n"
|
|
#~ "use std::time::Instant;\n"
|
|
#~ "use tokio::time::{sleep, Duration};\n"
|
|
#~ "\n"
|
|
#~ "#[async_trait]\n"
|
|
#~ "trait Sleeper {\n"
|
|
#~ " async fn sleep(&self);\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "struct FixedSleeper {\n"
|
|
#~ " sleep_ms: u64,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[async_trait]\n"
|
|
#~ "impl Sleeper for FixedSleeper {\n"
|
|
#~ " async fn sleep(&self) {\n"
|
|
#~ " sleep(Duration::from_millis(self.sleep_ms)).await;\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "async fn run_all_sleepers_multiple_times(sleepers: Vec<Box<dyn Sleeper>>, "
|
|
#~ "n_times: usize) {\n"
|
|
#~ " for _ in 0..n_times {\n"
|
|
#~ " println!(\"running all sleepers..\");\n"
|
|
#~ " for sleeper in &sleepers {\n"
|
|
#~ " let start = Instant::now();\n"
|
|
#~ " sleeper.sleep().await;\n"
|
|
#~ " println!(\"slept for {}ms\", start.elapsed().as_millis());\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " let sleepers: Vec<Box<dyn Sleeper>> = vec![\n"
|
|
#~ " Box::new(FixedSleeper { sleep_ms: 50 }),\n"
|
|
#~ " Box::new(FixedSleeper { sleep_ms: 100 }),\n"
|
|
#~ " ];\n"
|
|
#~ " run_all_sleepers_multiple_times(sleepers, 5).await;\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```rust,editable,compile_fail\n"
|
|
#~ "use async_trait::async_trait;\n"
|
|
#~ "use std::time::Instant;\n"
|
|
#~ "use tokio::time::{sleep, Duration};\n"
|
|
#~ "\n"
|
|
#~ "#[async_trait]\n"
|
|
#~ "trait Sleeper {\n"
|
|
#~ " async fn sleep(&self);\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "struct FixedSleeper {\n"
|
|
#~ " sleep_ms: u64,\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[async_trait]\n"
|
|
#~ "impl Sleeper for FixedSleeper {\n"
|
|
#~ " async fn sleep(&self) {\n"
|
|
#~ " sleep(Duration::from_millis(self.sleep_ms)).await;\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "async fn run_all_sleepers_multiple_times(sleepers: Vec<Box<dyn Sleeper>>, "
|
|
#~ "n_times: usize) {\n"
|
|
#~ " for _ in 0..n_times {\n"
|
|
#~ " println!(\"running all sleepers..\");\n"
|
|
#~ " for sleeper in &sleepers {\n"
|
|
#~ " let start = Instant::now();\n"
|
|
#~ " sleeper.sleep().await;\n"
|
|
#~ " println!(\"slept for {}ms\", start.elapsed().as_millis());\n"
|
|
#~ " }\n"
|
|
#~ " }\n"
|
|
#~ "}\n"
|
|
#~ "\n"
|
|
#~ "#[tokio::main]\n"
|
|
#~ "async fn main() {\n"
|
|
#~ " let sleepers: Vec<Box<dyn Sleeper>> = vec![\n"
|
|
#~ " Box::new(FixedSleeper { sleep_ms: 50 }),\n"
|
|
#~ " Box::new(FixedSleeper { sleep_ms: 100 }),\n"
|
|
#~ " ];\n"
|
|
#~ " run_all_sleepers_multiple_times(sleepers, 5).await;\n"
|
|
#~ "}\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "cargo run --bin server\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin pac\n"
|
|
#~ "```"
|
|
|
|
#, fuzzy
|
|
#~ msgid ""
|
|
#~ "```shell\n"
|
|
#~ "cargo run --bin client\n"
|
|
#~ "```"
|
|
#~ msgstr ""
|
|
#~ "```sh\n"
|
|
#~ "cargo embed --bin pac\n"
|
|
#~ "```"
|
|
|
|
#~ msgid "You will find solutions to the exercises on the following pages."
|
|
#~ msgstr "연습문제의 해답은 다음 페이지에서 확인할 수 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Feel free to ask questions about the solutions [on GitHub](https://github."
|
|
#~ "com/google/comprehensive-rust/discussions). Let us know if you have a "
|
|
#~ "different or better solution than what is presented here."
|
|
#~ msgstr ""
|
|
#~ "[깃허브](https://github.com/google/comprehensive-rust/discussions)에서 이"
|
|
#~ "에 대해 자유롭게 질문하시고 더 나은 솔루션이 있다면 알려주시기 바랍니다."
|
|
|
|
#~ msgid ""
|
|
#~ "**Note:** Please ignore the `// ANCHOR: label` and `// ANCHOR_END: label` "
|
|
#~ "comments you see in the solutions. They are there to make it possible to "
|
|
#~ "re-use parts of the solutions as the exercises."
|
|
#~ msgstr ""
|
|
#~ "**참고:** `// ANCHOR: label`과 `// ANCHOR_END: label` 주석은 문제를 구성하"
|
|
#~ "기 위한 메타 주석으로 무시하시면 됩니다."
|
|
|
|
#~ msgid "Day 1 Morning Exercises"
|
|
#~ msgstr "1일차 오전 연습문제"
|
|
|
|
#~ msgid "Bonus question"
|
|
#~ msgstr "보너스 문제"
|
|
|
|
#~ msgid ""
|
|
#~ "It requires more advanced concepts. 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]]` 반환 타입으로 사용할 수 없습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "You can attempt to use something like `Vec<Vec<i32>>`, but this doesn't "
|
|
#~ "work out-of-the-box 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`을 사용하는데 어려움이 있습니다."
|
|
|
|
#~ msgid ""
|
|
#~ "Once we get to traits and generics, we'll be able to use the [`std::"
|
|
#~ "convert::AsRef`](https://doc.rust-lang.org/std/convert/trait.AsRef.html) "
|
|
#~ "trait to abstract over anything that can be referenced as a slice."
|
|
#~ msgstr ""
|
|
#~ "트레잇나 제네릭을 다루고 나면 [`std::convert::AsRef`](https://doc.rust-"
|
|
#~ "lang.org/std/convert/trait.AsRef.html) 트레잇을 사용하여 슬라이스처럼 사용"
|
|
#~ "될 수 있는 타입을 추상화할 수 있습니다."
|
|
|
|
#~ 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 ""
|
|
#~ "또한, 슬라이스 타입은 길이를 포함하지 않기 때문에 한 단계 아래의 슬라이스"
|
|
#~ "들이 같은 길이임을 보장할 수 없습니다. 때문에 슬라이스 타입의 변수에는 잘"
|
|
#~ "못된 행렬이 전달될 수 있습니다."
|
|
|
|
#~ msgid "Day 1 Afternoon Exercises"
|
|
#~ msgstr "1일차 오후 연습문제"
|
|
|
|
#~ msgid "Designing a Library"
|
|
#~ msgstr "도서관 설계"
|
|
|
|
#~ msgid "Day 2 Morning Exercises"
|
|
#~ msgstr "2일차 오전 연습문제"
|
|
|
|
#~ msgid "Day 2 Afternoon Exercises"
|
|
#~ msgstr "2일차 오후 연습문제"
|
|
|
|
#~ msgid "Day 3 Morning Exercise"
|
|
#~ msgstr "3일차 오전 연습문제"
|
|
|
|
#~ msgid "Day 3 Afternoon Exercises"
|
|
#~ msgstr "3일차 오후 연습문제"
|
|
|
|
#~ msgid "\"127.0.0.1:6142\""
|
|
#~ msgstr "'127.0.0.1:6142'"
|