구조체에 대해서 설명할려고 합니다.
구조체는 항상 대문자로 시작되는 변수을 제공해야합니다.
러스트에서는 배열을 가지고 있습니다. 정적이거나 동적일 수 있습니다.
또한 러스트에서는 변수로 부르지 않고 바인딩이라고 부릅니다.
Dec가 새 바인딩을 선언하고 이를 변수라고 합니다.
이 타입 어노테이션은 이 바인딩이 참조할 값의 유형을 rust에 알려줍니다.
따라서 여기에 콜론 데크를 선택적으로 입력할 수 있습니다.
그러면 컴파일러가 이 바인딩이 덱 인스턴스를 참조할 것임을 100% 명확하게 알 수 있습니다.
Deck이라는 구조체 작성 후 실행 시켜도록합니다.
--> src/main.rs:8:38
|
8 | println!("Heres your deck : {}", deck);
| ^^^^ `Deck` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `Deck`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
이런 오류가 발생합니다.
rust는 오류에 대해서 명확하게 알려줍니다. 문제를 해결하기 위해 무엇을 해야 하는지 정확히 알려주고 있습니다.
오류에서 중괄호인 서식 지정 자리 표시지가 문자열 내부의 문자열 내부에 포맷터가 필요하다는 것을 알려줍니다.
note 부분에 콜론 물음표 넣으면 문제가 해결 된다고 하지만 ":?" 넣어 지만 해결이 안되는 모습을 볼 수 있습니다.
":? "은 뜻하는거는 포맷터 라고 합니다.
어떤 값을 인쇄하는 방식을 사용자가 지정할 수 있습니다.
디버그 포맷터라고 합니다.
note: add `#[derive(Debug)]` to `Deck` or manually `impl Debug for Deck`
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
위 그림과 같이 #[derive(Debug)] 입력하면 오류가 사라진것을 볼 수 있습니다. 해당 오류는 Deck 구조체을 사용하지 않아서 삭제하라는 의미라고 생각 됩니다.
#[derive(Debug)]에 대해서 자세히 알려드리겠습니다.
#[derive(Debug)] 전체 문장은 몇 가지 속성 또는 속성 목록을 정의하는 것으로 어트리뷰트 또는 어튜리뷰트 목록을 정의하는 것 입니다. 이 구조체를 처리하는 방법에 대해 추가 지침을 러스트 컴파일러에 제공합니다.
derive attribute는 나머지 컴파일러에게 이 특정 구조체에 대해 몇 가지 추가 기능을 추가하도록 함수를 추가할 것을 나머지 컴파일러에 알려 줍니다.
다음에 벡터와 배열 차이점에 대해서 이야기 하겠습니다.
배열은 크기가 정해진 정적이고 벡터는 크기가 동적으로 변경 될 수 있습니다.
#[derive(Debug)]
struct Deck {
cards:Vec<String>,
}
fn main() {
let suits = ["Hearts" , "Spades", "Diamonds"];
let values = ["Ace","Two","Three"];
let cards = vec![];
for suit in suits{
for value in values {
let card = format!("{} of {} ", value, suit);
cards.push(card)
}
}
let deck = Deck { cards: vec![]};
println!("Heres your deck : {:?}", deck);
}
카드 값을 출력하는 부분을 추가 했습니다. 그리고 cards 라는 빈 벡터을 만들고 빈 벡터 push. 할려고 합니다.
요기서 오류가 발생합니다.
" cannot mutate immutable variable `cards`"
위에 와 같은 오류가 발생합니다.
Rust에서 변수는 기본적으로 불변이므로 다른 많은 프로그래밍 언어와 매우 다릅니다.
불변이란 변수가 변경될 수 없다는 뜻입니다. 이것이 바로 러스트에서 실제로 변수를 변수라고 부르지 않고 바인딩이라고 부르는 이유 입니다.
따라서 바인딩은 기본적으로 불변이라고 말하는 것이 조금 더 정확할 것 입니다.
왼쪽에 표에 numbers 바인딩 빈 벡터로 바인딩 한것을 볼 수 있습니다. 해당 벡터에 새로운 요소를 추가하려고 시도하여 숫자에 할당된 값을 변경할 수 없습니다. 또한 새로운 값으로 숫자를 재할당하는 것도 허용되지 않는다는 것입니다.
불변 데이터는 경우 mut 키워드 없이 바인딩하고
가변 데이터는 경우 mut 키워드 추가 해서 바인딩 해야 합니다.
#[derive(Debug)]
struct Deck {
cards:Vec<String>,
}
fn main() {
let suits = ["Hearts" , "Spades", "Diamonds"];
let values = ["Ace","Two","Three"];
let mut cards = vec![];
for suit in suits{
for value in values {
let card = format!("{} of {} ", value, suit);
cards.push(card)
}
}
let deck = Deck { cards: cards};
println!("Heres your deck : {:?}", deck);
}
위에 코드을 동작 시키면 아래와 같은 출력값이 나옵니다. 하지만 보기에는 힘들어 수정 작업이 필요합니다.
Heres your deck : Deck { cards: ["Ace of Hearts ", "Two of Hearts ", "Three of Hearts ", "Ace of Spades ", "Two of Spades ", "Three of Spades ", "Ace of Diamonds ", "Two of Diamonds ", "Three of Diamonds "] }
println!("Heres your deck : {:#?}", deck);
#을 추가하며 출력값을 보기 좋게 할 수 있습니다.
Heres your deck : Deck {
cards: [
"Ace of Hearts ",
"Two of Hearts ",
"Three of Hearts ",
"Ace of Spades ",
"Two of Spades ",
"Three of Spades ",
"Ace of Diamonds ",
"Two of Diamonds ",
"Three of Diamonds ",
],
}
아래 소스 코드에서는 "self" 라는 키워드가 있습니다.
self는 부모 구현 블록에 언급된 모든 유형에 대한 참조와 같습니다.
따라서 self는 바로 여기에 있는 모든 것을 반환하겠다고 말하는 것으로 생각할 수 있습니다.
따라서 이 경우에는 덱이 될 것입니다.
이렇게 Deck을 넣는 대신 self를 사용하는 이유는 바로 이 때문입니다.
나중에 속성과 구현에 대해 이야기할 때 self를 사용하는 이유에 대해 설명해드리겠습니다.
이 어노테이션은 새 데이터에서 어떤 종류의 데이터를 반환할지 rust에게 알려줍니다.
이 경우 우리는 self를 반환할 것이고, 이는 실제로 Deck을 반환한다는 것을 의미합니다.
impl 구현 하기 위해서는 구조체와 같은 이름을 가지게 될 것 입니다.
함수를 정의할 것이며, 이 함수는 동일한 구현 블록 내에서 정의할 수 있습니다.
따라서 이 구현 블록을 사용하여 메서드와 연관 함수를 정의할 수 있습니다.
연관 함수는 무엇인가요?
이것은 거의 모든 다른 언어에서 클래스 메서드와 동일합니다.
따라서 클래스 메서드에 익숙하다면 연관 함수와 같은 개념입니다.
#[derive(Debug)]
struct Deck {
cards:Vec<String>,
}
impl Deck {
fn new() -> Self {
let suits = ["Hearts" , "Spades", "Diamonds"];
let values = ["Ace","Two","Three"];
let mut cards = vec![];
for suit in suits{
for value in values {
let card = format!("{} of {} ", value, suit);
cards.push(card)
}
}
let deck = Deck { cards: cards};
return deck;
}
}
fn main() {
let deck = Deck::new();
println!("Heres your deck : {:#?}", deck);
}
위에 코드 처럼 기능을 단위로 분리해서 처리 할 수 있습니다. 자세한 내용을 다음 파트에서 알려드리겠습니다.
'블럭체인 > rust' 카테고리의 다른 글
rust - 카드 놀이 _ 2 (1) | 2024.11.18 |
---|---|
rust - 카드놀이 초기 설정 (0) | 2024.11.15 |
rust - 설치 (0) | 2024.11.15 |