구조체를 이용한 예제 프로그램
앞에서 공부한 구조체를 예제를 통해서 이해해 보자.
사각형의 넓이를 계산하는 간단한 프로그램을 작성해 보자.
일단은 먼저, 구조체를 사용하지 말고 변수를 이용해 넓이를 구한 후, 이를 구조체를 사용하는 방법으로 변경해 가도록 하겠다.
fn area(width: u32, length: u32) -> u32 {
width * length
}
fn main() {
let width = 50;
let length = 50;
println!("Square is {}", area(width, length));
}
Compiling rust v0.1.0 (/Users/seunghye/Documents/juneun/rust)
Finished dev [unoptimized + debuginfo] target(s) in 0.35s
Running `target/debug/rust`
Square is 2500
사각형의 넓이를 구하는 방법은 잘 알다시피, (가로 * 세로) 를 해 주면 된다.
이 공식이 기억나지 않는다면 초등학교를 다시 방문해 보도록 하자.
코드에서는 임의로 50 * 50으로 정해 주었고, area() 함수를 통해 넓이를 리턴해 주도록 했다.cargo run으로 실행 해 보니 다행이 2500을 출력 하며 계산이 잘 된 것을 확인할 수 있었다.
그럼 이제 구조체를 만들어 보자
struct Rectangle {
length: u32,
width: u32,
}
Rectangle이라는 구조체를 정의해 주었다.
이 구조체는 필드값으로 length와 witdh를 갖는다.
그럼 이제 이 구조체를 이용해 사각형의 넓이를 구해보자.
struct Rectangle {
length: u32,
width: u32,
}
fn area(width: u32, length: u32) -> u32 {
width * length
}
fn main() {
let rectangle = Rectangle {
length: 50,
width: 50
};
println!("Square is {}", area(rectangle.width, rectangle.length));
}
Compiling rust v0.1.0 (/Users/seunghye/Documents/juneun/rust)
Finished dev [unoptimized + debuginfo] target(s) in 0.68s
Running `target/debug/rust`
Square is 2500
구조체만 이용했을 뿐 앞의 코드와 달라진 점은 없다.
길이와 넓이 모두 50으로 아까와 동일하기 때문에 넓이도 2500으로 출력 되었다.
그런데 구조체는 하나인데, area() 함수의 인자를 두개나 쓸 필요는 없을 것 같다.
그리고 우리는 이 구조체의 인스턴스를 함수가 호출된 이후에도 계속 쓰기를 원한다.
이럴 때는 소유권을 넘겨주는게 아닌 빌려주는게 좋다.
이런 부분들을 수정해 훨씬 우아하게 코드를 작성해 보자.
fn area(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.length
}
fn main() {
let rectangle = Rectangle {
length: 50,
width: 50
};
println!("Square is {}", area(&rectangle));
}
이전의 코드보다 훨씬 이뻐졌다.
힘들게 함수의 인자를 두개나 넣어줄 필요도 없어졌고, area()를 호출한 이후에도 구조체를 이용할 수 있게 되었다.
파생 트레잇 (deviced trait)로 쉽게 디버깅하기
지금은 간단한 구조체이기 때문에 파악이 쉬웠는데, 만약 복잡한 프로그램에서의 복잡한 구조체였다면 디버깅하기 쉽지 않았을 것이다.
러스트는 쉽고 빠른 디버깅을 지원하기 위해 인스턴스를 그대로 출력하는 기능을 지원한다.
그러기 위해선 트레잇 이라는 기능을 이용해야 한다.트레잇은 나중에 더 자세하게 배우니까 지금은 일종의 추상화 기능이라고 이해하고 넘어가자.
일단 코드를 먼저 보고 이해해 보도록 하자.
#[derive(Debug)]
struct Rectangle {
length: u32,
width: u32,
}
fn area(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.length
}
fn main() {
let rectangle = Rectangle {
length: 50,
width: 50
};
println!("Square is {:?}", rectangle);
}
Square is Rectangle { length: 50, width: 50 }
#[derive(Debug)]구조체를println!()에서 출력할 수 있게 해주는어노테이션이다Debug라는 트레잇을 구조체에서 사용하겠다고 컴파일러에게 알려주는 부분이다
{:?}println 매크로에서 디버스 포맷팅을 출력하기 위한 명시자
만약 구조체를 출력할 때 선언한 것 그대로 출력하고 싶으면, {:#?} 를 사용하면 된다.
이렇게 이쁘게 출력된다.
Square is Rectangle {
length: 50,
width: 50,
}
이제 슬슬 러스트에서 새로운 부분들이 등장하고 있다.
위에서 작성한 코드 조차도 최적의 코드는 아니다.
러스트에는 더 우아하게 코드를 작성할 수 있는 방법들이 있다.
다음 공부에선 이런 방법에 대해 알아보도록 하자.
'⚙️ Rust > 👀 Tutorial' 카테고리의 다른 글
| [Rust / 튜토리얼] 13. 러스트의 열거형과 Option, None 그리고 Some (0) | 2022.06.03 |
|---|---|
| [Rust / 튜토리얼] 13. 러스트의 메소드. (0) | 2022.06.01 |
| [Rust / 튜토리얼] 11. 러스트에서 구조체를 정의하고 생성하기 (0) | 2022.05.27 |
| [Rust / 튜토리얼] 10. 러스트의 슬라이스 (slice) (0) | 2022.05.25 |
| [Rust / 튜토리얼] 9. 러스트의 참조자와 빌림 (0) | 2022.05.23 |