Penflip

Penflip - Write better with others

  • Loading...
  • Discover Projects
  • Help
  • Signup
  • Login
  • Welcome back!
    No account? Signup Close
    Ready to write better?
    Have an account? Login Close

sarojaba · Rust Doc Korean

Make Changes
46

5.17. 문자열(Strings) - 100%

문자열은 어느 프로그래머이든 마스터가 되기위한 중요한 개념입니다. Rust의 문자열 처리 시스템은 시스템 focus 때문에 다른 언어들과 좀 다릅니다. 언제라도 여러분은 다양한 크기의 자료 구조를 가집니다. 문자열은 약간 어려운 부분도 있지만, 크기 조절이 가능한 자료 구조입니다. 한마디로, Rust의 문자열 또한 C와 같은 다른 시스템 언어들과는 다르게 동작한다는 것입니다.

좀 더 자세히 파봅시다. ‘문자열(string)’은 UTF-8 바이트의 스트림으로 부호화된 유니코드 스칼라 값의 나열입니다. 모든 문자열은 올바르게 부호화된 UTF-8 나열이라는 것을 보장합니다. 게다가, 몇몇 시스템 언어들과 다르게 문자열은 null로 끝나지 않고 null 바이트를 포함할 수 있습니다.

Rust에는 두가지 주요 문자열 타입이 있습니다: &str 과 String 입니다. 우선 &str에 대해 이야기 해볼까요? 이것들은 ‘문자열 슬라이스(string slice)’라고 부릅니다. 문자열 리터럴은 &'static str 타입을 가집니다:

let greeting = "Hello there."; // greeting: &'static str

이 문자열은 정적으로 할당되며, 이것이 의미하는 바는 이것이 컴파일된 프로그램 안에 저장되어 있고, 프로그램이 실행되는 내내 존재한다는 뜻입니다. greeting 바인딩은 정적으로 할당된 문자열에 대한 참조입니다. 문자열 슬라이스는 고정된 크기를 가지며, 변경될 수 없습니다.

반면에, String은 힙에 할당된 문자열입니다. 이 문자열은 크기가 커질 수 있고, UTF-8 인코딩임이 보장됩니다. String들은 일반적으로 문자열 슬라이스를 to_string 메쏘드를 사용해서 변환함으로써 만들어집니다.

let mut s = "Hello".to_string(); // mut s: String
println!("{}", s);

s.push_str(", world.");
println!("{}", s);

String을 강제적으로 &str로서 사용할 때는(coerce) 그 앞에 &을 붙입니다.

fn takes_slice(slice: &str) {
    println!("Got: {}", slice);
}

fn main() {
    let s = "Hello".to_string();
    takes_slice(&s);
}

이러한 강제(coercion)은 &str 대신에 &str의 traits 중 하나를 받는 함수에 대해서는 발생하지 않습니다. 예로 <code>TcpStream::connect</code>는 ToSocketAddrs type의 인자를 가집니다. &str는 인자로서 허용되나, String은 반드시 명시적으로 &*를 사용해서 변환해주어야 합니다.

use std::net::TcpStream;

TcpStream::connect("192.168.0.1:3000"); // &str parameter

let addr_string = "192.168.0.1:3000".to_string();
TcpStream::connect(&*addr_string); // convert addr_string to &str

String을 &str로서 다루는 것은 비용이 적지만, &str을 String로 변환하는 것은 메모리 할당을 필요로 합니다. 그럴 이유가 없다면 그렇게 하지 마시기를!

인덱싱

문자열들은 유효한 UTF-8로 인코딩되었기 때문에, 문자열들은 그 안의 문자들에 대해 인덱싱을 통한 접근을 지원하지 않습니다.

let s = "hello";

println!("The first letter of s is {}", s[0]); // ERROR!!!

일반적으로, []을 통해 벡터에 접근하는 것은 아주 빠릅니다. 그러나, UTF-8로 인코딩된 문자열 안에 있는 각각의 문자들은 각각 서로 다른 길이의 바이트들로 이루어져 있기 때문에, 문자열 안의 n번째 문자를 찾기 위해서는 맨 처음부터 순서대로 탐색해 나가지 않으면 안됩니다. 이것은 상당히 비싼 동작이고, 우리는 이것이 오해를 불러 일으키기를 원치 않았습니다. 더욱이, '문자'가 정확히 무엇인지는 유니코드에서 제대로 정의되어 있지 않습니다. 우리는 문자열이 각각의 바이트들로서 보일 것인지, 혹은 codepoint로 보일 것인지 선택할 수 있습니다:

let hachiko = "忠犬ハチ公";

for b in hachiko.as_bytes() {
    print!("{}, ", b);
}

println!("");

for c in hachiko.chars() {
    print!("{}, ", c);
}

println!("");

이것은 다음을 출력합니다:

229, 191, 160, 231, 138, 172, 227, 131, 143, 227, 131, 129, 229, 133, 172, 
忠, 犬, ハ, チ, 公, 

