TL;DR

  • module์€ ์ฝ”๋“œ์˜ ์ด๋ฆ„ยท๊ณต๊ฐœ ๋ฒ”์œ„, crate๋Š” ์ปดํŒŒ์ผ ๋‹จ์œ„, package๋Š” Cargo ์„ค์ •ยท์˜์กด์„ฑ ๊ด€๋ฆฌ ๋‹จ์œ„์˜ ๊ตฌ๋ถ„
  • ํŒŒ์ผ ๋ถ„๋ฆฌ ํ›„ ์ฃผ๋ฌธยท๊ฒฌ์  ๋‘ binary๊ฐ€ ๊ฐ™์€ library์˜ ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ™•์žฅ ์˜ˆ์ œ
  • ์—ฌ๋Ÿฌ package๋ฅผ ํ•จ๊ป˜ ๊ฐœ๋ฐœํ•  ๋•Œ ๋นŒ๋“œยทํ…Œ์ŠคํŠธ์™€ ๊ธฐ๋ณธ lockfileยท๋นŒ๋“œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜๋Š” workspace์˜ ์—ญํ• 

AI-assisted

1. ํ•จ์ˆ˜ ํ•˜๋‚˜๋กœ ์‹œ์ž‘ํ•˜๋Š” package์™€ crate

๊ฐ€๊ฒฉ์„ ๊ณ„์‚ฐํ•˜๊ณ  ์ถœ๋ ฅํ•˜๋Š” CLI๋ฅผ ๋งŒ๋“ ๋‹ค๊ณ  ํ•˜์ž. ์ฒ˜์Œ์—๋Š” ํ•จ์ˆ˜ ํ•˜๋‚˜์™€ main()์ด๋ฉด ์ถฉ๋ถ„ํ•˜๋‹ค.

cargo new shop --vcs none
cd shop

src/main.rs์˜ ๋‚ด์šฉ์„ ๋‹ค์Œ์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

fn total(unit_price: u32, quantity: u32) -> u32 {
    unit_price * quantity
}
 
fn main() {
    println!("{}", total(1000, 3)); // 3000
}
cargo run

ํ”„๋กœ์ ํŠธ์˜ ์ฃผ์š” ํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. ์ดํ›„ 4์ ˆ๊นŒ์ง€๋Š” ์ด shop ๋””๋ ‰ํ„ฐ๋ฆฌ ์•ˆ์—์„œ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ๋ช…๋ น์„ ์‹คํ–‰ํ•œ๋‹ค.

shop/
โ”œโ”€โ”€ Cargo.toml
โ””โ”€โ”€ src/
    โ””โ”€โ”€ main.rs
  • package: Cargo.toml๋กœ ์ด๋ฆ„, ๋ฒ„์ „, ์˜์กด์„ฑ๊ณผ ๋นŒ๋“œ ๋Œ€์ƒ์„ ๊ด€๋ฆฌํ•˜๋Š” Cargo ๋‹จ์œ„. ์ด package์˜ ์ด๋ฆ„์€ shop์ด๋‹ค.
  • crate: Rust ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์ฝ”๋“œ. ์—ฌ๊ธฐ์„œ๋Š” ์‹คํ–‰ ํŒŒ์ผ์„ ๋งŒ๋“œ๋Š” binary crate ํ•˜๋‚˜๊ฐ€ ์žˆ๋‹ค.
  • crate root: ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ฝ๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ํŒŒ์ผ. ๊ธฐ๋ณธ Cargo ๊ตฌ์กฐ์—์„œ๋Š” src/main.rs๊ฐ€ binary crate์˜ root๋‹ค.
  • module: crate ์•ˆ์—์„œ ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ๋ฌถ๊ณ  ์ด๋ฆ„๊ณผ ๊ณต๊ฐœ ๋ฒ”์œ„๋ฅผ ๋‚˜๋ˆ„๋Š” ๋‹จ์œ„. ํ˜„์žฌ ํ•จ์ˆ˜๋Š” crate์˜ ๋ฃจํŠธ module์— ์žˆ๋‹ค.

Rust Book 7์žฅ์€ ์ฝ”๋“œ๊ฐ€ ๋Š˜์–ด๋‚  ๋•Œ ์ด ๊ตฌ์กฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๋‚˜๋ˆ„๋Š”์ง€ ์„ค๋ช…ํ•œ๋‹ค.
Package์™€ crate๋Š” ๊ฐ๊ฐ Cargo์˜ ๊ด€๋ฆฌ ๋‹จ์œ„์™€ ์ปดํŒŒ์ผ ๋‹จ์œ„์ด๋ฏ€๋กœ ๊ฐ™์€ ํ”„๋กœ์ ํŠธ๋ฅผ ์„ค๋ช…ํ•ด๋„ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฒ”์œ„๊ฐ€ ๋‹ค๋ฅด๋‹ค.

Cargo์˜ ๊ธฐ๋ณธ ๊ทœ์น™: root ํŒŒ์ผ๊ณผ crate ์ข…๋ฅ˜

  • Binary crate: src/main.rs์—์„œ ์‹œ์ž‘ํ•ด ์‹คํ–‰ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ ๋‹ค.
  • Library crate: src/lib.rs์—์„œ ์‹œ์ž‘ํ•ด ๋‹ค๋ฅธ crate๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.
  • Package ๊ตฌ์„ฑ: library crate๋Š” ์ตœ๋Œ€ ํ•˜๋‚˜, binary crate๋Š” ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ํฌํ•จ. ์ถ”๊ฐ€ binary๋Š” ๋ณดํ†ต src/bin/์ด๋ฆ„.rs์— ๋‘”๋‹ค.
  • ํŒŒ์ผ ์ˆ˜: crate ํ•˜๋‚˜์— ์—ฌ๋Ÿฌ module๊ณผ .rs ํŒŒ์ผ์ด ํฌํ•จ. ํŒŒ์ผ ๊ฐœ์ˆ˜์™€ crate ๊ฐœ์ˆ˜๋Š” ๋ณ„๊ฐœ๋‹ค.

