서문
- 함수는 독립적으로 특정 task를 수행하는 코드.
- Swift에서 function syntax는 다양하게 표현될 수 있다. (parameter name같이 쓰는게 Obj-C에서 온거구나..)
- Default value를 제공할 수 있다 @for → function call 간소화
- 매개변수로 넣는 변수를 수정하는 역할을 할 수도 있다 (inout parameter)
- Swift에서 function은 type을 가지는데 다른 일반 type처럼 사용될 수 있어서 function을 또 다른 function의 parameter로 전달하고 return하는 등 모든 작업을 할 수 있다
- Function 안에서 또 다른 Function을 만드는 것도 가능하다 @for → 기능 캡슐화
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
return backward ? stepBackward : stepForward
}
- Argument는 function parameter list와 순서가 같아야 한다
- (그렇지 않은 언어도 있다고 한다. 아마.. C#, 코틀린?)
- Default를 제공하면 optional하게 Agument를 안 넣어줘도 동작한다
- 이름 명확하게 잘 짓자
- Function name이 같더라도 parameter list가 다르면 다른 함수처럼 사용할 수 있다
- call할 때 넣는 parameter list에 따라 선택됨
- return이 없는 Function도 엄밀히 말하면 Void 타입(=empty tuple)을 return하는 것
- return이 있는 Function을 사용할 때 return value를 안 쓰면 compile 에러난다
- 아래와 같은 syntax가 추천됨
func printAndCount(string: String) -> Int {
print(string)
return string.count
}
func printWithoutCounting(string: String) {
let _ = printAndCount(string: string)
}
● return이 optional인 경우
예시
//array가 empty인 경우 (min,max)가 nil이 되어 runtime error 발생
//(min: Int, max: Int) 뒤에 ?를 추가하여 해결
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty { return nil }
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
var arr: [Int] = [Int]()
if let ret = minMax(array:arr){
print(ret.min, ret.max)
}
//추가로
(Int?, Int?)와 (Int, Int)?는 다르다
● 암시적 return
- getter나 setter에서 많이 사용됨
- If the entire body of the function is a single expression, the function implicitly returns that expression
func greeting(for person: String) -> String {
"Hello, " + person + "!"
}
● parameter name은 중복이 안되나 별명(Argument Label)은 중복가능하다
특이하네... 쓰지말자
func minMax(a aa:Int, a bb:Int){
print("haha")
}
minMax(a:1, a:1)
● default value가 있는 parameter는 list의 뒤쪽에 써라
- 왜냐면 default가 없는 parameter가 더 중요할 가능성이 높거든
- 보기도 좋다. 생략된 param이 제각각이더라도 같은 function임을 인지하기 쉬움
//끝으로 몰아놓지 않으면 확실히 보기 안좋다
func abcd(a: Int = 1, b: Int, c: Int = 2){
print("haha")
}
abcd(b:2, c:3)
abcd(a:1, b:2)
● 가변 parameter
- 뒤에 ...을 붙이면 가변 param으로 사용가능하고 array취급하여 사용하면 된다
- (참고로 인자를 1개 넘겨도 array로 만들어짐)
func arithmeticMean(a numbers: Double...){
var total: Double = 0
for number in numbers {
print(number)
total += number
}
}
arithmeticMean(a:1,2)
arithmeticMean(a:1,a:2) //예상과 다르게 이렇게 쓰면 안됨
위와 같은 특징 때문에 가변 param 뒤에 오는 param은 Argument Label로 언더바를 사용할 수 없다
● inout parameter
- 기본적으로 parameter로 전달받은 값은 constant로 만들어져 변경할 수 없다
- 이 값을 바꾸고 함수가 종료된 후에도 그 변경이 유지되길 원한다면 inout이라는 걸 사용할 수 있다
- (물론 전달하는 param이 외부에서 constant면 당연히 inout으로 전달할 수 없다)
- 전달할 때는 C언어 주소넘기듯 &를 붙혀줘야 한다
- 추가로, inout param은 default를 부여할 수 없고 가변 param 사용 불가하다
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
● Nested Function
- 어떤 Function 내에서만(=local로) 동작하는 함수
- local로 선언했지만 이를 return함으로써 외부의 다른 scope에서도 사용할 수 있게 할 수 있다
//stepForward와 stepBackward는 Nested Function이지만
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
return backward ? stepBackward : stepForward
}
var currentValue = -4
//return에 의해 moveNearerToZero로 외부에서 사용할 수 있게 됨
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
'Swift > Language Guide' 카테고리의 다른 글
Control Flow - #2/2 (0) | 2021.09.12 |
---|---|
Control Flow - #1/2 (0) | 2021.09.12 |
Type Casting - #1/1 (0) | 2021.09.10 |
Collection Types - #2/2 : Set, Dictionary (0) | 2021.09.10 |
Collection Types - #1/2 : Array (0) | 2021.09.09 |
댓글