프로그래밍 언어에서의 함수란?
함수는 프로그래밍에서 특정 작업을 수행하는 코드 블록으로,
1. 재사용 가능하고
2. 모듈화 된 단위입니다.
3. 함수를 사용하면 코드의 가독성과 유지보수성이 높아지고,
4. 중복 코드를 줄일 수 있어 효율적입니다.
당연히 Rust에서도 함수를 구현할 수 있는 문법을 제공합니다.
C, C++의 함수
int add(int a, int b){
..
}
C, C++에서 "add" 라는 함수를 정의하면 위와 같이 정의합니다.
이때 이 "add" 라는 함수의 행동을 정의하고 싶다면 { } 사이에 원하는 구문을 삽입합니다.
예를 들어
return a + b;
와 같은 구문을 넣을 수 있을 겁니다.
이때, return 하고자 하는 값의 type을 함수 이름 앞에,
함수의 연산에 사용될 인자를 함수 이름 뒤 괄호에 포함시킵니다.
즉, 구조상으로 이게 함수라는 걸 아는 거지,
명시적으로 이게 함수다, 라고 말하는 표현법이 없습니다.
Rust의 함수
Rust는 "fn" 예약어를 통해 이게 함수라는 걸 명시합니다.
예시로, 두 개의 unsigned 32bit 정수를 받고, boolean 값을 return 하는
함수를 정의해보겠습니다.
fn is_divisible_by(lhs: u32, rhs: u32) -> bool {
if rhs == 0 {
return false;
}
lhs % rhs == 0
}
"is_divisible_by" 라는 이름의 함수로 두 개의 u32 인자 lhs, rhs를 받고
boolean 값을 return 하는 함수입니다.
divide_by_zero error를 피하기 위해 분모가 0인지 확인하고,
lhs % rhs == 0을 return 하는 모습입니다.
왜 함수 block 마지막에 return과, 세미 콜론이 없냐면,
[Rust] Expression
Expression Rust를 포함하고, 여러 프로그래밍 언어의 소스코드는 여러 구문으로 구성되어있습니다. 예를 들어, C++의 swap 연산은 아래와 같습니다. #include // 템플릿을 사용한 swap 함수template void sw
swc0317.tistory.com
위의 포스트를 참조해 주세요.
Rust의 void 형 return
C/C++에서 함수 내부에서 return 하는 값이 없다면
void 예약어를 통해 "return 하지 않는다"를 명시합니다.
void print(string S){
..
}
Rust에선 void 형이 없습니다. 대신 () 라는, 빈 튜플을 return 하는 걸
void 형으로 명시합니다.
[Rust] 기본 골자
Rust의 타입형들 Rust learn by example Primitives - Rust By ExampleRust provides access to a wide variety of primitives. A sample includes: Signed integers: i8, i16, i32, i64, i128 and isize (pointer size) Unsigned integers: u8, u16, u32, u64, u128
swc0317.tistory.com
또는, 의도적으로 누락할 수 있습니다.
fn fizzbuzz(n: u32) -> () {
if is_divisible_by(n, 15) {
println!("fizzbuzz");
} else if is_divisible_by(n, 3) {
println!("fizz");
} else if is_divisible_by(n, 5) {
println!("buzz");
} else {
println!("{}", n);
}
}
fn fizzbuzz_to(n: u32) {
for n in 1..=n {
fizzbuzz(n);
}
}
위 함수는 1부터 n까지 fizzbuzz라는 함수를 실행하는 함수입니다.
이때 return이 없다는 걸 위처럼 -> ()를 누락할 수도 있고,
명시할 수도 있습니다.
Associated function & Method
Method, 메소드는 파이썬을 해보셨다면 익숙하실겁니다.
def block_read(self, address):
# 읽어올 32byte(8개의 워드)를 담을 리스트
# address엔 tag 24bit + cache idx 3bit을 포함한 상위 27비트가 담겨있음.
# 하위 2bit는 32bit data aligned를 이용하므로
# 4의 배수 단위로 0 ~ 28까지 메모리를 접근해주면 OK.
data_block = []
for offset in range(0, 32, 4):
word_address = address + offset
data_block.append(self.mem[word_address])
return data_block
위의 함수는 메모리를 block 단위로 읽어오는 함수입니다.
이때, 현재 object 타입에 정의된 "특정한" 함수를
현재 객체에 실행하고 싶다면 "." 을 통해 명시합니다.
즉, 메소드란 어떤 객체가 특정한 타입을 가질 때, 명시된
연산을 인자로 삽입할 필요없이 "현재 객체에 연산하라"를
함축합니다.
Associated Function은 Method와 유사하게,
"특정 타입에 연관된 함수" 입니다. 그러나,
함수 연산에 객체를 받지않습니다. 즉
둘의 명시적인 차이는 인자로 self가 포함되느냐 아니냐 입니다.
예시입니다.
struct Point {
x: f64,
y: f64,
}
impl Point {
fn origin() -> Point {
Point { x: 0.0, y: 0.0 }
}
fn new(x: f64, y: f64) -> Point {
Point { x: x, y: y }
}
}
struct Rectangle {
p1: Point,
p2: Point,
}
impl Rectangle {
fn area(&self) -> f64 {
let Point { x: x1, y: y1 } = self.p1;
let Point { x: x2, y: y2 } = self.p2;
((x1 - x2) * (y1 - y2)).abs()
}
fn perimeter(&self) -> f64 {
let Point { x: x1, y: y1 } = self.p1;
let Point { x: x2, y: y2 } = self.p2;
2.0 * ((x1 - x2).abs() + (y1 - y2).abs())
}
fn translate(&mut self, x: f64, y: f64) {
self.p1.x += x;
self.p2.x += x;
self.p1.y += y;
self.p2.y += y;
}
}
먼저 두 개의 double precision 소수 타입으로 구성된 Point 구조체와,
이 Point 타입 두 개로 이루어진 Rectangle 구조체입니다.
이때 impl 예약어 아래 정의된 함수들은,
앞서말한 Associated function & Method로,
해당 구조체에 특정한 연산을 할 수 있는 함수들을
구현해놓은 Implemetation block 입니다.
이때 origin, new 함수들은 self가 포함되지 않으니,
associated function,
area, perimeter, traslate은 인자에 self가 포함되니,
method 함수입니다. 단순히
인자로 구분하는 것 뿐만 아니라 실제 사용법도 다릅니다.
아래는 assoicated function을 사용하는 예제입니다.
fn main() {
let rectangle = Rectangle {
p1: Point::origin(),
p2: Point::new(3.0, 4.0),
};
}
보시면 각 Point 인자들을 정의하기 위해 origin, new 함수를 쓰되,
특정한 객체없이 함수를 사용합니다.
아래는 Method 함수를 사용하는 예재입니다.
println!("Rectangle perimeter: {}", rectangle.perimeter());
println!("Rectangle area: {}", rectangle.area());
square.translate(1.0, 1.0);
pair.destroy();
보시면 특정 타입의 실체 객체가 있어야 사용할 수 있는 함수들입니다.
'프로그래밍 언어 > [Rust]' 카테고리의 다른 글
[Rust] ToolChain Nightly (1) | 2025.02.15 |
---|---|
[Rust] Closures (0) | 2025.02.09 |
[Rust] Expression (0) | 2025.01.07 |
[Rust] Type Conversion (0) | 2025.01.07 |
[Rust] Types (1) | 2025.01.03 |