Python ๋น„๊ต: ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ์™€ ์ฝ”๋“œ์˜ ์‚ฌ์šฉ ์—ญํ• 

  • Package ๊ด€๋ฆฌ: Rust์˜ Cargo.toml์€ Python์˜ pyproject.toml์— ๋Œ€์‘ํ•˜๋ฉฐ ์ด๋ฆ„ยท๋ฒ„์ „ยท์˜์กด์„ฑ์„ ๊ด€๋ฆฌํ•œ๋‹ค.
  • Import ๋‹จ์œ„: Python์—์„œ import shop์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” package์˜ ์ด๋ฆ„ ๊ณต๊ฐ„์€ Rust์˜ module ๊ณผ ์œ ์‚ฌ.
  • ์‚ฌ์šฉ ์—ญํ• : Python์˜ CLI ์ง„์ž…์ ์€ Rust์˜ binary ์—ญํ• ์—, importํ•ด์„œ ์“ฐ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” Rust์˜ library ์—ญํ• ์— ๊ฐ€๊น๋‹ค.

2. ๋ฐฐ์†ก๋น„ ๊ณ„์‚ฐ์„ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ module๋กœ ๋ฌถ๋Š”๋‹ค

๊ณ„์‚ฐ์— ๋ฐฐ์†ก๋น„ ๊ทœ์น™์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ƒํ’ˆ ํ•ฉ๊ณ„๊ฐ€ 5,000 ๋ฏธ๋งŒ์ด๋ฉด ๋ฐฐ์†ก๋น„ 300์„ ๋ถ™์ด๊ณ  ๊ทธ ์ด์ƒ์ด๋ฉด ๋ฐฐ์†ก๋น„๋ฅผ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.

CLI๋Š” ์ตœ์ข… ๊ธˆ์•ก๋งŒ ํ•„์š”ํ•˜๋ฏ€๋กœ ๋ฐฐ์†ก๋น„ ๊ณ„์‚ฐ ํ•จ์ˆ˜๋Š” ๋‚ด๋ถ€์— ๋‘”๋‹ค. mod๋กœ ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ์„ ๋ฌถ์–ด src/main.rs๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ”๊พผ๋‹ค.

mod pricing {
    pub fn total(unit_price: u32, quantity: u32) -> u32 {
        let subtotal = unit_price * quantity;
        subtotal + shipping_fee(subtotal)
    }
 
    fn shipping_fee(subtotal: u32) -> u32 {
        if subtotal < 5000 { 300 } else { 0 }
    }
}
 
fn main() {
    println!("{}", pricing::total(1000, 3)); // 3300
}
  • ์ด๋ฆ„ ๊ตฌ๋ถ„: pricing::total์€ ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ module ์•ˆ์˜ ํ•จ์ˆ˜๋‹ค. ๋‹ค๋ฅธ module์—๋„ total์ด๋ผ๋Š” ์ด๋ฆ„์„ ์“ธ ์ˆ˜ ์žˆ๋‹ค.
  • ๊ณต๊ฐœ ๊ธฐ๋Šฅ: pub fn total์€ module ๋ฐ–์˜ main()์—์„œ ํ˜ธ์ถœํ•œ๋‹ค.
  • ๋‚ด๋ถ€ ๊ตฌํ˜„: shipping_fee๋Š” ๊ณต๊ฐœํ•˜์ง€ ์•Š์•˜๋‹ค. main()์—์„œ ์ง์ ‘ ํ˜ธ์ถœํ•˜๋ ค ํ•˜๋ฉด ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๊ฐ€ ๋‚œ๋‹ค.

๋ฐฐ์†ก๋น„ ๊ณ„์‚ฐ ๋ฐฉ๋ฒ•์„ ๋ฐ”๊ฟ”๋„ ํ˜ธ์ถœ์ž๋Š” ์ตœ์ข… ๊ธˆ์•ก์„ ๊ตฌํ•˜๋Š” total()๋งŒ ์‚ฌ์šฉํ•œ๋‹ค.

๊ณต๊ฐœ ๋ฒ”์œ„: pub๋Š” ์–ด๋А ๊ฒฝ๊ณ„๊นŒ์ง€ ํ—ˆ์šฉํ•˜๋Š”๊ฐ€

  • ๊ธฐ๋ณธ ๋ฒ”์œ„: ๊ณต๊ฐœํ•˜์ง€ ์•Š์€ ํ•ญ๋ชฉ์€ ์ •์˜ํ•œ module๊ณผ ๊ทธ ํ•˜์œ„ module์—์„œ ์‚ฌ์šฉํ•œ๋‹ค.
  • pub: ํ•ญ๋ชฉ์„ ๊ณต๊ฐœ. ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•˜๋ ค๋ฉด ๊ทธ ํ•ญ๋ชฉ๊นŒ์ง€์˜ ๊ฒฝ๋กœ๋„ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค.
  • Crate ๋‚ด๋ถ€ ๊ณต๊ฐœ: pub(crate)๋Š” ๊ฐ™์€ crate ์•ˆ์—์„œ ์‚ฌ์šฉํ•˜๋„๋ก ๋ฒ”์œ„๋ฅผ ์ œํ•œํ•œ๋‹ค.
  • ๊ฒ€์‚ฌ ๋Œ€์ƒ: ๊ฒฝ๋กœ์™€ ๊ณต๊ฐœ ๋ฒ”์œ„๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฒ€์‚ฌ. ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋Š” ๋‚ด๋ถ€ ๊ธฐ๋Šฅ์— ์˜์กดํ•˜๋Š” ์ฝ”๋“œ๋Š” ์ปดํŒŒ์ผ๋˜์ง€ ์•Š๋Š”๋‹ค.

Python ๋น„๊ต: ํ•จ์ˆ˜ ๋ชจ์Œ๊ณผ ๊ณต๊ฐœ ๋ฒ”์œ„

  • ํ•จ์ˆ˜ ๋ชจ์Œ: Rust์˜ pricing module์€ Python์˜ pricing.py์ฒ˜๋Ÿผ ๊ฐ€๊ฒฉ ๊ด€๋ จ ํ•จ์ˆ˜๋ฅผ ๋ชจ์€๋‹ค. Python์—์„œ pricing.total๋กœ ์†Œ์†์„ ๋‚˜ํƒ€๋‚ด๋“ฏ Rust์—์„œ๋Š” pricing::total๋กœ ๋‚˜ํƒ€๋‚ธ๋‹ค.
  • ํŒŒ์ผ ๋ฐฐ์น˜: Rust๋Š” ๊ฐ™์€ ํŒŒ์ผ์˜ mod pricing { ... } ๋˜๋Š” ๋ณ„๋„ pricing.rs์— module์„ ์ •์˜ํ•œ๋‹ค. Python์˜ ์ผ๋ฐ˜์ ์ธ .py module์€ ํŒŒ์ผ ์ž์ฒด๋กœ ์ •์˜ํ•œ๋‹ค.
  • ๋‚ด๋ถ€์šฉ ๊ด€๋ก€: Python์˜ _shipping_fee๋Š” ๋‚ด๋ถ€์šฉ์ด๋ผ๋Š” ๊ด€๋ก€์ด๋ฉฐ ์ง์ ‘ importํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. Rust์˜ ๋น„๊ณต๊ฐœ ํ•จ์ˆ˜๋Š” ๋ถ€๋ชจ module์—์„œ ํ˜ธ์ถœํ•˜๋ฉด ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋‹ค.
  • __all__: Python์€ ์ฃผ๋กœ from module import *์— ํฌํ•จํ•  ์ด๋ฆ„์„ ์ •ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. Rust์˜ pub์ฒ˜๋Ÿผ ์ง์ ‘ ์ ‘๊ทผ์„ ์ œํ•œํ•˜๋Š” ๊ธฐ๋Šฅ์€ ์•„๋‹ˆ๋‹ค.

