녹슨 모듈 소개
main.rs
라는 간단한 동작만으로도 우울한 검색을 할 수 있고 더 많은 문제를 남길 수 있다.본고에서 저는 몇 가지 정보를 공유할 것입니다. 이 정보는 모듈 시스템을 어떻게 더 잘 사용하는지 이해하고 심지어 당신에게 제공하는 기능을 받아들이는 데 도움이 될 것입니다.
왜 직접 파일 경로로 가져오지 않습니까?
나는 이것이 우리 많은 사람들이 먼저 시도한 방법이라고 믿지만, 그것이 작용하지 않을 때, 우리는 실망을 느낀다.
예를 들어, 함수
cat.rs
가 포함된 meow()
라는 파일이 있다고 가정합니다.fn meow() {
println!("Meow, Meow!");
}
그리고 우리는 meow()
에서 main.rs
에게 전화를 걸어 보았다. 이렇게:fn main() {
meow();
}
하지만 Rust는 안 된다고 합니다.error[E0425]: cannot find function `meow` in this scope
--> src/main.rs:2:5
|
2 | meow();
| ^^^^ not found in this scope
그래.우리는 meow()
키워드 공개 pub
를 사용하는 것을 잊어버렸기 때문에, 이 문제를 복구하고 다시 시도할 것입니다.아니오, 같은 잘못이에요.다음 단계에서는 다음을 시도할 수 있습니다.
use cat;
fn main() {
cat::meow();
}
이제 우리는 이 잘못을 얻었다.error[E0432]: unresolved import `cat`
--> src/main.rs:1:5
|
1 | use cat;
| ^^^ no `cat` external crate
위 코드의 오류는 모듈 이름과 디렉터리 구조 사이에 1대1의 맵이 존재한다고 가정하는 데 있습니다.그러나 녹슨 것은 이렇게 일하는 것이 아니다. 녹슨 모듈이 어떻게 작동하는지 이해하는 데 도움을 주는 관건이라고 생각한다.Rust의 모듈 경로가 파일 시스템에 직접 바인딩되지 않았습니다.반면 Rust에 모듈 구조에 대한 정보를 더 알려주어야만
use
코드에 모듈을 만들 수 있습니다.모듈 구조를 파일 시스템 구조에 독립된 것으로 볼 수 있다는 것이다.먼저 Rust 각 파일이 모듈 계층 구조에서 어디에 속하는지 알려주고 파일 시스템 경로 대신'모듈 경로'를 사용하여 모듈을 가져올 수 있습니다.처음에는 귀찮아 보였지만, 왜 이런 식으로 일을 하는지 점차 이해하게 될 것이다.
Rust가 파일 경로만 모듈 경로로 사용하는 것이 아니라는 점을 설명하기 위해 하나의 파일에 여러 모듈을 포함하는 예제
main.rs
를 살펴보겠습니다.mod cat {
pub fn meow() {
crate::dog::woof();
}
}
mod dog {
pub fn woof() {
println!("Woof, Woof!");
}
}
fn main() {
cat::meow();
}
분명히 단독 모듈을 사용해서 이 점을 실현하는 것은 좀 지나치지만, 모듈의 작업 방식을 보여 준다.모든 함수가 다른 모듈에 보일 수 있도록
pub
키워드를 사용해야 합니다. ((pub
키워드를 생략해서 내용을 모듈의 개인 내용으로 설정할 수도 있습니다.)이것은 컴파일될 것이다.우리가 그것을 운행할 때 우리는 다음과 같은 것을 얻을 수 있다.
Woof, Woof!
같은 파일에 있어도 함수 mod cat
가 모듈 경로를 만들었습니다.모듈 자체는 meow()
라는 전역 이름 공간 아래에 끼워 넣었다.이런 방식을 통해 우리는 파일 경로만 사용하는 것보다 다른 모듈 명칭 공간을 유연하게 설명할 수 있다.이런 간단한 예는 불필요하게 복잡하다고 생각할 수 있지만, 라이브러리를 작성하고 API에 좋은 가져오기 구조를 제공하기를 원할 때, 파일 시스템의 정확한 구조와 일치하지 않을 때 매우 좋은 특성입니다.만약 당신이 이렇게 할 수 있는 라이브러리를 사용한 적이 있다면, 이것은 좋은 점 중의 하나입니다.
다른 파일은요?
좋습니다. 한 파일에 여러 모듈을 포함하는 것이 의미가 있기를 바랍니다.다른 파일에서 함수를 가져오는 것은 어떻습니까?
첫 번째 예로 돌아가서
crate
라는 다른 문서에서 use somelib::prelude::*;
라고 성명했다.meow()
에서 변경해야 할 사항은 먼저 Rust에 모듈cat.rs
을 알려주는 것이다.이렇게 하면 Dell
main.rs
에 다음과 같은 내용이 추가됩니다.mod cat;
이것은 Rust가 같은 디렉터리cat
를 찾거나 main.rs
라는 디렉터리에서 cat.rs
파일을 찾지만 cat
파일과 mod.rs
디렉터리를 동시에 가지고 있을 수 없음을 알려준다.우리는 곧 목록에 도착할 것이다.우리의 예에서 우리는 같은 디렉터리에
cat.rs
가 있기 때문에 현재 우리의 cat
에서 우리는 이 모듈의 함수를 호출할 수 있다. 아래와 같다.mod cat;
fn main() {
cat::meow();
}
이 정도면 됐어!목록은요?
앞에서 언급한 바와 같이
cat.rs
는 main.rs
라는 디렉터리를 가리키는데 그 중에는 mod cat;
라는 파일이 포함되어 있다.예시를 위해 이 디렉터리를 만들고
cat
이 디렉터리로 이동합니다.실제로 우리는 mod.rs
잘못된 뜻을 없애기 위해 ("child"모듈에서) cat.rs
로 이름을 바꿀 것이다.현재 우리는
cat.rs
와 kitten.rs
라는 디렉터리가 있는데 그 중에는 두 개의 파일main.rs
과 cat
이 포함되어 있다.우리는
mod.rs
함수를 kitten.rs
에 넣으면 된다.그러나 이 디렉터리의 다른 파일에서 가져오는 방법을 보여 줍니다.meow()
에서는 다음과 같이 Rust에 대해 mod.rs
를 알려야 합니다.pub mod kitten;
mod.rs
모듈이 부모 모듈에도 표시되도록 주의kitten.rs
키워드)하지만 지금 우리
pub
는 이렇게 전화해야 한다kitten
:mod cat;
fn main() {
cat::kitten::meow();
}
main()
의 원본 가져오기 경로를 사용하고 새로운 파일 구조를 유지하려면 어떻게 해야 합니까?우리 할 수 있을까?그래, 우리는 할 수 있어!이것이 바로 Rust의 모듈 시스템이 더욱 의미 있게 변하기 시작할 가능성이 있는 곳이다.
이것을 시험해 보세요
meow()
:mod kitten;
pub use kitten::meow;
이제 우리는 다시 main()
함수에서 mod.rs
를 호출할 수 있다.이것은
cat::meow()
에서 이루어진 것이다. 우리는 Rust에 main()
라는 다른 모듈(이곳은 mod.rs
과 같은 디렉터리에 있는 kitten
을 가리키고 이 모듈은 현재 모듈의 역할 영역에 보인다.그러나 kitten.rs
키워드가 없으면 모듈은 부모 레벨에 보이지 않습니다.우리는 mod.rs
이 모듈에서 pub
함수를 가져올 수 있으며, 전체 모듈을 볼 수 있는 것이 아니라 meow()
을 통해서만 이 가져오기를 공개할 수 있습니다. (부모 모듈을 볼 수 있습니다.)또한 함수의 이름을
use
에서 다시 내보낼 때 다음과 같이 변경할 수도 있습니다.mod kitten;
pub use kitten::meow as woof;
지금 우리 pub use
는 이렇게 해야 한다.fn main() {
cat::woof();
}
전체 네임스페이스 계층에서 Rust 모듈 시스템의 유연성을 확인하시기 바랍니다.편리한 방식으로 파일을 구성할 수도 있고, 호출자에게 더 의미 있는 방식으로 구조와 모듈을 내보낼 수도 있습니다.때로는 똑같을 때도 있고, 때로는 다르다. 녹이 슬면 선택할 수 있다.
한 위치에서 모듈 차원 구조 성명
모듈 성명을
mod.rs
파일 등 파일에 넣는 것은 가능하지만, 개인적으로는 모듈 성명이 전체 코드 라이브러리에 분산되고 따르기 어려울 수 있다고 생각합니다.내 코드에서 나는
main()
(또는 mod.rs
에서 전체 모듈 구조를 설명하는 것을 좋아한다. 이것은 모든 같은 기능을 제공하는 동시에 어떤 main.rs
파일도 필요하지 않게 한다.위의 예제에서는 디렉토리 이름
lib.rs
을 파일mod.rs
만 포함할 수 있습니다(이번에는 없습니다cat
). 현재kitten.rs
는 다음과 같습니다.mod cat {
mod kitten;
pub use kitten::meow;
}
fn main() {
cat::meow();
}
내가 이 점을 발견했을 때, 나는 Rust 모듈 시스템이 정말 얼마나 강한지 깨달았다.이것은 나로 하여금 한 곳에서 나의 모듈 구조를 묘사할 수 있게 하고, 그리고 나의 전체 판자 상자는 이 구조를 인용하여 물건을 가져올 수 있게 한다.예를 들어
mod.rs
아래에 main.rs
라는 새 디렉터리를 추가합니다. 이 디렉터리에는 cat
라는 파일이 포함되어 있습니다.다음은
activities
입니다.pub struct CatToy {
name: String
}
impl CatToy {
pub fn new(name: &str) -> Self {
Self { name: name.to_string() }
}
pub fn fetch(&self) {
println!("Fetch the {}", self.name);
}
}
우리는 play.rs
에서 이런 구조를 이렇게 묘사할 수 있다.mod cat {
// We still have our imports from before.
mod kitten;
pub use kitten::meow;
// And now we describe the additional structure.
pub mod activities {
pub mod play;
}
}
fn main() {
let ball = cat::activities::play::CatToy::new("ball");
ball.fetch();
}
이것은 괜찮지만, 우리의 가져오는 경로가 좀 길다.우리는 파일의 질서성을 유지하기를 원하지만, 이 함수들의 호출자가 우리의 디렉터리 구조를 걱정하지 않기를 원하지 않는다.또는, 가져오는 경로를 수정하지 않은 상태에서 디렉터리 구조를 수정하기를 원합니다. (이로써 보드 상자의 사용자도 코드를 업데이트할 필요가 없습니다.)이렇게 하면 가져오기 경로를 단축할 수 있습니다.
mod cat {
mod kitten;
pub use kitten::meow;
mod activities {
pub mod play;
}
pub use activities::play::*;
}
fn main() {
let ball = cat::CatToy::new("ball");
ball.fetch();
}
이것은 호출자 코드의 사용을 크게 간소화시켰다는 것을 알 수 있다.마지막 일(그래, 여러 가지)
play.rs
를 사용하여 일부 컨텐트를 main.rs
이외의 다른 모듈로 가져오려면 모듈 경로의 시작 부분에 use
를 추가해야 합니다.예를 들어, 다른 파일의
main.rs
를 사용하려면 다음과 같이 하십시오.use crate::cat::CatToy;
pub fn fetch_ball() {
let ball = CatToy::new("ball");
ball.fetch();
}
위의 예시에서 우리는 이렇게 할 필요가 없다. 왜냐하면 crate::
함수는 이미 기본 단계CatToy
범위 내에 있고 모든 다른 모듈은 이 범위의 하위 모듈이기 때문이다.마지막으로 모듈을 부모 모듈로 다시 내보낼 필요가 없는 곳에서 가져오고 사용하려면 필요하지 않습니다.
main()
crate
만 있으면 돼요.부모 범위에 어떤 내용을 보여야 할 때만 사용합니다pub use
.한층 더 읽다
이 문서가 Rust 모듈 시스템을 이해하기 쉽게 하는 데 도움이 되었으면 합니다.
아직 내가 보도하지 않은 것이 많다.
더 많은 정보를 원하신다면, 저는 Rust By Example에 방문하여 관련 문서를 얻는 것을 강력히 권장합니다.
그 밖에 Official Rust Book도 좋은 장과 절이 하나 있다.
처음에 나는 많은 공식 문서가 이해하기 어렵다는 것을 알았지만 모듈의 기본 지식을 이해하면 그것을 되돌려 다시 읽을 수 있고 모든 것이 준비되기 시작했다.나는 여전히 많은 연습을 해야만 그것을 이해할 수 있지만, 지금은 그것이 정말 좋고, 매우 강하다는 것을 발견했다.
Reference
이 문제에 관하여(녹슨 모듈 소개), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/stevepryde/intro-to-rust-modules-3g8k텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)