지금 보고 있는대로, char의 갯수보다는 많은 바이트(byte)들이 있습니다.

인덱스를 통한 참조와 비슷한 동작을 하고 싶다면 이렇게 하십시오:

# let hachiko = "忠犬ハチ公";
let dog = hachiko.chars().nth(1); // kinda like hachiko[1]

이것은 chars들의 리스트의 처음부터 살펴봐야 함을 강조해 줍니다.

Slicing

slicing 문법을 가지고 string의 slice를 얻을 수 있습니다.:

let dog = "hachiko";
let hachi = &dog[0..5];

허나 이것들은 byte offsets 이지 character offsets이 아닙니다. 그래서 위 코드는 compile-time에서는 문제가 없지만 runtime에서는 에러를 발생시킵니다.

let dog = "忠犬ハチ公";
let hachi = &dog[0..2];

다음과 같은 에러를 수반합니다:

thread '<main>' panicked at 'index 0 and/or 2 in `忠犬ハチ公` do not lie on
character boundary'

문자열 연결(Concatenation)

String에 대해, 그 뒤에 &str을 연결할 수 있습니다:

let hello = "Hello ".to_string();
let world = "world!";

let hello_world = hello + world;

그러나 두개의 String이 있을 땐, &가 필요합니다:

let hello = "Hello ".to_string();
let world = "world!".to_string();

let hello_world = hello + &world;

이것은 &String가 자동적으로 &str이 되도록 강제(coerce)되기 때문입니다. 이것은 ‘<code>Deref</code> coercions’로 불리는 특징입니다.

Updated by AinL over 3 years (view history)
5.16. 벡터 (Vectors) - 100% 5.18. 제너릭 (Generics) - 100%

Contents

    Rust 문서 한글화 프로젝트 1. 소개(Introduction) - 1.10.0 2. 시작하기(Getting Started) - 100% 3. Rust 배우기 (Learn Rust) - 100% 3.1. 추리 게임 (Guessing Game) - 100% 3.2. 식사하는 철학자들 (Dining Philosophers) - 100% 3.3. 다른 언어에 Rust 포함하기 (Rust Inside Other Languages) - 100% 4. 효과적인 Rust (Effective Rust) - 100% 4.1. 스택과 힙 (The Stack and the Heap) - 100% 4.2. 테스팅 (Testing) - 100% 4.3. 조건부 컴파일 (Conditional Compilation) - 70% 4.4. 문서화 (Documentation) - 20% 4.5. 반복자 (Iterators) - 100% 4.6. 동시성 (Concurrency) - 90% 4.7. 오류 처리 (Error Handling) - 4% 4.8. Choosing your Guarantees - 0% 4.9. 외부 함수 인터페이스 (Foreign Function Interface) - 50% 4.9. Borrow 와 AsRef 4.11. 배포 채널 (Release Channels) - 100% 5. 문법과 의미 (Syntax and Semantics) - 100% 5.1. 변수 바인딩 (Variable Bindings) - 100% 5.2. 함수 (Functions) - 100% 5.3. 기본형 (Primitive Types) - 100% 5.4. 주석 (Comments) - 100% 5.5. 조건식 (if) - 100% 5.6. 반복 (Loops) - 100% 5.7. 소유권 (Ownership) - 100% 5.8. 참조와 빌림 (References and Borrowing) - 100% 5.9. 수명 (Lifetimes) - 100% 5.10. 가변성 (Mutability) - 100% 5.11. 구조체 (Structs) - 100% 5.12. 열거형 (Enums) - 100% 5.13. 정합 (Match) - 100% 5.14. 패턴 (Patterns) - 80% 5.15. 메소드 문법 (Method Syntax) - 100% 5.16. 벡터 (Vectors) - 100% 5.17. 문자열(Strings) - 100% 5.18. 제너릭 (Generics) - 100% 5.19. 트레잇 (Traits) - 100% 5.20. 드랍 (Drop) - 100% 5.21. if let - 100% 5.22. 트레잇 객체 (Trait Objects) - 75% 5.23. 클로저 (Closures) - 10% 5.24. 전역 함수 사용법 (Universal Function Call Syntax) - 0% 5.25. 크레이트들과(Crate) 모듈들(Module) - 0% 9. 용어 색인 (Concordance) Show all
    Discussions 5 Pending changes 5 Contributors
    Download Share

    Download

    Working...

    Downloading...

    Downloaded!

    Download more

    Error!

    Your download couldn't be processed. Check for abnormalities and incorrect syntax. We've been notified of the issue.

    Back

    Download PDF Download ePub Download HTML Download Word doc Download text Download source (archive)

    Close
566 Words
3,581 Characters

Share

Collaborators make changes on their own versions, and all changes will be approved before merged into the main version.

Close

Penflip is made by Loren Burton
in Los Angeles, California

Tweet

    About

  • Team
  • Pricing
  • Our Story

    Quick Start

  • Markdown
  • Penflip Basics
  • Working Offline

    Support

  • Help
  • Feedback
  • Terms & Privacy

    Connect

  • Email
  • Twitter