3. ํŒŒ์ผ์„ ๋‚˜๋ˆ ๋„ crate๋Š” ํ•˜๋‚˜๋‹ค

๊ฐ€๊ฒฉ ๊ณ„์‚ฐ์ด ๊ธธ์–ด์ง€๋ฉด main.rs์—์„œ ๋ณ„๋„ ํŒŒ์ผ๋กœ ์˜ฎ๊ธด๋‹ค. ๊ฐ™์€ module์˜ ์ฝ”๋“œ๋ฅผ ๋‹ค๋ฅธ ํŒŒ์ผ์— ๋ณด๊ด€ํ•˜๋Š” ๋ณ€ํ™”๋‹ค.

shop/
โ”œโ”€โ”€ Cargo.toml
โ””โ”€โ”€ src/
    โ”œโ”€โ”€ main.rs
    โ””โ”€โ”€ pricing.rs

src/main.rs๋ฅผ ๋‹ค์Œ์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

mod pricing;
 
use crate::pricing::total;
 
fn main() {
    println!("{}", total(1000, 3)); // 3300
}

src/pricing.rs์—๋Š” ์ด์ „ mod pricing { ... } ์•ˆ์˜ ๋‚ด์šฉ์„ ๋„ฃ๋Š”๋‹ค.

pub fn total(unit_price: u32, quantity: u32) -> u32 {
    let subtotal = unit_price * quantity;
    subtotal + shipping_fee(subtotal)
}
 
fn shipping_fee(subtotal: u32) -> u32 {
    if subtotal < 5000 { 300 } else { 0 }
}
ํ‘œ๊ธฐ์—ญํ• 
mod pricing;ํ˜„์žฌ module์˜ ํ•˜์œ„ module์„ ์„ ์–ธํ•˜๊ณ  ๋ณ„๋„ ํŒŒ์ผ์˜ ๋ณธ๋ฌธ์„ ์—ฐ๊ฒฐ
crate::pricing::totalํ˜„์žฌ crate์˜ root๋ถ€ํ„ฐ ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒฝ๋กœ
use crate::pricing::total;ํ˜„์žฌ ๋ฒ”์œ„์—์„œ ํ•จ์ˆ˜๋ฅผ total์ด๋ผ๋Š” ์งง์€ ์ด๋ฆ„์œผ๋กœ ์‚ฌ์šฉ

use๋Š” ๊ธฐ์กด ํ•ญ๋ชฉ์˜ ์ด๋ฆ„์„ ํ˜„์žฌ ๋ฒ”์œ„์— ๊ฐ€์ ธ์˜จ๋‹ค.

Python ๋น„๊ต: import์˜ ์—ญํ• ์„ mod์™€ use๋กœ ๋‚˜๋ˆ  ์ฝ๊ธฐ

  • ์ด๋ฆ„ ๊ฐ€์ ธ์˜ค๊ธฐ: from pricing import total์˜ ์‚ฌ์šฉ ๋ฐฉ์‹์€ use crate::pricing::total;๊ณผ ๋น„์Šทํ•˜๋‹ค. ๋‘ ์–ธ์–ด ๋ชจ๋‘ as calculate_total์„ ๋ถ™์—ฌ ํ˜„์žฌ ๋ฒ”์œ„์˜ ๋ณ„์นญ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Module ์—ฐ๊ฒฐ: Rust์—์„œ๋Š” ๋ณ„๋„ ํŒŒ์ผ์˜ module์„ mod pricing;๋กœ ์„ ์–ธํ•œ๋‹ค. Python์˜ import๋Š” ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅํ•œ module์„ ์ฐพ๊ณ  ํ•„์š”ํ•˜๋ฉด ๋กœ๋”ฉยท์ดˆ๊ธฐํ™”๋„ ํ•œ๋‹ค.
  • ์ฒ˜๋ฆฌ ์‹œ์ : Rust modยทuse๋Š” ์ปดํŒŒ์ผํ•  ๊ตฌ์กฐ์™€ ์ด๋ฆ„ ํ•ด์„์„ ์ •ํ•œ๋‹ค. Python์˜ module ์ตœ์ƒ์œ„ ์ฝ”๋“œ๋Š” ์ดˆ๊ธฐํ™”ํ•  ๋•Œ ์‹คํ–‰๋œ๋‹ค.
  • ํŒŒ์ผ ๋ถ„๋ฆฌ ๊ฒฐ๊ณผ: ์†Œ์Šค ํŒŒ์ผ์€ ๋‘ ๊ฐœ์ง€๋งŒ binary crate๋Š” ์—ฌ์ „ํžˆ ํ•˜๋‚˜๋‹ค.
  • ์ปดํŒŒ์ผ ์‹œ์ž‘์ : main.rs์—์„œ ์‹œ์ž‘ํ•ด ์„ ์–ธ๋œ pricing module๋„ ํ•จ๊ป˜ ์ปดํŒŒ์ผํ•œ๋‹ค.
  • ๊ณต๊ฐœ ๋ฒ”์œ„ ์œ ์ง€: ํŒŒ์ผ์„ ์˜ฎ๊ฒจ๋„ total์€ ๊ณต๊ฐœํ•˜๊ณ  shipping_fee๋Š” ๋‚ด๋ถ€์— ๋‘๋Š” ๊ด€๊ณ„๊ฐ€ ์œ ์ง€๋œ๋‹ค.

