23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
지난 시간 오리엔테이션 후, 한 주 뒤인 4월 29일 2차 Rust 스터디를 진행 했습니다.
이번 스터디는 책의 "3장 일반적인 프로그래밍 개념", "4장 소유권 이해하기" 내용을 공유하는 시간이었습니다.
이 장에서는 프로그래밍 언어의 공통적인 개념들을 러스트에서 어떻게 구현하는지 설명합니다. 러스트의 고유 개념은 없지만, 러스트의 문맥에서 이러한 개념들을 사용하는 방법과 규칙을 다룹니다. 다루는 주요 내용은 다음과 같습니다:
변수: 데이터 저장과 접근 방법.
기본 타입: 숫자, 문자열, 불리언 등 기본 데이터 타입.
함수: 코드 블록을 모듈화하고 재사용하는 방법.
주석: 코드 내 설명을 추가하는 방법.
제어 흐름: 조건문과 반복문을 사용하여 프로그램의 흐름을 제어하는 방법.
이 기초 개념들은 모든 러스트 프로그램에서 사용되며, 이를 잘 이해하면 러스트 프로그래밍의 강력한 기반을 다질 수 있습니다.
변수는 프로그램에서 데이터를 저장하고 접근하는 기본적인 방법입니다. 러스트에서는 변수를 통해 값을 저장하고, 필요할 때 이를 참조할 수 있습니다. 변수는 변하지 않는 값인 불변 변수와 변할 수 있는 값인 가변 변수로 나뉩니다.
러스트에서 변수를 선언할 때는 let 키워드를 사용합니다.
let x = 5;위 코드에서는 x라는 변수를 선언하고 5라는 값을 할당했습니다. 기본적으로 러스트의 변수는 불변입니다. 값을 변경하려면 mut 키워드를 사용해야 합니다.
let mut y = 10; y = 20;이렇게 mut를 사용하여 y 변수를 가변 변수로 선언하면, 이후에 값을 변경할 수 있습니다.
변수에 접근하려면 변수 이름을 사용하면 됩니다. 예를 들어, 위에서 선언한 변수 x와 y에 접근하는 방법은 다음과 같습니다.
println!("x의 값은: {}", x); println!("y의 값은: {}", y);러스트는 다양한 숫자 타입을 지원합니다. 정수형에는 i32, u32 등이 있으며, 실수형에는 f32, f64 등이 있습니다.
let int_val: i32 = 10;
let float_val: f64 = 10.5;문자열은 String과 &str 타입으로 나눌 수 있습니다. String은 가변이며 소유권을 가지는 문자열 타입이고, &str은 불변이며 참조형 문자열 타입입니다.
let mut s = String::from("Hello"); s.push_str(", world!");불리언 타입은 bool로, true와 false 값을 가질 수 있습니다.
let is_active: bool = true;러스트에서 함수는 fn 키워드를 사용하여 선언합니다. 함수는 이름, 매개변수, 반환 타입을 가질 수 있습니다.
fn add(a: i32, b: i32) -> i32 {
a + b
}위 함수는 두 개의 정수를 입력받아 더한 값을 반환합니다.
함수를 호출할 때는 함수 이름과 함께 인수를 전달합니다.
let result = add(5, 3);
println!("결과는: {}", result);주석은 코드 내 설명을 추가할 때 사용합니다. 러스트에서는 한 줄 주석과 여러 줄 주석을 지원합니다.
한 줄 주석은 //를 사용하여 작성합니다.
// 이 함수는 두 수를 더합니다.
fn add(a: i32, b: i32) -> i32 {
a + b
}여러 줄 주석은 /* */ 사이에 작성합니다.
`/*
이 함수는 두 수를 더한 결과를 반환합니다.
입력: 두 개의 정수
출력: 두 수의 합
*/
fn add(a: i32, b: i32) -> i32 {
a + b
}조건문은 if, else if, else 키워드를 사용하여 작성합니다.
let number = 5;
if number < 5 {
println!("숫자는 5보다 작습니다.");
} else if number == 5 {
println!("숫자는 5입니다.");
} else {
println!("숫자는 5보다 큽니다.");
}러스트에서는 loop, while, for 반복문을 사용하여 반복 작업을 수행할 수 있습니다.
// loop
let mut counter = 0;
loop {
counter += 1;
if counter == 10 {
break;
}
}
// while
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
// for
let a = [10, 20, 30, 40, 50];
for element in a.iter() {
println!("값은: {}", element);
}위와 같은 제어 흐름 구조를 통해 프로그램의 흐름을 제어하고 다양한 로직을 구현할 수 있습니다.
이러한 기초 개념들은 러스트 프로그래밍을 이해하는 데 중요한 역할을 하며, 이를 잘 익히면 더욱 복잡한 프로그램을 작성하는 데 큰 도움이 됩니다.
러스트의 소유권(ownership) 시스템은 메모리 안정성을 보장하는 핵심 기능입니다. 이 시스템은 가비지 컬렉터 없이도 메모리 관리 문제를 해결할 수 있도록 돕습니다. 이번 블로그 글에서는 소유권의 개념과 이를 이해하는 데 필요한 참조와 대여, 슬라이스에 대해 알아보겠습니다.
소유권은 러스트 프로그램의 메모리 관리법을 지배하는 규칙 모음입니다. 모든 프로그램은 실행 중에 메모리를 관리해야 합니다. 일반적으로 가비지 컬렉션을 사용하거나 프로그래머가 명시적으로 메모리를 할당하고 해제하지만, 러스트는 소유권이라는 시스템을 통해 메모리를 관리합니다.
각 값은 단 하나의 소유자(Owner)만 가진다.
소유자가 스코프를 벗어나면, 값은 메모리에서 해제된다.
이 규칙 덕분에 러스트는 메모리 누수를 방지할 수 있습니다.
변수는 선언된 시점부터 스코프를 벗어날 때까지 유효합니다. 예를 들어:
{
let s = "hello";
// s는 여기서 유효합니다
}
// 이 스코프를 벗어나면 s는 더 이상 유효하지 않습니다러스트의 String 타입은 힙 메모리를 사용합니다. String은 컴파일 타임에 크기를 알 수 없는 데이터를 저장할 수 있습니다. 예를 들어:
let s = String::from("hello");이렇게 생성된 String은 변경할 수 있습니다:
let mut s = String::from("hello");
s.push_str(", world!");
println!("{}", s); // "hello, world!" 출력`변수를 다른 변수에 할당하면 소유권이 이동합니다:
let s1 = String::from("hello");
let s2 = s1;이 경우, s1의 소유권이 s2로 이동하여 s1은 더 이상 유효하지 않습니다. 이를 방지하려면 clone을 사용하여 깊은 복사를 수행할 수 있습니다:
let s1 = String::from("hello");
let s2 = s1.clone();
println!("s1 = {}, s2 = {}", s1, s2);스택에 저장되는 데이터는 복사 시 소유권 이동 없이 사용 가능합니다:
let x = 5;
let y = x;
println!("x = {}, y = {}", x, y);함수에 값을 전달하면 소유권이 이동하거나 복사됩니다. 예를 들어:
fn takes_ownership(some_string: String) {
println!("{}", some_string);
}
fn makes_copy(some_integer: i32) {
println!("{}", some_integer);
}
let s = String::from("hello");
takes_ownership(s);
let x = 5;
makes_copy(x);takes_ownership 함수가 호출된 후 s는 더 이상 유효하지 않지만, makes_copy 함수가 호출된 후에도 x는 유효합니다.
함수의 반환값을 통해 소유권을 반환할 수 있습니다:
fn gives_ownership() -> String {
let some_string = String::from("yours");
some_string
}
fn takes_and_gives_back(a_string: String) -> String {
a_string
}
let s1 = gives_ownership();
let s2 = String::from("hello");
let s3 = takes_and_gives_back(s2);
소유권을 이동시키지 않고 값을 참조하려면 참조자(reference)를 사용합니다. 이는 대여(borrowing)라고 합니다.
불변 참조자는 값을 읽을 수만 있고, 수정할 수 없습니다.
let s1 = String::from("hello");
let s2 = &s1;
println!("{} {}", s1, s2); // 둘 다 사용 가능가변 참조자는 값을 수정할 수 있습니다.
let mut s = String::from("hello");
let s1 = &mut s;
s1.push_str(", world!");
println!("{}", s1); // "hello, world!" 출력가변 참조는 동시에 하나만 가질 수 있습니다.
슬라이스는 데이터의 연속된 부분을 참조합니다. 이는 소유권을 가지지 않고 데이터를 참조할 수 있게 해줍니다.
문자열 슬라이스는 &str 타입을 사용합니다.
let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];
println!("{} {}", hello, world); // "hello world" 출력배열에서도 슬라이스를 사용할 수 있습니다.
let a = [1, 2, 3, 4, 5];
let slice = &a[1..3];
for element in slice.iter() {
println!("{}", element); // 2, 3 출력
}소유권, 참조와 대여, 슬라이스는 러스트의 메모리 관리 시스템의 핵심 개념입니다. 소유권 시스템은 메모리 누수와 같은 문제를 방지하며, 이를 통해 안전하고 효율적인 코드를 작성할 수 있습니다. 참조와 대여, 슬라이스를 적절히 활용하면 더욱 안정적이고 효율적인 프로그램을 만들 수 있습니다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.