모듈과 크레이트 사용해보기

파이썬 폴더에 my_modle.py 를 생성합니다.

def greet():
    print(f"Hi! I am hello_bot")


class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def get_older(self, year):
        self.age += year

이제 이 함수와 클래스를 main.py에서 참조합니다.

from my_module import greet, Person

if __name__ == '__main__':
    greet()

    john = Person("john", 20)
    john.get_older(3)
    print(john.age)

이번에는 bots 폴더를 만들고 hello_bot.py 파일을 추가합니다.

.
├── bots
│   └── hello_bot.py
├── main.py
└── my_module.py

hello_bot.py 는 다음과 같습니다.

BOT_NAME = "hello_bot"


def hello():
    print("Hello, humans!")

my_module.py에서 greet 함수가 BOT_NAME 을 이용하도록 합니다.

from bots.hello_bot import BOT_NAME


def greet():
    print(f"Hi! I am {BOT_NAME}")

그 다음 main.py 에서 bots 모듈을 사용해 보겠습니다.

from bots.hello_bot import hello
from my_module import greet, Person

if __name__ == '__main__':
    hello()

    greet()

    john = Person("john", 20)
    john.get_older(3)
    print(john.age)

이번에는 동일한 구조를 러스트에서 구현해 보겠습니다. src 폴더에 my_module.rs 를 생성합니다.

src
├── main.rs
└── my_module.rs

그리고 다음 코드를 입력합니다. 함수 하나와 구조체 하나가 들어있습니다. 여기서 함수, 구조체, 메소드가 모두 pub 키워드로 선언되어 있다는 점에 주목하세요. 이때 구조체 필드도 public으로 만드려면 pub 키워드를 사용해야 합니다. 여기서는 name 만 public입니다.

pub fn greet() {
    println!("Hi! I am hello_bot");
}

pub struct Person {
    pub name: String,
    age: i32,
}

impl Person {
    pub fn new(name: &str, age: i32) -> Self {
        Person {
            name: String::from(name),
            age: age,
        }
    }

    pub fn get_older(&mut self, year: i32) {
        self.age += year;
    }
}

이제 main.rs에서 이 my_module.rs 모듈의 함수와 구조체를 사용해 보겠습니다. 먼저 mod 키워드를 사용해 my_module 을 스코프로 가져옵니다. 그 다음 use my_module::{greet, Person}; 로 가져오고자 하는 함수와 구조체를 가져올 수 있습니다. 이렇게 가져온 함수와 구조체를 이제 main() 함수 내에서 사용할 수 있습니다. 이때 john.alive 는 private이므로 주석을 해제하고 컴파일하면 컴파일이 되지 않습니다.

mod my_module; // will look for a file src/my_module.rs

use my_module::{greet, Person}; // actually import the function and struct from my_module.rs

fn main() {
    greet();

    let mut john = Person::new("john", 20);
    john.get_older(3);
    println!("{}", john.name);
    // println!("Am I alive? {}", john.alive); // won't compile!
}

다음으로는 하위 폴더 bots를 만들어 보겠습니다. bots 폴더에는 hello_bot.rsmod.rs 두 파일을 생성합니다.

src
├── bots
│   ├── hello_bot.rs
│   └── mod.rs
├── main.rs
└── my_module.rs

항상 하위 폴더를 모듈로 만드는 경우에는 mod.rs 가 있어야 합니다. 이 파일은 해당 모듈의 엔트리포인트가 되어 이 모듈 안에 있는 다른 하위 모듈들을 찾을 수 있게 합니다. 따라서 mod.rs 에는 hello_bot 모듈의 정보가 있어야 합니다.

pub mod hello_bot; // will look for hello_bot.rs

이제 hello_bot.rs 파일을 작성합니다.

pub static BOT_NAME: &str = "hello_bot";

pub fn hello() {
    println!("Hello, humans!");
}

static 변수와 함수 하나가 생성되어 있고, 둘 다 public으로 선언되었습니다. 먼저, BOT_NAME 스태틱을 src/my_module.rs 에서 참조해 보겠습니다. my_module.rs 는 크레이트 루트가 아니기 때문에 use crate:: 문법으로 참조해야 합니다. 여기서 greet 함수가 이 BOT_NAME 스태틱을 참조해 실행되도록 수정해 봅시다.

use crate::bots::hello_bot::BOT_NAME;

pub fn greet() {
    println!("Hi! I am {}", BOT_NAME);
}

이제 main.rs 에서 bots 모듈을 사용해 보겠습니다. main.rs는 크레이트 루트기 때문에 use bots::hello_bot::hello; 로 모듈을 불러올 수 있습니다.

mod my_module; // will look for a file src/my_module.rs
mod bots; // will look for a file src/hello/mod.rs

use my_module::{greet, Person}; // actually import the function and struct from my_module.rs
use bots::hello_bot::hello; // actually import the function from hello.rs


fn main() {
    hello();

    greet();

    let mut john = Person::new("john", 20);
    john.get_older(3);
    println!("{}", john.name);
    // println!("Am I alive? {}", john.alive); // won't compile!
}