Module ํŒŒ์ผ: ์„ ์–ธ ์œ„์น˜์— ๋”ฐ๋ผ ๋ณธ๋ฌธ์„ ์ฐพ์Œ

  • ํ˜„์žฌ ์˜ˆ์ œ: root์˜ mod pricing;์€ src/pricing.rs ๋˜๋Š” src/pricing/mod.rs์—์„œ ๋ณธ๋ฌธ์„ ์ฐพ๋Š”๋‹ค. ๋‘ ํŒŒ์ผ์„ ๋™์‹œ์— ๋‘๋ฉด ์•ˆ ๋œ๋‹ค.
  • ํ•˜์œ„ module: src/pricing.rs์— mod tax;๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๊ธฐ๋ณธ ์œ„์น˜๋Š” src/pricing/tax.rs ๋˜๋Š” src/pricing/tax/mod.rs๋‹ค.
  • ๋ช…์‹œ์  ์—ฐ๊ฒฐ: ์ผ๋ฐ˜ module ํŒŒ์ผ์€ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๋†“๋Š” ๊ฒƒ๋งŒ์œผ๋กœ module tree์— ์ถ”๊ฐ€๋˜์ง€ ์•Š๋Š”๋‹ค. ์„ ์–ธ์œผ๋กœ ์—ฐ๊ฒฐํ•œ๋‹ค.
  • ๋ถ„๋ฆฌ ์›์น™: ํŒŒ์ผ๋กœ module ๋ถ„๋ฆฌํ•˜๊ธฐ๋Š” ์ฝ”๋“œ ์œ„์น˜๋ฅผ ๋ฐ”๊พธ๋ฉฐ ๋ณ„๋„ crate๋ฅผ ๋งŒ๋“œ๋Š” ์ž‘์—…๊ณผ ๊ตฌ๋ถ„๋œ๋‹ค.

๊ฒฝ๋กœ ํ‘œ๊ธฐ: ํ˜„์žฌ ์œ„์น˜์™€ ๋ถ€๋ชจ ์œ„์น˜

  • crate::: ํ˜„์žฌ crate์˜ root์—์„œ ์‹œ์ž‘ํ•œ๋‹ค.
  • self::: ํ˜„์žฌ module์—์„œ ์‹œ์ž‘ํ•œ๋‹ค.
  • super::: ๋ถ€๋ชจ module์—์„œ ์‹œ์ž‘ํ•œ๋‹ค.
  • ์™ธ๋ถ€ crate: ์˜์กดํ•˜๋Š” library crate์˜ ์ด๋ฆ„์œผ๋กœ ์‹œ์ž‘ํ•œ๋‹ค. ๋‹ค์Œ ์ ˆ์˜ shop::total์ด ๊ทธ ์˜ˆ๋‹ค.

์„ ํƒ ๊ธฐ์ค€: ํ”„๋กœ๊ทธ๋žจ ๋‚ด๋ถ€์˜ ์ฝ”๋“œ ์ •๋ฆฌ

  • ๋‹จ์ผ ํ”„๋กœ๊ทธ๋žจ: ํ•ด๋‹น ํ”„๋กœ๊ทธ๋žจ์—์„œ๋งŒ ์“ฐ๋Š” ๊ธฐ๋Šฅ์€ main.rs์™€ module๋กœ ๊ตฌ์„ฑํ•˜๋ฉด ์ถฉ๋ถ„ํ•˜๋‹ค.
  • Library ๋ถ„๋ฆฌ: ๋‹ค๋ฅธ binaryยทpackage์˜ ์žฌ์‚ฌ์šฉ์ด๋‚˜ ๋…๋ฆฝ๋œ ๊ณต๊ฐœ API ๊ฒฝ๊ณ„๊ฐ€ ํ•„์š”ํ•  ๋•Œ ์„ ํƒํ•œ๋‹ค. ๋‹ค์Œ ์˜ˆ์ œ์—์„œ๋Š” ๋‘ ์‹คํ–‰ ํ”„๋กœ๊ทธ๋žจ์˜ ๊ณ„์‚ฐ ๊ธฐ๋Šฅ์„ ๊ณต์œ ํ•œ๋‹ค.

4. ์ฃผ๋ฌธ๊ณผ ๊ฒฌ์  ํ”„๋กœ๊ทธ๋žจ์ด ๊ณ„์‚ฐ library๋ฅผ ๊ณต์œ ํ•œ๋‹ค

์ฃผ๋ฌธ CLI์— ๋”ํ•ด ๊ฒฌ์  ํ”„๋กœ๊ทธ๋žจ๋„ ๋ณ„๋„๋กœ ์‹คํ–‰ํ•  ํ•„์š”๊ฐ€ ์ƒ๊ฒผ๋‹ค. ์ฃผ๋ฌธ CLI๋Š” ์ƒํ’ˆ 3๊ฐœ์˜ ๊ธˆ์•ก์„ ์ถœ๋ ฅํ•˜๊ณ  ๊ฒฌ์  ํ”„๋กœ๊ทธ๋žจ์€ ์ƒํ’ˆ 5๊ฐœ์˜ ์˜ˆ์ƒ ๊ธˆ์•ก์„ ์ถœ๋ ฅํ•œ๋‹ค. ๊ฐ€๊ฒฉ๊ณผ ๋ฐฐ์†ก๋น„ ๊ทœ์น™์€ ๋‘ ํ”„๋กœ๊ทธ๋žจ์— ๋™์ผํ•˜๊ฒŒ ์ ์šฉํ•œ๋‹ค.

๊ณตํ†ต ๊ณ„์‚ฐ ๊ธฐ๋Šฅ์„ library crate๋กœ ์˜ฎ๊ธฐ๊ณ  ๋‘ binary crate๊ฐ€ ๊ทธ API๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๊ตฌ์„ฑํ•œ๋‹ค. ๊ฐ™์€ package ์•ˆ์— src/lib.rs์™€ src/bin/quote.rs๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

shop/
โ”œโ”€โ”€ Cargo.toml
โ””โ”€โ”€ src/
    โ”œโ”€โ”€ lib.rs
    โ”œโ”€โ”€ pricing.rs
    โ”œโ”€โ”€ main.rs
    โ””โ”€โ”€ bin/
        โ””โ”€โ”€ quote.rs

src/pricing.rs๋Š” 3์ ˆ์˜ ์ฝ”๋“œ๋ฅผ ์œ ์ง€ํ•œ๋‹ค. ์ƒˆ src/lib.rs์—๋Š” ๋‹ค์Œ์„ ๋„ฃ๋Š”๋‹ค.

mod pricing;
 
pub use pricing::total;

์ฃผ๋ฌธ CLI์ธ src/main.rs๋Š” ๋‹ค์Œ์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

use shop::total;
 
fn main() {
    println!("์ฃผ๋ฌธ ๊ธˆ์•ก: {}", total(1000, 3)); // ์ฃผ๋ฌธ ๊ธˆ์•ก: 3300
}

