제네릭을 활용하는 타입, 함수, 메서드를 직접 선언하는 방법을 살펴보자. 함수로부터 중복 제거하기 먼저 제네릭 타입을 사용하지 않고 함수로부터 중복된 코드를 제거하는 방법을 알아보자. fn main() { let number_list = vec![34, 50, 25, 100, 65]; let mut largest = number_list[0]; for number in number_list { if number > largest { largest = number; } } println!("가장 큰 숫자: {}", largest); } 두 개의 리스트에서 가장 큰 값을 찾으려면 위 예제를 복사하여 두번 실행 하면 된다. 이런 중복 코드를 없애려면 정수의 리스트를 매개변수로 전달받아 작업을 실행하는 함수를 ..
시작하며 러스트는 에러를 크게 회복 가능한(recoverable) 에러와 회복이 불가능한(unrecoverable) 에러 두가지로 구분한다. 러스트에는 예외라는 개념이 없고, 회복 가능한 에러를 표현하는 Result 타입과 회복 불가능한 에러가 프로그램의 실행을 종료하는 panic! 매크로를 지원한다. panic! 매크로를 이용한 회복 불가능한 에러 처리 panic! 매크로를 실행하면 프로그램은 실패 메시지를 출력하고 스택을 모두 정리한 다음 종료한다. fn main() { panic = 'abort' } 에러 메시지에는 패닉 메시지와 패닉이 발생한 소스 코드의 위치가 출력된다. panic! 역추적 사용하기 범위를 벗어난 인덱스를 이용해 panic! 매크로 호출해보자 책에서는 작성한 파일이 아닌 mod...
시작하며 이번 장에서는 자주 사용되는 벡터, 문자열, 해시맵 세 가지 컬렉션을 알아보자 벡터에 일련의 값 저장하기 벡터는 하나 이상의 값을 하나의 데이터 구조에 담을수 있으며 모든 값은 메모리상에 연속으로 저장된다. 벡터는 같은 타입의 값만 저장할 수 있다. 새로운 벡터 생성하기 새로운 빈 벡터를 생성하려면 Vec::new 함수를 호출하면 된다. let v: Vec = Vec::new(); //값을 포함하는 벡터 생성 Vec 타입으로 유추 let v2 = vec![1,2,3]; 벡터 수정 벡터를 생성하고 값을 추가하려면 push 메서드를 사용한다. let mut v = Vec::new(); v.push(5); v.push(6); v.push(7); v.push(8); 벡터 해제 벡터 역시 범위를 벗어날 ..
패키지: 크레이트를 빌드, 테스트, 공유할 수 있는 카고의 기능 크레이트: 라이브러리나 실행 파일을 생성하는 모듈의 트리(tree) 모듈과 use: 코드의 구조와 범위, 그리고 경로의 접근성을 제어하는 기능 경로(path): 구조체, 함수, 혹은 모듈 등의 이름을 결정하는 방식 패키지와 크레이트 크레이트는 하나의 바이너리 혹은 라이브러리다. 크레이트 루트(root)는 러스트 컴파일러가 컴파일을 시작해서 크레이트의 루트 모듈을 만들어내는 소스 파일이다. 패키지는 이 크레이트를 빌드하는 방법을 서술하는 Cargo.toml 파일을 갖는다. 패키지를 생성하게되면 (cargo new 명령) 카고는 Cargo.toml 파일을 생성해 패키지를 만들어 낸다. 모듈을 이용한 범위와 접근성 제어 모듈(module)은 크레..
열거자(enumerations, enums)는 사용 가능한 값만 나열한 타입을 정의할 때 사용한다. 열거자 정의하기 IP주소를 예를 들어 보자. IP주소는 버전 4나 버전 6으로 두 가지가 표준으로 자리 잡고 있다. enum IpAddrKind { V4, V6, } 열거된 값들을 열것값(variants)라고 한다. 열거자의 값 let four = IpAddrKind::V4; let six = IpAddrKind::V6; fn route(ip_type: IpAddrKind) {} route(IpAddrKind::V4); route(six); 열거자의 각 값은 식별자를 이용해 구분하며, 식별자와 값을 구분하기 위해 두 개의 콜론을 사용한다. 열거자를 매개변수로 갖는 함수를 정의할수도 있고, 열거자의 값을 이..
구조체(struct or structure)는 서로 관련이 있는 여러값을 의미 있는 하나로 모으고 이름을 지정해 접근할 수 있는 사용자 정의 데이터 타입이다. 구조체 정의와 인스턴스 생성 구조체를 정의하려면 struct 키워드 다음에 구조체에 부여할 이름을 지정해주면 된다. 이후 중괄호 안에 구조체가 저장할 데이터의 타입과 이름을 나열한다. 이 데이터들을 필드(field)라고 한다. 구조체를 정의한 후 이를 사용하려면 각 필드에 저장할 값을 명시에서 구조체의 인스턴스를 생성해야 한다. 정의 순서와 같을 필요는 없다. 구조체에서 원하는 값을 읽으려면 마침표(.)를 이용하면 된다. struct User { username: String, email: String, sign_in_count: u64, acti..
소유권이란? 러스트는 다른 언어들과 달리 가비지 콜렉터를 사용하거나, 명시적 메모리 할당 해제 하는 방법으로 메모리를 관리하지 않는다. 소유권 규칙 러스트가 다루는 각각의 값은 소유자(owner)라고 부르는 변수를 가지고 있다. 특정 시점에 값의 소유자는 단 하나뿐이다. 소유자가 범위를 벗어나면 그 값은 제거된다. 변수의 범위 변수의 범위(scope)는 선언된 지점 부터 현재의 범위를 벗어나기 전까지 유효하다. 범위와 변수의 유효성 사이의 관계는 다른 프로그래밍 언어와 크게 다르지 않다. { //변수 s를 아직 선언하지 않았다 let s = "hello"; //변수 s는 이 지점부터 유효 //변수 s를 이용해 필요한 동작을 수행 } //범위를 벗어나므로 변수 s는 이제 유효하지 않음 String 타입 S..
변수와 가변성 기본적으로 변수는 변경이 불가능 하다. 하지만 필요하다면 변수를 변경할 수 있게 선언할 수도 있다. 확인을 위해 variables 라는 프로젝트를 만들자 fn main() { let x = 5; println!("x의 값: {}", x); x = 6; println!("x의 값: {}", x); } 위 코드 작성후 빌드를 실행하면 에러가 발생한다. 에러 메시지를 읽어보면 불변 변수 x에 값을 두번 할당했기 때문이라고 나온다. 변수 이름 앞에 mut 키워드를 추가하면 가변 변수를 선언할 수 있다. fn main() { let mut x = 5; println!("x의 값: {}", x); x = 6; println!("x의 값: {}", x); } 이후 프로그램을 다시 실행하면 다음 결과가 ..
1~100사이의 난수를 생성해서 입력을 받아 입력한 값이 더 큰지 작은지 알려주어 숫자를 맞추는 게임을 구현해보자. 새 프로젝트 셋업하기 책에서는 cargo new 명령어를 통해 새프로젝트를 생성하라고 되어있지만 나는 IntelliJ를 통해 guessing_game 프로젝트를 생성하였다. 플레이어가 예측한 값 처리하기 먼저 플레이어에게 예측한 값을 묻는 코드를 작성해보자 use std::io; fn main() { println!("숫자를 맞혀봅시다!"); println!("정답이라고 생각하는 숫자를 입력하세요."); let mut guess = String::new(); io::stdin().read_line(&mut guess) .expect("입력한 값을 읽지 못했습니다."); println!("입..
시작하며 Rust 언어를 공부하기위해 한국어로 번역된 유일한 책인 이 책을 구매하였다. 그리고 지인의 추천으로 IntelliJ에서 Rust를 사용하고자 한다. 설치 러스트 설치 책을따라 https://www.rust-lang.org/tools/install 주소에 들어가서 rustup을 이용해 러스트를 설치하였다. 설치후 rustc --version 명령어를 통해 버전을 확인하였다. IntelliJ 설치 우선 IntelliJ 부터 설치하자. https://www.jetbrains.com/idea/ 해당 주소에서 커뮤니티 버전을 다운받아 설치하였다. 이제 rust 플러그인을 설치해보자. 플러그인 탭에서 rust를 검색하여 rust 플러그인을 설치하였다. rust 플러그인을 설치하기위해서는 toml 플러그인..
* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.