🍎 이번 포스팅의 주제
1) 함수 표기법/ 함수의 타입 표기
2) 함수의 오버로딩
3) 스코프
기존에 우리가 알고있는 함수의 정의문(선언문)과, 실행문의 표현은 각각 다음과 같다.
// 정의문
func addNums (_ nums : Int...)->Int{
var sum = 0
for i in nums {
sum += i
}
return sum
}
// 실행문
addNums(1,2,3,4,5)
이러한 정의문, 그리고 실행문과는 별개로, 함수를 ‘지칭’ 하는 경우 사용하는 ‘함수 표기법’이 별도로 필요하다.
💡 그렇다면 함수표기법이 필요한 사례에는 무엇이 있을까?
1) 개발자 문서를 읽을 때
-> 애플 개발자 문서에서 함수를 지칭할 때 함수 표기법이 사용된다.
2) 함수를 특정 변수에 할당할 때
-> 함수 자체를 변수에 할당하는 경우.
함수는 아래와 같이, 그 형태에 따라 다른 방식으로 표기한다.
// 1. 파라미터가 없는 함수
func doSth() -> Void{
print("hello")
}
var some :()->() = doSth // 함수 표기법
doSth
함수와 같이 파라미터가 없는 함수의 경우, 괄호를 생략 하고, doSth
와 같이 함수명만 남기는 방식으로 표기한다.
이때, doSth은 some 이라는 변수에 할당되었으므로, some을 실행함으로서 doSth을 실행할 수 있다.
some() // doSth() 와 같은 의미.
// 2. 아규먼트 레이블이 있는 파라미터를 가지는 경우
func isTrue(bool : Bool){
if bool {
print("true")
}
else {
print("false")
}
}
var some2 = isTrue(bool:) // 표기법, 묵시적 할당 (타입추론)
isTrue
함수와 같이, 아규먼트 레이블이 있는 파라미터를 가지는 함수의 경우, isTrue(bool:)
과 같이, 함수 이름과 아규먼트 레이블(콜론 포함)로 표기한다.
// 3. 파라미터가 여러개인 함수의 경우
func chooseStepFunction(gobackward : Bool, value : Int) -> Int {
func stepForward(_ input : Int) -> Int {
return input+1
}
func stepBackward(_ input : Int) -> Int {
return input-1
}
if gobackward {
return stepBackward(value)
}
else {
return stepForward(value)
}
}
var some3 = chooseStepFunction(gobackward: value:)
// 함수표기법
chooseStepFunction
함수와 같이 파라미터가 여러개인 함수의 경우, chooseStepFunction(gobackward: value:)
와 같이 콤마 없이 함수명, 아규먼트 레이블들 만으로 표기한다.
이때 아래와 같이 파라미터가 여러개인 함수가 와일드카드 패턴으로 표현되었을 경우에도
// 4. 파라미터가 여러개인 함수의 경우 ~ 와일드카드 패턴
func printFullname(_ first : String, _ last : String)->Void{
print(first+last)
}
var some4 = printFullname(_:_:) // some4는 이미 선언된 printFullname 함수 이다.
// 함수표기법
마찬가지로, printFullname(_:_:)
와 같이 함수명, 와일드카드패턴의 아규먼트 레이블들로 표기한다.
위에서 예시로 소개한 함수를 다시 차례대로 변수에 할당한다면, 명시적으로 표기했을때 다음과 같다.
var fType1 : ()->() = doSth // ()->Void 도 가능
var fType2 :(Bool)->() = isTrue(bool: )
var fType3 : (Bool,Int)->Int = chooseStepFunction(gobackward:value:)
var fType4 : (String,String)->() = printFullname(_:_:)
위 처럼, 함수가 할당되는 변수의 타입을 명시적으로 표기할때, 함수의 입력 타입과 리턴타입을 정확히 적어준다.
오버로딩이란, 함수의 이름을 재사용하는것으로, 같은 함수의 이름에 여러개의 함수를 대응시키는 방식이다.
비슷한 기능을 하는 함수의 이름을 굳이 다르게 해서 전부 숙지해야 하는 수고로움을 덜어준다는 이점이 있다. (ex) tableView 함수)
Swift는 오버로딩을 지원하는 언어로, 함수명
, 파라미터의 수
와 자료형
, **아규먼트 레이블**
, 리턴형
이 전부 같아야 서로 같은 함수로 인식 하기 때문에, 이 모든 요소들이 동일하지 않다면, 이미 선언된 함수의 이름을 사용해 새로운 함수를 선언 가능하다.
// 오버로딩 예시
func doSomething (input : Int ){
print(input)
}
func doSomething(val : Int){
print(val)
}
func doSomething (_ input : Int){
print(input)
}
// 위와 같이, 파라미터의 자료형과 수가 동일하더라도, 아규먼트 레이블이 다르기 때문에 오버로딩 가능
func doSomething (input : Double ){
print(input)
} // 파라미터 자료형이 다르기 때문에 오버로딩 가능
스코프란, 코드 내에서 같은 중괄호{} 범위 내에서 작성되는 코드 범위 이다.
스코프에 대한 중요 원칙은 다음과 같다.
💡 스코프 주요 원칙
1. 변수는 코드에서 선언이 되어야지 접금 가능하다.(선언하기 이전에는 접근 불가) (전역변수는 예외.)
코드는 순차적으로 실행되기 때문에, 코드상에서 변수 접근에 앞서, 변수 선언이 이루어져야한다.
2. 상위 스코프에 선언한 변수 및 상수에 접근 가능하며, 하위 스코프에는 접근이 불가능
`상위스코프{ 하위스코프 }`
3. 동일한 스코프에서 이름이 중복될수는 없지만, 서로 다른 스코프에서는 이름 중복이 가능
4. 가장 인접한 스코프에 있는 변수 및 상수에 먼저 접근한다.