๊ฒฌ์  ํ”„๋กœ๊ทธ๋žจ์„ ๋‘˜ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๋งŒ๋“ ๋‹ค.

mkdir -p src/bin

์ƒˆ src/bin/quote.rs์—๋Š” ๋‹ค์Œ์„ ๋„ฃ๋Š”๋‹ค.

use shop::total;
 
fn main() {
    println!("๊ฒฌ์  ๊ธˆ์•ก: {}", total(1000, 5)); // ๊ฒฌ์  ๊ธˆ์•ก: 5000
}
Binary ์ด๋ฆ„Crate root์—ญํ• ์‚ฌ์šฉํ•˜๋Š” ๊ณตํ†ต ํ•จ์ˆ˜
shopsrc/main.rs์ฃผ๋ฌธ ๊ธˆ์•ก ์ถœ๋ ฅshop::total
quotesrc/bin/quote.rs๊ฒฌ์  ๊ธˆ์•ก ์ถœ๋ ฅshop::total
  • Library crate ํ•˜๋‚˜: lib.rs์—์„œ pricing module์„ ์—ฐ๊ฒฐํ•˜๊ณ  total์„ ๊ณต๊ฐœํ•œ๋‹ค.
  • Binary crate ๋‘ ๊ฐœ: ๊ฐ root์— main()์ด ์žˆ๋‹ค. ์ฃผ๋ฌธยท๊ฒฌ์  ํ”„๋กœ๊ทธ๋žจ์€ ๊ฐ™์€ library API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ๋ณ„๋„ ์‹คํ–‰ ํŒŒ์ผ๋กœ ๋นŒ๋“œ๋œ๋‹ค.
  • Package ํ•˜๋‚˜: Cargo.toml๋กœ ์„ธ crate๋ฅผ ํ•จ๊ป˜ ๊ด€๋ฆฌํ•œ๋‹ค. Cargo๊ฐ€ ๊ฐ™์€ package์˜ library๋ฅผ binary์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ์—ฐ๊ฒฐํ•˜๋ฏ€๋กœ ์ƒˆ dependency ํ•ญ๋ชฉ์€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค.
cargo build --bins
cargo run --bin shop
cargo run --bin quote

์ฃผ๋ฌธ ํ”„๋กœ๊ทธ๋žจ์€ ์ฃผ๋ฌธ ๊ธˆ์•ก: 3300, ๊ฒฌ์  ํ”„๋กœ๊ทธ๋žจ์€ ๊ฒฌ์  ๊ธˆ์•ก: 5000์„ ์ถœ๋ ฅํ•œ๋‹ค. Binary๊ฐ€ ๋‘ ๊ฐœ์ด๋ฏ€๋กœ ์‹คํ–‰ํ•  ๋Œ€์ƒ์„ --bin์œผ๋กœ ์„ ํƒํ•œ๋‹ค.

๋‘ ํ”„๋กœ๊ทธ๋žจ์˜ ๊ณ„์‚ฐ์€ pricing.rs์˜ ๊ตฌํ˜„ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๋ฐฐ์†ก๋น„ ๊ทœ์น™์„ ์ˆ˜์ •ํ•˜๋ฉด ๋‘ ํ”„๋กœ๊ทธ๋žจ์„ ๋‹ค์‹œ ๋นŒ๋“œํ–ˆ์„ ๋•Œ ๊ฐ™์€ ๋ณ€๊ฒฝ์ด ์ ์šฉ๋œ๋‹ค. ์‹คํ–‰ ์ง„์ž…์ ๊ณผ ์ถœ๋ ฅ ์ฒ˜๋ฆฌ๋Š” ๊ฐ binary์— ๋‘๊ณ  ๊ณตํ†ต ๊ทœ์น™์€ library์—์„œ ๊ด€๋ฆฌํ•œ๋‹ค.

Python ๋น„๊ต: ๊ณตํ†ต ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๋‘ CLI ์ง„์ž…์ 

  • ๊ณตํ†ต ๊ธฐ๋Šฅ: pricing.py์˜ ๊ณ„์‚ฐ ํ•จ์ˆ˜๋ฅผ cli.py์™€ quote.py๊ฐ€ ํ•จ๊ป˜ importํ•˜๋Š” ๊ตฌ์กฐ์™€ ๋น„์Šทํ•˜๋‹ค.
  • ๊ณต๊ฐœ ๊ฒฝ๋กœ ๋ชจ์Œ: shop/__init__.py์—์„œ from .pricing import total๋กœ shop.total์„ ์ œ๊ณตํ•˜๋Š” ๋ฐฉ์‹์€ pub use pricing::total๊ณผ ๋น„์Šทํ•˜๋‹ค. Python์˜ __init__.py๋Š” ์‹คํ–‰๋˜๋Š” module์ด๊ณ  Rust์˜ re-export๋Š” ์ปดํŒŒ์ผ ์ค‘ ์ด๋ฆ„์˜ ๊ณต๊ฐœ ๊ฒฝ๋กœ๋ฅผ ์ •ํ•œ๋‹ค.
  • ๋ช…๋ น ๋“ฑ๋ก: ์„ค์น˜ ๊ฐ€๋Šฅํ•œ Python ํ”„๋กœ์ ํŠธ๋Š” pyproject.toml์˜ [project.scripts]์— shop = "shop.cli:main", quote = "shop.quote:main"์„ ๋“ฑ๋กํ•ด ๋ช…๋ น ๋‘ ๊ฐœ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
  • ์‹คํ–‰ ๋ฐฉ์‹: Rust๋Š” binary ๋‘ ๊ฐœ๋ฅผ ์ปดํŒŒ์ผํ•œ๋‹ค. Python์˜ ์œ„ ์„ค์ •์€ ์„ค์น˜ ์‹œ ์ง€์ •ํ•œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” CLI ๋ช…๋ น์„ ์ œ๊ณตํ•œ๋‹ค.

