Computational Design
함수를 호출할 때, 전달인자(argument)를 같이 보내줘야 하는 경우가 있죠. - link
이 경우 두 가지를 생각해 볼 수 있어요. Call by value (값에 의한 호출)과 Call by reference (참조에 의한 호출)이 그것이죠.
이 개념을 왜 이해해야 할까요?
1) 알고리듬을 작성할 수 없기 때문에
인풋과 아웃풋의 데이터 흐름을 디자인할 때, 함수가 어떻게 호출이 되고, 값이 어떻게 업데이트가 되는지 모르면 프로그래밍 자체를 할 수 없죠!
2) 메모리와 속도의 최적화 문제
처음 시작하는 디자이너분들은, 지금 단계에서 고민할 필요는 없지만, 나중에, 실제 애플리케이션을 구현할 때, 컴퓨팅 속도와 메모리 공간의 최적화를 이해할 수 있게 되죠. 가령 쓸 때 없이, 함수 내부에서 복제가 일어나 시간과 메모리의 사용이 과다해질 수 있게 때문이죠. 반대로, 원본 값이 수정되어 결괏값이 잘못 나오는 경우도 생기죠.
일반적으로
포인터를 사용하는 c 혹은 c++의 경우에는 명시적으로 참조 혹은 값으로 보낼 수 있죠. 하지만 여러분의 대부분은, 가비지 콜렉터가 작동하는 모던 언어를 주로 사용하여 코딩을 시작하는 디자이너 분들에게는, 굳이 지금 이해할 필요는 없어요.
일반적으로,
숫자 int / float/ double
문자 char / string
논리 bool
의 경우 함수에서 값을 복사하여 내부적인 스콥에서 사용하게 되죠. 결국 어떠한 계산이 일어나더라도, 원본 값에는 영향을 미치지 않는 것이 포인트입니다! 즉 복제된 값에 의한 호출을 한 것이죠.
public int Increase(int data){
data++;
return data;
}
int myNum = 2;
Increase(myNum);
Console.WriteLine("By value : " + myNum.ToString()); // By value : 2
int yourNum = 2;
yourNum = Increase(yourNum);
Console.WriteLine("By value : " + yourNum.ToString()); // By value : 3
하지만,
클래스 class
오브젝트 object
배열 array, list
열거 enum
인터페이스 interface
이번엔 오브젝트의 경우에는, 함수에서 값을 수정하면, 원본 값이 수정되는 것을 알 수 있죠? 참조가 발생했기 때문이죠. 즉 메모리의 주소 자체가 넘어가 버린 것이죠. 따라서 함수 안에서 그 주어진 데이터를 업데이트하면, 원본 데이터에 영향을 미치게 되는 것이죠!
public List<int> Increase(List<int> data){
data[0]++;
return data;
}
public List<int> IncreaseByValue(List<int> data){
List<int> dataNew = new List<int>();
dataNew.Add(data[0] + 1);
return dataNew;
}
List < int> myNum = new List<int>(){2};
Increase(myNum);
Console.WriteLine("By ref : " + myNum[0].ToString()); // By ref : 3
List < int> youNum = new List<int>(){2};
IncreaseByValue(youNum);
Console.WriteLine("By value : " + youNum[0].ToString()); // By value : 2
Class 예제
public class Person {
public int age = 2;
public double height = 90;
}
public Person Increase(Person data){
data.age++;
return data;
}
public Person IncreaseByValue(Person data){
Person p = new Person();
p.age = data.age + 1;
return data;
}
Person p0 = new Person();
Increase(p0);
Console.WriteLine("By ref : " + p0.age.ToString()); // By ref : 3
Person p1 = new Person();
IncreaseByValue(p1);
Console.WriteLine("By value : " + p1.age.ToString()); // By ref : 2
* 그라스하퍼는 일반적으로 by value로 볼 수 있어요.(몇몇 클래스 베이스는 by reference 죠)
* c 혹은 c++의 환경에서는 더 복잡한 컨디션이 있을 수 있어요.
* 주어가 함수일 때는 Called by, 인수일 때는 Passed by라고 하네요.
* 기본적인 개념을 이해한 후, 더 깊이 있는 내용은,
최적화시키고자 하는 상황에 맞는, 더 자세한 문서를 참조해주세요.
혹시 잘못된 내용 있으면 댓글로 지적 부탁드립니다.
감사합니다!
DATA & DESIGN 컴퓨테이셔널 디자인 바로가기