데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      Openlab - 2차 Rust 스터디

      lambda 24.05.02
      143 1 0
      DEVOTEE 요약
      2주차 러스트 스터디에서는 "3장 일반적인 프로그래밍 개념"과 "4장 소유권 이해하기"를 다뤘습니다. 3장에서는 변수, 기본 타입, 함수, 주석, 제어 흐름 등의 기초 개념을 설명했고, 4장에서는 러스트의 고유한 메모리 관리 시스템인 소유권, 참조와 대여, 슬라이스에 대해 다뤘습니다. 이러한 개념들은 러스트 프로그래밍의 기본을 이해하는 데 중요한 역할을 합니다.
      DEVOTEE 추천 블로그

      2주차 스터디 소개

      지난 시간 오리엔테이션 후, 한 주 뒤인 4월 29일 2차 Rust 스터디를 진행 했습니다.

      이번 스터디는 책의 "3장 일반적인 프로그래밍 개념", "4장 소유권 이해하기" 내용을 공유하는 시간이었습니다.



      3장 일반적인 프로그래밍 개념

      이 장에서는 프로그래밍 언어의 공통적인 개념들을 러스트에서 어떻게 구현하는지 설명합니다. 러스트의 고유 개념은 없지만, 러스트의 문맥에서 이러한 개념들을 사용하는 방법과 규칙을 다룹니다. 다루는 주요 내용은 다음과 같습니다:

      1. 변수: 데이터 저장과 접근 방법.

      2. 기본 타입: 숫자, 문자열, 불리언 등 기본 데이터 타입.

      3. 함수: 코드 블록을 모듈화하고 재사용하는 방법.

      4. 주석: 코드 내 설명을 추가하는 방법.

      5. 제어 흐름: 조건문과 반복문을 사용하여 프로그램의 흐름을 제어하는 방법.

      이 기초 개념들은 모든 러스트 프로그램에서 사용되며, 이를 잘 이해하면 러스트 프로그래밍의 강력한 기반을 다질 수 있습니다.

      1. 변수: 데이터 저장과 접근 방법

      변수란 무엇인가?

      변수는 프로그램에서 데이터를 저장하고 접근하는 기본적인 방법입니다. 러스트에서는 변수를 통해 값을 저장하고, 필요할 때 이를 참조할 수 있습니다. 변수는 변하지 않는 값인 불변 변수와 변할 수 있는 값인 가변 변수로 나뉩니다.

      변수 선언하기

      러스트에서 변수를 선언할 때는 let 키워드를 사용합니다.

      let x = 5;

      위 코드에서는 x라는 변수를 선언하고 5라는 값을 할당했습니다. 기본적으로 러스트의 변수는 불변입니다. 값을 변경하려면 mut 키워드를 사용해야 합니다.

      let mut y = 10; y = 20;

      이렇게 mut를 사용하여 y 변수를 가변 변수로 선언하면, 이후에 값을 변경할 수 있습니다.

      변수 접근하기

      변수에 접근하려면 변수 이름을 사용하면 됩니다. 예를 들어, 위에서 선언한 변수 x와 y에 접근하는 방법은 다음과 같습니다.

      println!("x의 값은: {}", x); println!("y의 값은: {}", y);

      2. 기본 타입: 숫자, 문자열, 불리언 등 기본 데이터 타입

      숫자 타입

      러스트는 다양한 숫자 타입을 지원합니다. 정수형에는 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;

      3. 함수: 코드 블록을 모듈화하고 재사용하는 방법

      함수 선언하기

      러스트에서 함수는 fn 키워드를 사용하여 선언합니다. 함수는 이름, 매개변수, 반환 타입을 가질 수 있습니다.

      fn add(a: i32, b: i32) -> i32 {
      	a + b 
      }

      위 함수는 두 개의 정수를 입력받아 더한 값을 반환합니다.

      함수 호출하기

      함수를 호출할 때는 함수 이름과 함께 인수를 전달합니다.

      let result = add(5, 3);
      println!("결과는: {}", result);

      4. 주석: 코드 내 설명을 추가하는 방법

      주석은 코드 내 설명을 추가할 때 사용합니다. 러스트에서는 한 줄 주석과 여러 줄 주석을 지원합니다.

      한 줄 주석

      한 줄 주석은 //를 사용하여 작성합니다.

      // 이 함수는 두 수를 더합니다.
      fn add(a: i32, b: i32) -> i32 {
      	a + b
      }

      여러 줄 주석

      여러 줄 주석은 /* */ 사이에 작성합니다.

      `/* 
      이 함수는 두 수를 더한 결과를 반환합니다. 
      입력: 두 개의 정수 
      출력: 두 수의 합 
      */
      fn add(a: i32, b: i32) -> i32 {
      	a + b
      }

      5. 제어 흐름: 조건문과 반복문을 사용하여 프로그램의 흐름을 제어하는 방법

      조건문

      조건문은 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);
      }

      위와 같은 제어 흐름 구조를 통해 프로그램의 흐름을 제어하고 다양한 로직을 구현할 수 있습니다.


      이러한 기초 개념들은 러스트 프로그래밍을 이해하는 데 중요한 역할을 하며, 이를 잘 익히면 더욱 복잡한 프로그램을 작성하는 데 큰 도움이 됩니다.

      4. 소유권 이해하기

      러스트의 소유권(ownership) 시스템은 메모리 안정성을 보장하는 핵심 기능입니다. 이 시스템은 가비지 컬렉터 없이도 메모리 관리 문제를 해결할 수 있도록 돕습니다. 이번 블로그 글에서는 소유권의 개념과 이를 이해하는 데 필요한 참조와 대여, 슬라이스에 대해 알아보겠습니다.

      4.1. 소유권이 뭔가요?

      소유권은 러스트 프로그램의 메모리 관리법을 지배하는 규칙 모음입니다. 모든 프로그램은 실행 중에 메모리를 관리해야 합니다. 일반적으로 가비지 컬렉션을 사용하거나 프로그래머가 명시적으로 메모리를 할당하고 해제하지만, 러스트는 소유권이라는 시스템을 통해 메모리를 관리합니다.

      소유권의 기본 규칙

      1. 각 값은 단 하나의 소유자(Owner)만 가진다.

      2. 소유자가 스코프를 벗어나면, 값은 메모리에서 해제된다.

      이 규칙 덕분에 러스트는 메모리 누수를 방지할 수 있습니다.

      변수의 스코프

      변수는 선언된 시점부터 스코프를 벗어날 때까지 유효합니다. 예를 들어:

      {
          let s = "hello";
          // s는 여기서 유효합니다
      }
      // 이 스코프를 벗어나면 s는 더 이상 유효하지 않습니다

      String 타입과 힙 메모리

      러스트의 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);
      

      4.2. 참조와 대여

      소유권을 이동시키지 않고 값을 참조하려면 참조자(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!" 출력

      가변 참조는 동시에 하나만 가질 수 있습니다.

      4.3. 슬라이스

      슬라이스는 데이터의 연속된 부분을 참조합니다. 이는 소유권을 가지지 않고 데이터를 참조할 수 있게 해줍니다.

      문자열 슬라이스

      문자열 슬라이스는 &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 출력
      }

      결론

      소유권, 참조와 대여, 슬라이스는 러스트의 메모리 관리 시스템의 핵심 개념입니다. 소유권 시스템은 메모리 누수와 같은 문제를 방지하며, 이를 통해 안전하고 효율적인 코드를 작성할 수 있습니다. 참조와 대여, 슬라이스를 적절히 활용하면 더욱 안정적이고 효율적인 프로그램을 만들 수 있습니다.

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      lambda 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기