๊ณต๊ฐœ API: module ์ „์ฒด ๋Œ€์‹  ํ•„์š”ํ•œ ํ•จ์ˆ˜ ๊ณต๊ฐœ

  • mod pricing: library์˜ ๋‚ด๋ถ€ module ๊ตฌ์กฐ๋Š” ๊ณต๊ฐœํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • pub use pricing::total: ์™ธ๋ถ€์—๋Š” root ๊ฒฝ๋กœ์˜ total์„ ๊ณต๊ฐœํ•œ๋‹ค. ์ด๋Ÿฐ ๊ณต๊ฐœ๋ฅผ re-export๋ผ๊ณ  ํ•œ๋‹ค.
  • ๋Œ€์•ˆ: pub mod pricing์œผ๋กœ module์„ ๊ณต๊ฐœํ•˜๋ฉด ์™ธ๋ถ€์—์„œ shop::pricing::total ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์œ ์ง€๋ณด์ˆ˜: re-export๋กœ ๊ณต๊ฐœ ๊ฒฝ๋กœ๋ฅผ ์œ ์ง€ํ•˜๋ฉด ๋‚ด๋ถ€ module ๋ฐฐ์น˜๋ฅผ ๋ฐ”๊ฟ€ ๋•Œ ํ˜ธ์ถœ ์ฝ”๋“œ๋ฅผ ๋œ ์ˆ˜์ •ํ•œ๋‹ค.

crate์˜ ๊ฒฝ๊ณ„: ๊ฐ™์€ package์—๋„ root๋Š” ๊ฐ๊ฐ ์žˆ์Œ

  • Binary ๋‚ด๋ถ€: main.rs์™€ quote.rs๋Š” ๊ฐ๊ฐ ๋‹ค๋ฅธ binary crate์˜ root๋‹ค. crate::๋Š” ๊ทธ ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•˜๋Š” crate์˜ root๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  • Library ์ ‘๊ทผ: ๋‘ binary๋Š” shop::total๋กœ library ํ•จ์ˆ˜๋ฅผ ์ฐธ์กฐํ•œ๋‹ค. use shop::total;๋กœ root ๋ฒ”์œ„์— ๊ฐ€์ ธ์˜จ ํ•จ์ˆ˜๋ฅผ crate::total ๊ฒฝ๋กœ๋กœ๋„ ์ฐธ์กฐํ•œ๋‹ค.
  • ๊ณต๊ฐœ ๋ฒ”์œ„: library์˜ pub(crate) ํ•ญ๋ชฉ์€ ๊ฐ™์€ package์˜ binary์—๋„ ๊ณต๊ฐœ๋˜์ง€ ์•Š๋Š”๋‹ค. ์„œ๋กœ ๋‹ค๋ฅธ crate์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

5. ์—ฌ๋Ÿฌ package๋ฅผ ํ•จ๊ป˜ ๊ฐœ๋ฐœํ•  ๋•Œ workspace๋กœ ๋ฌถ๋Š”๋‹ค

์ฃผ๋ฌธยท๊ฒฌ์  CLI๋Š” app package์— ํ•จ๊ป˜ ๋‘๊ณ  ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ์€ ์˜์กด์„ฑยท๋ฒ„์ „ ์„ค์ •์„ ๋ณ„๋„๋กœ ๊ด€๋ฆฌํ•˜๋Š” pricing package๋กœ ๋‚˜๋ˆˆ๋‹ค. ๋‘ package๋ฅผ ๊ฐ™์€ ์ €์žฅ์†Œ์—์„œ ํ•จ๊ป˜ ๋นŒ๋“œํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๋ ค๋ฉด Cargo workspace๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. Workspace๋Š” Rust Book 14.3์ ˆ์—์„œ ๋‹ค๋ฃฌ๋‹ค.

์•ž์˜ shop์€ ๋‚จ๊ฒจ ๋‘๊ณ  ๊ทธ ์˜†์— ์ƒˆ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ ๋‹ค. ํ˜„์žฌ shop ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ๋‹ค์Œ์„ ์‹คํ–‰ํ•œ๋‹ค.

cd ..
mkdir shop-workspace
cd shop-workspace
cargo new app --vcs none
cargo new pricing --lib --vcs none
cp ../shop/src/pricing.rs pricing/src/calculation.rs
mkdir -p app/src/bin

์ตœ์ข… ํŒŒ์ผ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. ์ดํ›„ ๋ช…๋ น์€ shop-workspace root์—์„œ ์‹คํ–‰ํ•œ๋‹ค.

shop-workspace/
โ”œโ”€โ”€ Cargo.toml
โ”œโ”€โ”€ app/
โ”‚   โ”œโ”€โ”€ Cargo.toml
โ”‚   โ””โ”€โ”€ src/
โ”‚       โ”œโ”€โ”€ main.rs
โ”‚       โ””โ”€โ”€ bin/
โ”‚           โ””โ”€โ”€ quote.rs
โ””โ”€โ”€ pricing/
    โ”œโ”€โ”€ Cargo.toml
    โ””โ”€โ”€ src/
        โ”œโ”€โ”€ lib.rs
        โ””โ”€โ”€ calculation.rs

5.1 Workspace root๋Š” member๋ฅผ ์ง€์ •ํ•œ๋‹ค

shop-workspace/Cargo.toml์„ ์ƒˆ๋กœ ์ž‘์„ฑํ•œ๋‹ค.

[workspace]
members = ["app", "pricing"]
resolver = "3"
  • Member: app, pricing ๋‘ package๋ฅผ ํ•จ๊ป˜ ๊ด€๋ฆฌํ•œ๋‹ค.
  • Virtual workspace: ์ด root์—๋Š” [package]๊ฐ€ ์—†๋‹ค. root ์ž์ฒด๋Š” package๋‚˜ crate๊ฐ€ ์•„๋‹ˆ๋ฉฐ member์˜ ๊ตฌ์„ฑ์„ ๊ด€๋ฆฌํ•œ๋‹ค.
  • Resolver: ์˜ˆ์ œ๋Š” Rust 2024 edition์„ ์‚ฌ์šฉํ•˜๋ฉฐ virtual workspace์—๋Š” ์˜์กด์„ฑ resolver๋ฅผ ๋ช…์‹œํ•œ๋‹ค.

5.2 Pricing package๋Š” ๊ณ„์‚ฐ library๋ฅผ ์ œ๊ณตํ•œ๋‹ค

pricing/Cargo.toml์„ ๋‹ค์Œ์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

[package]
name = "pricing"
version = "0.1.0"
edition = "2024"

pricing/src/lib.rs๋ฅผ ๋‹ค์Œ์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

mod calculation;
 
pub use calculation::total;

calculation.rs๋Š” ์•ž ๋ช…๋ น์œผ๋กœ ๋ณต์‚ฌํ•œ ๊ฐ€๊ฒฉยท๋ฐฐ์†ก๋น„ ๊ณ„์‚ฐ ์ฝ”๋“œ๋‹ค. Library ๋‚ด๋ถ€ module ์ด๋ฆ„์€ calculation, library crate ์ด๋ฆ„์€ pricing์ด๋‹ค.

