프로그래밍에서 함수의 인자로 값을 전달할 때, 전달 방식에 따라 Call by Value와 Call by Reference로 나눌 수 있다. 이는 값의 복사 여부와 메모리에서의 동작 방식에 차이를 만든다.
Call by Value는 인자의 값을 복사하여 함수에 전달하는 방식이다. 이 방식에서는 함수 내부에서 값을 변경하더라도 원본 변수에는 영향을 미치지 않는다.
func changeValue(_ num: Int) {
var num = num
num = 10
print("함수 내부 값: \(num)")
}
var myNumber = 5
changeValue(myNumber)
print("함수 호출 후 원본 값: \(myNumber)")
함수 내부 값: 10
함수 호출 후 원본 값: 5
함수 내부에서 num
의 값을 변경했지만, 이는 복사된 값이므로 myNumber
의 값은 그대로 유지된다.
Call by Reference는 변수의 메모리 주소(참조)를 전달하는 방식이다. 따라서 함수 내부에서 변경된 값이 원본 변수에도 반영된다.
Swift에서는 기본적으로 값 타입(value type, struct)이기 때문에 inout
키워드를 사용해야 참조로 전달할 수 있다.
func changeValue(_ num: inout Int) {
num = 10
print("함수 내부 값: \(num)")
}
var myNumber = 5
changeValue(&myNumber)
print("함수 호출 후 원본 값: \(myNumber)")
함수 내부 값: 10
함수 호출 후 원본 값: 10
inout
키워드를 사용해 num
을 참조 타입으로 전달했기 때문에, 함수 내부에서 변경한 값이 원본 변수에도 적용되었다.
비교 항목 | Call by Value | Call by Reference |
---|---|---|
전달 방식 | 값 복사 | 참조(메모리 주소) 전달 |
원본 데이터 영향 | 없음 | 있음 |
성능 | 상대적으로 느림 (복사 비용 발생) | 상대적으로 빠름 (복사 없음) |
Swift에서 기본 적용 | struct , enum | class , inout |
Swift에서는 대부분의 기본 타입(Int, String, Array 등)이 구조체(struct)로 되어 있기 때문에 기본적으로 Call by Value로 동작한다.
그러나 class
타입을 사용하거나 inout
키워드를 적용하면 참조 타입(Call by Reference)처럼 동작할 수 있다.
class Person {
var name: String
init(name: String) {
self.name = name
}
}
func changeName(_ person: Person) {
person.name = "새로운 이름"
}
var user = Person(name: "소담")
changeName(user)
print("변경된 이름: \(user.name)")
변경된 이름: 새로운 이름
클래스는 참조 타입이기 때문에 함수 내부에서 변경된 값이 원본 객체에도 반영되었다.
class
나 inout
을 이용하면 Call by Reference처럼 동작할 수 있다.