-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
195 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# 러스트의 메서드와 연관함수 | ||
|
||
구조체 내에 정의되는 함수 | ||
|
||
첫번째 파라미터는 언제나 `self`이다. (파이썬 같다.) | ||
|
||
`self`는 메서드가 호출되는 구조체의 인스턴스를 가리킨다. | ||
|
||
## 메서드 정의하기 | ||
|
||
사각형을 나타내는 `Rectangle` 구조체가 있다. | ||
|
||
```rust | ||
struct Rectangle { | ||
length: u32, | ||
width: u32, | ||
} | ||
``` | ||
|
||
이 구조체의 넓이를 구하는 `area` 메서드를 만든다. | ||
|
||
```rust | ||
impl Rectangle { | ||
fn area(&self) -> u32 { | ||
self.length * self.width | ||
} | ||
} | ||
``` | ||
|
||
`impl` 키워드를 사용해서 메서드를 정의한다. | ||
|
||
`&self` 파라미터로 구조체 인스턴스 소유권을 빌려서 사용한다. | ||
|
||
> 메서드가 `self`의 타입을 가진 덕분에 참조 및 역참조가 자동으로 동작한다. 덕분에 C++ 처럼 `->` 연산자를 사용할 필요 없다. | ||
## 연관함수 | ||
|
||
`impl` 블록 내에 `self` 파라미터를 갖지 않는 함수도 정의할 수 있다. | ||
|
||
함수가 동작할 때 구조체 인스턴스가 필요없지만 해당 구조체와 관련이 있어서 연관함수라고 불린다. | ||
|
||
연관함수는 `String::from` 같이 새 구조체 인스턴스를 반환하는 생성자로 많이 쓴다. | ||
|
||
정사각형 `Rectangle`을 만들 때 아래와 같이 연관함수를 만들어두면 편하다. | ||
|
||
```rust | ||
impl Rectangle { | ||
fn square(size: u32) -> Rectangle { | ||
Rectangle { length: size, width: size } | ||
} | ||
} | ||
``` | ||
|
||
사용은 `let sq = Rectangle::square(3);` 같이 구조체::함수 형태이다. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
# 러스트의 구조체 | ||
|
||
연관된 여러 값을 묶어서 의미있는 데이터 단위 정의한다. | ||
|
||
## 구조체 만들기 | ||
|
||
`struct` 키워드와 필드, 타입을 입력하면 구조체를 만들 수 있다. | ||
|
||
아래는 사용자 계정 정보를 저장하는 구조체 | ||
|
||
```rust | ||
struct User { | ||
username: String, | ||
email: String, | ||
sign_in_count: u64, | ||
active: bool, | ||
} | ||
``` | ||
|
||
## 구조체 사용하기 | ||
|
||
각 필드 값을 입력한 인스턴스를 만들어서 사용한다. | ||
|
||
```rust | ||
let user1 = User { | ||
email: String::from("[email protected]"), | ||
username: String::from("someusername123"), | ||
active: true, | ||
sign_in_count: 1, | ||
}; | ||
``` | ||
|
||
## 필드 초기화 축약 | ||
|
||
변수명과 구조체의 필드명이 같으면 축약해서 필드를 초기화할 수 있다. | ||
|
||
아래 코드에서 매개변수와 구조체 필드명이 `email`과 `username`로 같아서 축약 초기화를 했다. | ||
|
||
```rust | ||
fn build_user(email: String, username: String) -> User { | ||
User { | ||
email, | ||
username, | ||
active: true, | ||
sign_in_count: 1, | ||
} | ||
} | ||
``` | ||
|
||
ES6의 객체 리터럴 축약 표기와 같다. | ||
|
||
## 기존 구조체 인스턴스 재활용해서 새 구조체 인스턴스 만들기 | ||
|
||
`user2`는 `email`과 `username` 필드에는 새 값을 할당하고 | ||
|
||
나머지 필드는 `user1`에서 재사용했다. | ||
|
||
```rust | ||
let user2 = User { | ||
email: String::from("[email protected]"), | ||
username: String::from("anotherusername567"), | ||
..user1 | ||
}; | ||
``` | ||
|
||
ES6의 객체 전개와 같다. | ||
|
||
## 필드 이름이 없는 튜플 구조체 | ||
|
||
```rust | ||
struct Color(i32, i32, i32); | ||
struct Point(i32, i32, i32); | ||
|
||
let black = Color(0, 0, 0); | ||
let origin = Point(0, 0, 0); | ||
``` | ||
|
||
`black`과 `origin`은 구조체 내 타입이 모두 동일해도 서로 다른 타입이다. | ||
|
||
## 필드가 없는 유사 유닛 구조체 | ||
|
||
유닛 타입인 `()`와 비슷하다. | ||
|
||
필드가 없다. | ||
|
||
특정한 타입의 트레잇(Trait)을 구현해야 되는데 타입 자체에 데이터를 저장하지 않고 싶을 때 유용하다. | ||
|
||
## 구조체 출력하기 | ||
|
||
```rust | ||
struct Rectangle { | ||
length: u32, | ||
width: u32, | ||
} | ||
``` | ||
|
||
이 구조체를 출력하려고 할 때 | ||
|
||
```rust | ||
fn main() { | ||
let rect1 = Rectangle { length: 50, width: 30 }; | ||
|
||
println!("rect1 is {}", rect1); | ||
} | ||
``` | ||
|
||
`println!`에 `{}`만 사용하면 `Rectangle`의 기본 포맷터가 없다고 에러가 나고 | ||
|
||
`Debug`라는 출력포맷을 사용하겠다는 뜻을 나타내는 `{:?}`를 사용하라고 한다. | ||
|
||
```rust | ||
println!("rect1 is {:?}", rect1); | ||
``` | ||
|
||
위와 같이 `{:?}`을 사용하면 에러가 나면서 | ||
`#[derive(Debug)]`어노테이션을 구조체 정의 앞에 붙이라고 한다. | ||
|
||
```rust | ||
#[derive(Debug)] | ||
struct Rectangle { | ||
length: u32, | ||
width: u32, | ||
} | ||
``` | ||
|
||
어노테이션을 붙이면 출력이 잘 된다. | ||
|
||
``` | ||
rect1 is Rectangle { length: 50, width: 30 } | ||
``` | ||
|
||
`{:?}` 대신에 `{:#?}`를 사용하면 아래와 같이 보기 좋게 구조체를 출력해줘서 큰 구조체를 디버깅할 때 도움이 된다. | ||
|
||
``` | ||
rect1 is Rectangle { | ||
length: 50, | ||
width: 30 | ||
} | ||
``` |