5.3 App package๋Š” pricing์„ dependency๋กœ ์„ ์–ธํ•œ๋‹ค

app/Cargo.toml์„ ๋‹ค์Œ์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

[package]
name = "app"
version = "0.1.0"
edition = "2024"
 
[dependencies]
pricing = { path = "../pricing" }

app/src/main.rs๋ฅผ ๋‹ค์Œ์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

use pricing::total;
 
fn main() {
    println!("์ฃผ๋ฌธ ๊ธˆ์•ก: {}", total(1000, 3)); // ์ฃผ๋ฌธ ๊ธˆ์•ก: 3300
}

app/src/bin/quote.rs์—๋Š” ๊ฒฌ์  ํ”„๋กœ๊ทธ๋žจ์„ ๋„ฃ๋Š”๋‹ค. ๊ณตํ†ต ํ•จ์ˆ˜์˜ ๊ฒฝ๋กœ๋Š” ์ด์ œ pricing::total์ด๋‹ค.

use pricing::total;
 
fn main() {
    println!("๊ฒฌ์  ๊ธˆ์•ก: {}", total(1000, 5)); // ๊ฒฌ์  ๊ธˆ์•ก: 5000
}
  • Member ๊ด€๊ณ„: workspace์—์„œ ๋‘ package๋ฅผ ํ•จ๊ป˜ ๊ด€๋ฆฌํ•œ๋‹ค.
  • Dependency ๊ด€๊ณ„: app์ด pricing library๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ด€๊ณ„๋Š” app/Cargo.toml์— ๋ณ„๋„๋กœ ์„ ์–ธํ•œ๋‹ค.
  • ๊ฒฝ๋กœ ๊ธฐ์ค€: path = "../pricing"์€ ์„ ์–ธํ•œ app/Cargo.toml์˜ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•ด์„ํ•œ๋‹ค.
cargo run -p app --bin app
cargo run -p app --bin quote
cargo check --workspace
  • ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰: -p app์€ package๋ฅผ ์„ ํƒํ•˜๊ณ  --bin app, --bin quote๋Š” ๊ทธ ์•ˆ์˜ ์‹คํ–‰ ํ”„๋กœ๊ทธ๋žจ์„ ์„ ํƒํ•œ๋‹ค. ์ฃผ๋ฌธยท๊ฒฌ์  ์ถœ๋ ฅ์€ 4์ ˆ๊ณผ ๊ฐ™๋‹ค.
  • ์ „์ฒด ๊ฒ€์‚ฌ: workspace์˜ member๋ฅผ ํ•œ ๋ฒˆ์— ๊ฒ€์‚ฌํ•œ๋‹ค.
workspace: shop-workspace
โ”œโ”€โ”€ package: app
โ”‚   โ”œโ”€โ”€ binary crate: src/main.rs
โ”‚   โ””โ”€โ”€ binary crate: src/bin/quote.rs
โ””โ”€โ”€ package: pricing
    โ””โ”€โ”€ library crate: src/lib.rs
        โ””โ”€โ”€ module: calculation
 
binary crate app   โ”€โ”€ dependency โ”€โ”€> library crate pricing
binary crate quote โ”€โ”€ dependency โ”€โ”€> library crate pricing
  • ํฌํ•จ ๊ด€๊ณ„: tree๋Š” workspace์˜ package ๊ตฌ์„ฑ, package์˜ crate, crate ๋‚ด๋ถ€ module์„ ๋ณด์—ฌ์ค€๋‹ค.
  • ์‚ฌ์šฉ ๊ด€๊ณ„: ์•„๋ž˜ ํ™”์‚ดํ‘œ๋Š” ๋‘ binary๊ฐ€ library์— ์˜์กดํ•˜๋Š” ๋ฐฉํ–ฅ์ด๋‹ค. Workspace์— ํฌํ•จ๋˜๋Š” ๊ฒƒ๊ณผ library๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋ณ„๋„ ๊ด€๊ณ„๋‹ค.

Workspace ์„ค์ •: ๊ณต์œ ๋˜๋Š” ๊ฒƒ๊ณผ ๋ณ„๋„์ธ ๊ฒƒ

  • ๊ธฐ๋ณธ ๊ณต์œ : Cargo workspace ์„ค์ •์— ๋”ฐ๋ผ root์˜ Cargo.lock๊ณผ target ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค.
  • ๋ณ„๋„ ๊ด€๋ฆฌ: ๊ฐ package๋Š” ์ž์‹ ์˜ Cargo.toml๊ณผ dependency ๋ชฉ๋ก์„ ์œ ์ง€ํ•œ๋‹ค.
  • ์„ ํƒ์  ๊ณต์œ : ๋ฒ„์ „ยทedition ๋“ฑ์€ workspace.package, ๊ณตํ†ต dependency๋Š” workspace.dependencies๋กœ ์ •์˜ํ•˜๊ณ  member์—์„œ ๋ช…์‹œ์ ์œผ๋กœ ์ƒ์†ํ•œ๋‹ค. ์ด ์˜ˆ์ œ์—์„œ๋Š” ๊ฐ package์— ์ง์ ‘ ์ ์—ˆ๋‹ค.

Python ๋น„๊ต: workspace๋Š” uv์˜ ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ์— ๋Œ€์‘

  • ํ”„๋กœ์ ํŠธ ๋ถ„๋ฆฌ: uv workspace์˜ member๋„ ๊ฐ๊ฐ pyproject.toml์„ ์œ ์ง€ํ•˜๋ฉฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๊ณ„์‚ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.
  • ๊ณต์œ  ์„ค์ •: uv๋Š” [tool.uv.workspace]๋กœ member๋ฅผ ์ง€์ •ํ•˜๊ณ  ํ•˜๋‚˜์˜ uv.lock์„ ๊ณต์œ ํ•œ๋‹ค. Rust ์˜ˆ์ œ์˜ [workspace]์™€ Cargo.lock์— ๋Œ€์‘ํ•˜๋Š” ์—ญํ• ์ด๋‹ค.
  • ๋„๊ตฌ์˜ ๊ธฐ๋Šฅ: uv workspace๋Š” Python ์–ธ์–ด ์ž์ฒด์˜ ๊ธฐ๋Šฅ์ด ์•„๋‹ˆ๋ผ ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ ๋„๊ตฌ์˜ ๊ธฐ๋Šฅ์ด๋‹ค. Cargo์ฒ˜๋Ÿผ member ๊ด€๊ณ„์™€ ์‹ค์ œ dependency ๊ด€๊ณ„๋ฅผ ๋”ฐ๋กœ ์„ ์–ธํ•œ๋‹ค.

