5강에서 함수 는 작업을 수행하거나 입력에 기반하여 출력을 생성하기 위한 인스트럭션을 제공하는 재사용 가능한 코드 라고 배웠습니다.
함수를 정의하려면 고유한 식별자 , 결과로 예상되는 정보의 타입 , 함수가 수행할 기능의 세 가지 핵심 부분을 제공해야 합니다.
함수 정의하기
함수 시그니처
3강에서는 변수 또는 상수의 이름을 지정하고 사용할 값의 타입을 부여하여 변수 또는 상수를 선언 하는 방법을 배웠습니다.
함수 시그니처(function signature) 도 비슷한 방식으로 사용합니다. 함수 시그니처는 함수에 고유한 식별자(identifier) , 함수에 필요한 입력을 설명하는 파라미터(parameters) , 결과(출력)의 반환 타입(return type) 을 사용합니다.
실제로 함수가 하는 작업은 코드 블록 에서 정의됩니다.
코드 블록
코드 블록(code block) 은 함수 시그니처 이후에 따라오는 표현식 의 그룹입니다. 이는 함수 및 코드 블록에 대한 구문입니다.
name() : type =
코드 블록
코드 블록의 포맷은 여러 가지 방법으로 지정할 수 있습니다. 한 가지 방법으로는 식별자 다음에 코드 줄을 들여쓰기하는 것이 있습니다. 위의 함수 구문에서 이러한 방법을 확인할 수 있습니다. (나중에 코드 블록을 설정하는 방법을 자세히 배울 예정이지만, 지금은 이 방법을 사용하면 됩니다.)
코드 블록의 표현식은 함수가 호출되었을 때 실제로 하는 작업을 정의합니다.
이러한 표현식은 함수가 호출되었을 때만 실행됩니다. 프로그램이 코드 블록의 마지막에 도달하면 이러한 표현식은 최소한 그 함수가 다음에 호출되기 전까지는 완료되며, 프로그램은 함수 호출 이후의 다음 코드 비트를 실행합니다.
바디
코드 블록은 함수가 하는 작업을 정의할 때 바디(body) 라는 이름으로도 부릅니다.
스코프
지금까지 배운 내용은 다음과 같습니다.
- 함수에는 프로그램에서 작업을 하도록 함수를 활성화하는 데 사용하는 고유한 식별자가 있습니다.
- 함수가 하는 작업은 함수 바디의 표현식에 따라 달라집니다.
- 바디의 마지막 코드 줄이 완료되면 함수 호출이 완료되며, 프로그램은 프로그램에 있는 함수 호출 다음의 코드 줄로 이동합니다.
함수의 스코프(scope) 는 해당 함수의 인스트럭션과 함수에서 도출되는 모든 값에 의해 결정됩니다.
이제 함수를 정의하기 위해 사용할 수 있는 표현식으로 돌아가겠습니다. 3강에서 알아보았던 상수와 변수를 생성하고 함수 바디에 추가할 수 있습니다.
바디에 변수를 추가하면 함수 스코프에 대해 로컬 이 됩니다. 로컬 이란 코드가 해당 바디 내에 있고 해당 바디 내에서만 작동하며 함수가 호출될 때만 작동한다는 의미입니다.
그렇다면 스코프 란 무엇일까요? 스코프란 함수 이름과 함수에 의해 생성되는 값의 연결 입니다. 이 값은 값이 생성된 코드 블록 또는 해당 스코프 내에서만 사용할 수 있습니다.
인스턴스화
인스턴스 는 호출 및 실행되는 해당 함수의 고유한 사용 사례입니다. 인스턴스의 생성을 인스턴스화(instantiation) 라고 합니다. 인스턴스와 인스턴스화는 모두 매우 짧은 시간을 뜻하는 instant 라는 단어와 관련이 있습니다.
또한 이에 따라 수명 개념이 발생합니다.
수명
인스턴스에는 시작, 중간, 종료로 구성된 수명(lifetime) 이 있습니다.
즉, 함수 바디 내용의 수명 은 바디의 스코프 에 의해 제한되며, 스코프 밖에서는 로컬 변수(이 현재 스코프로 제한되는 변수)에 액세스할 수 없습니다.
조건부
다음 예시에서는 플레이어가 가진 코인 수로 구매 가능한 쥐덫의 최대 개수를 계산하는 방법을 보여줍니다.
상수 MousetrapsYouCanBuy 는 if 블록 내에서 생성되므로 스코프가 if 블록으로 제한됩니다.
상수 MaxMousetrapsYouCanBuy 가 if 코드 블록 바깥에서 사용되면 오류가 생깁니다. 해당 스코프 밖에는 MaxMousetrapsYouCanBuy 라는 이름이 존재하지 않기 때문입니다. 오류 메시지로 알 수 없는 식별자 가 표시됩니다. 이처럼 MaxMousetrapsYouCanBuy 는 해당 스코프 내에서만 유효합니다.
표현식이 완료되면 그 바디 안에서 생성된 로컬 상수와 로컬 변수는 더 이상 존재하지 않습니다. 수명이 다한 것입니다.
스코프 는 항목이 수명이 다할 때까지 작동하는 작은 코드 청크라고 생각하면 이해하기 쉽습니다.
함수 구문
이번에는 함수 구문을 좀 더 심층적으로 다시 살펴보겠습니다.
name() : type =
코드 블록
name() : type = |
이것이 함수 시그니처 입니다. 함수 시그니처에는 사용될 입력의 타입 이 포함됩니다. 함수가 반환하는 값 ( |
codeblock |
함수 코드 블록 즉 바디 는 함수가 호출되었을 때 하는 작업 을 나타내기 위해 상수, 변수, 기타 표현식을 추가하는 곳입니다. |
예를 들어, 쥐덫을 구매하기 위해 가격을 지불하는 함수는 다음과 같습니다.
var Coins : int = 500
CoinsPerMousetrap : int = 100
BuyMousetrap() : void =
set Coins = Coins - CoinsPerMousetrap
Print("Mousetrap bought! You have {Coins} coins left.")
함수 이름의 명명 규칙은 변수 및 상수에 사용하는 명명 규칙과 동일합니다. 함수는 작업의 시퀀스를 수행하므로, BuyMousetrap() 처럼 함수가 수행하는 작업을 반영하는 방식으로 명명하는 것이 좋습니다.
Void
BuyMousetrap() 의 함수 시그니처에 void 가 포함된 것을 보셨을 겁니다. 함수의 void 타입이란 그 함수를 호출해도 아무것도 반환되지 않는다는 의미입니다. 다음 수업에서 'void'에 대해 자세히 알아보고 사용 방법도 살펴보겠습니다.
중복 배제
프로그래밍의 중요한 원리는 중복 배제 입니다.
동일한 코드 줄을 세 번 이상 반복 작성하고 있다면, 다른 방법을 고려해야 한다는 뜻입니다. 물론 여기에는 이유가 있습니다!
작성하는 코드의 줄이 늘어날수록 코드를 관리하기 힘들어지며, 필연적으로 한곳의 코드를 변경하고 다른 곳의 코드는 변경하지 않게 되므로 결국에는 버그가 발생할 가능성이 높습니다.
함수는 상수와 마찬가지로 반복할 필요가 없는 코드를 반복하지 않게 해 줍니다. 따라서 함수를 사용하면 코드를 반복할 필요가 없을 뿐만 아니라, 유지보수가 더 수월해지고, 오류가 있는 코드를 작성할 확률도 줄어듭니다.
코드를 작성할 때는 대소문자에 유의하세요. 표현식 및 함수를 명명할 때와 키워드 및 내장 함수를 사용할 때 모두 유의해야 합니다. Verse는 대소문자를 구분하며, 대소문자를 올바르게 일관적으로 사용하지 않으면 버그와 컴파일 오류가 발생할 수 있습니다.
요약
- 함수 는 재사용 가능한 코드로, 작업을 수행하거나 입력에 기반하여 출력을 생성하는 인스트럭션을 제공합니다.
- 함수는 세 가지 부분으로 이루어지는데, 식별자 , 타입 , 그리고 함수가 호출되었을 때의 결과 가 포함되는 코드 블록 입니다.
- 함수는 함수 시그니처 에 의해 호출됩니다.
- 코드 블록이 함수가 하는 작업을 정의할 때는 바디라고 부르기도 합니다.
- 스코프 는 해당 함수와 연결된 값을 참조하며, 이에 따라 코드 블록의 콘텐츠에 의해 정의됩니다.
- 코드 블록에 포함된 코드는 해당 스코프에 대해 로컬 입니다.
- 수명 은 스코프의 기간입니다.
- 중복 배제 를 기억하세요.