6. ๊ณ„์‚ฐ ํ…Œ์ŠคํŠธ๋ฅผ library์— ๋‘๊ณ  ํ•จ๊ป˜ ์‹คํ–‰ํ•œ๋‹ค

๊ฐ€๊ฒฉ ๊ทœ์น™์˜ ํ…Œ์ŠคํŠธ๋ฅผ CLI์™€ ๋ถ„๋ฆฌํ•˜๋ฉด ์ถœ๋ ฅ ์ฒ˜๋ฆฌ ์—†์ด ๊ณ„์‚ฐ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•œ๋‹ค. pricing/src/lib.rs ๋์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

#[cfg(test)]
mod tests {
    use super::total;
 
    #[test]
    fn shipping_threshold() {
        assert_eq!(total(1000, 3), 3300);
        assert_eq!(total(1000, 5), 5000);
    }
}
  • mod tests: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋„ library ์•ˆ์˜ module์ด๋‹ค.
  • super::total: ๋ถ€๋ชจ module์ธ library root๊ฐ€ ๊ณต๊ฐœํ•œ ๊ณ„์‚ฐ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • ํ™•์ธํ•  ๊ทœ์น™: 5,000 ๋ฏธ๋งŒ์—๋Š” ๋ฐฐ์†ก๋น„๋ฅผ ๋ถ™์ด๊ณ  ๊ฒฝ๊ณ„ ๊ธˆ์•ก๋ถ€ํ„ฐ๋Š” ๋ฐฐ์†ก๋น„๋ฅผ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.
cargo test -p pricing
cargo test --workspace

์ฒซ ๋ช…๋ น์€ ๊ณ„์‚ฐ package๋ฅผ ์„ ํƒํ•˜๊ณ  ๋‘˜์งธ ๋ช…๋ น์€ member ์ „์ฒด์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. Library์˜ ๊ณ„์‚ฐ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ์ด ํ…Œ์ŠคํŠธ์™€ app์˜ ์‚ฌ์šฉ ์ฝ”๋“œ๋ฅผ ๊ฐ™์€ workspace์—์„œ ํ™•์ธํ•œ๋‹ค.

Python ๋น„๊ต: ๊ณ„์‚ฐ ํ•จ์ˆ˜ ํ…Œ์ŠคํŠธ์™€ ์‹คํ–‰ ํ”„๋กœ๊ทธ๋žจ ๋ถ„๋ฆฌ

  • ํ…Œ์ŠคํŠธ ์œ„์น˜: test_pricing.py์—์„œ ๊ณตํ†ต total ํ•จ์ˆ˜๋ฅผ importํ•˜๊ณ  ๊ณ„์‚ฐ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐฉ์‹๊ณผ ๋น„์Šทํ•˜๋‹ค.
  • ๊ตฌ์กฐ ์„ ํƒ: Python์€ import ๊ฐ€๋Šฅํ•œ ํ•จ์ˆ˜๋งŒ ์žˆ์–ด๋„ ํ…Œ์ŠคํŠธํ•œ๋‹ค. Rust๋„ binary ๋‚ด๋ถ€ module์— unit test๋ฅผ ๋‘˜ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด ์˜ˆ์ œ์—์„œ๋Š” ์—ฌ๋Ÿฌ binary๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” library API๋ฅผ ๊ฒ€์‚ฌํ•œ๋‹ค.

7. ๊ตฌ์กฐ๋Š” ํ•„์š”ํ•œ ๊ฒฝ๊ณ„๋ถ€ํ„ฐ ๋‚˜๋ˆˆ๋‹ค

์˜ˆ์ œ์˜ ๊ณ„์‚ฐ ์ฝ”๋“œ๋Š” 2์ ˆ๋ถ€ํ„ฐ ๊ฐ™์€ ๊ทœ์น™์„ ์œ ์ง€ํ–ˆ๋‹ค. ์ดํ›„ ํ™•์žฅ์€ ๊ตฌํ˜„ ์œ„์น˜, ๊ณต๊ฐœ API, ์ปดํŒŒ์ผ ๋‹จ์œ„, Cargo ๊ด€๋ฆฌ ๋‹จ์œ„๋ฅผ ๋ฐ”๊พธ๋Š” ๊ณผ์ •์ด์—ˆ๋‹ค.

๋‹จ๊ณ„Package ์ˆ˜์ฃผ๋œ crate ์ˆ˜์ถ”๊ฐ€ํ•œ ๊ฒฝ๊ณ„ํ•„์š”ํ•œ ์ด์œ 
ํ•จ์ˆ˜ ํ•˜๋‚˜1Binary 1ํ•จ์ˆ˜๊ฐ„๋‹จํ•œ ๊ณ„์‚ฐยท์ถœ๋ ฅ
Inline module1Binary 1Module์˜ ๊ณต๊ฐœ ๋ฒ”์œ„๋‚ด๋ถ€ ๋ฐฐ์†ก๋น„ ๊ณ„์‚ฐ ์ˆจ๊น€
Module ํŒŒ์ผ ๋ถ„๋ฆฌ1Binary 1ํŒŒ์ผ๊ณ„์‚ฐ ์ฝ”๋“œ์™€ CLI๋ฅผ ๋”ฐ๋กœ ์ฝ๊ณ  ์ˆ˜์ •
Library ์ถ”์ถœ1Library 1 + Binary 2Crate์ฃผ๋ฌธยท๊ฒฌ์  ํ”„๋กœ๊ทธ๋žจ์ด ๊ณตํ†ต ๊ณ„์‚ฐ API ์‚ฌ์šฉ
Workspace ๊ตฌ์„ฑ2Library 1 + Binary 2Package, workspace๊ฐœ๋ณ„ ์„ค์ •๊ณผ ์ „์ฒด ๋นŒ๋“œยทํ…Œ์ŠคํŠธ ๋ณ‘ํ–‰

ํ‘œ์˜ crate ์ˆ˜: ๊ตฌํ˜„์˜ ์ฃผ๋œ ๊ฒฝ๊ณ„ ๊ธฐ์ค€

  • ์ง‘๊ณ„ ๋ฒ”์œ„: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ธฐ๋ณธ libraryยทbinary๋ฅผ ์…Œ๋‹ค.
  • ํ…Œ์ŠคํŠธ ๋Œ€์ƒ: Cargo๊ฐ€ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ๋“ฑ์— ๋งŒ๋“œ๋Š” ์ถ”๊ฐ€ target์€ ํ‘œ์—์„œ ์ œ์™ธํ–ˆ๋‹ค.