Swift의 함수, 메서드, 클로저 개요
스위프트 함수 선언
func <함수명> (<매개변수 이름>: <매개변수 타입>,
<매개변수 이름>: <매개변수 타입>, ... ) -> <반환 결과 타입> {
// 함수 코드
}
- 함수 시그니처(function signature) - 함수명, 매개변수, 반환 결과 타입의 조합
- func - 이것이 함수임을 컴파일러에게 알려주기 위해 사용되는 키워드
- <함수명> - 함수에 할당되는 이름, 애플리케이션 코드 내에서 함수를 호출할 때 참조되는 이름
- <매개변수 이름> - 함수 코드 내에서 참조할 매개변수의 이름
- <매개변수 타입> - 해당 매개변수의 타입
- <반환 결과 타입> - 함수가 반환하는 결과의 데이터 타입, 만일 함수가 결과를 반환하지 않는다면 반환 결과 타입을 지정하지 않음(Void)
- 함수 코드 - 작업을 수행하는 함수의 코드
func sayHello() {
print("Hello")
}
매개변수x 반환결과x 메시지 표시
func buildMessageFor(name: String, count: Int) -> String {
return "\(name), you are customer number \(count)"
}
매개변수: 문자열, 정수 반환결과타입: 문자열
매개변수와 인자 혼용
매개변수(parameter): 함수가 호출될 때 받게 되는 값
인자(argument): 실제로 함수가 호출되고 값이 전돨된 시점에서는 매개변수x -> 인자
함수와 메서드
메서드: 특정 클래스나 구조체 또는 열거형과 연관된 함수
Ex) 스위프트 클래스 내에서 함수를 선언했다면 이것은 메서드로 간주
단일 표현식에서의 암묵적 반환
함수가 단일 표현식 을 가지고 있다면 return 구문을 생략가능
func buildMessageFor(name: String, count: Int) -> String {
"\(name), you are customer number \(count)"
}
하나 이상의 표현식을 가지고 있다면 컴파일 에러 발생
func buildMessageFor(name: String, count: Int) -> String {
let uppername = name.uppercased()
"\(name), you are customer number \(count)" // 컴파일 에러
}
스위프트 함수 호출
<함수명> (<인자1>, <인자2> ...)
함수를 통해 전달되는 각각의 인자는 함수가 받도록 구성된 매개변수와 일치
sayHello()
매개변수x 반환결과x
반환값 처리하기
let message = buildMessageFor(name: "John", count: 100)
매개변수: 문자열, 정수 반환결과타입: 문자열
반환된 결괏값을 사용하지 않는 경우
_ = buildMessageFor(name: "John", count: 100) // 결괏값을 버림
지역 매개변수명과 외부 매개변수명
지역 매개변수명(local parameter name, 매개변수명(parameter name)): 함수 코드 내에서 참조할 수 있는 이름을 할당한 매개변수
외부 매개변수명(external parameter name, 인자명(argument label)): 함수가 호출될 때 참조되는 매개변수
기본적으로, 함수 매개변수에는 동일한 지역 매개변수명과 외부 매개변수명이 할당
let message = buildMessageFor(name: "John", count: 100)
지역 매개변수명: name, count, 외부 매개변수명: name, count
매개변수에 할당된 디폴트 외부 매개변수명은 삭제 가능(_)
func buildMessageFor(_ name: String, _ count: Int) -> String {
return "\(name), you are customer number \(count)"
}
let message = buildMessageFor("John", 100)
지역 매개변수명: name, count, 외부 매개변수명: x
외부 매개변수명 추가
func buildMessageFor(userName name: String, userCount count: Int) -> String {
return "\(name), you are customer number \(count)"
}
let message = buildMessageFor(userName: "John", userCount: 100)
지역 매개변수명: name, count, 외부 매개변수명: userName, userCount
함수에 디폴트 매개변수 선언하기
인자로 쓸 값이 들어오지 않은 경우, 사용할 디폴트 매개변수 값을 지정
func buildMessageFor(_ name: String = "Customer", count: Int) -> String {
return "\(name), you are customer number \(count)"
}
let message = buildMessageFor(count: 100) //name 인자는 전달x
print(message)
출력
Customer, you are customer number 100
여러 결괏값 반환하기
튜플로 래핑하면 여러 개의 결괏값을 반환가능
func sizeConverter(_ length: Float) -> (yards: Float, centimeters: Float, meters: Float) {
let yards = length * 0.0277778
let centimeters = length * 2.54
let meters = length * 0.0254
return (yards, centimeters, meters)
}
let lengthTuple = sizeConverter(20) // 튜플 인스턴스 생성
print(lengthTuple.yards)
print(lengthTuple.centimeters)
print(lengthTuple.meters)
가변개수 매개변수
함수가 받게 될 매개변수가 몇 개인지 알 수 없는 경우: 가변개수 매개변수(variadic parameter) 를 사용
func displayStrings(_ strings: String...){ // 0개 이상
for string in strings { // 배열 개체의 형태로 사용
print(string)
}
}
displayStrings("one", "two", "three", "fout")
변수인 매개변수
함수가 받는 모든 매개변수는 기본적으로 상수 로 취급 - 변경x
함수 내에서 매개변수의 값을 변경하기 위해서 섀도 복사본(shadow copy) 생성
func calcuateArea(length: Float, width: Float) -> Float {
var length = length // shadow copy
var width = width // shadow copy
length = length * 2.54
width = width * 2.54
return length * width
}
print(calcuateArea(length: 10, width: 20))
입출력 매개변수로 작업하기
섀도 복사본은 변경하더라도 원본 변수에 반영되지 않는다!
var myValue = 10
func doubleValue(_ value: Int) -> Int {
var value = value
value += value
return value
}
print("Before function call myValue = \(myValue)")
print("doubleValue call returns \(doubleValue(myValue))")
print("After function call myValue = \(myValue)")
출력
Before function call myValue = 10
doubleValue call returns 20
After function call myValue = 10
myValue 변수가 변경되지 않음
함수가 값을 반환한 뒤에도 매개변수에 대한 변경을 유지하기 위해선,
함수 선언부 내에서 매개변수를 입출력 매개변수(in-out parameter)로 선언
func doubleValue(_ value: inout Int) -> Int {
//var value = value 섀도우 복사본x
value += value
return value
}
.
.
.
print("doubleValue call returns \(doubleValue(&myValue))") // 함수 호출 시 '&'
출력
Before function call myValue = 10
doubleValue call returns 20
After function call myValue = 20
매개변수인 함수
함수를 데이터 타입처럼 취급
- 함수를 상수나 변수에 할당
func inchestoFeet (_ inches: Float) -> Float { return inches * 0.0833333 } let toFeet = inchestoFeet let result = toFeet(10) // 상수 이름을 이용하여 함수 호출
toFeet의 데이터 타입은 (Float) -> Float
- 함수를 매개변수로 사용
func inchestoFeet(_ inches: Float) -> Float { return inches * 0.0833333 } func inchesToYards(_ inches: Float) -> Float { return inches * 0.0277778 } let toFeet = inchestoFeet // 상수 할당, 데이터 타입은 동일 let toYards = inchesToYards // 상수 할당, 데이터 타입은 동일 func outputConversion(_ converterFunc: (Float) -> Float, value: Float) { let result = converterFunc(value) print("Result of conversion is \(result)") } outputConversion(toYards, value: 10) // 야드로 변환하기 outputConversion(toFeet, value: 10) // 피트로 변환하기
- 함수를 데이터 타입으로 반환
func decideFunction(_ feet: Bool) -> (Float) -> Float { if feet { return toFeet } else { return toYards } }
클로저 표현식
클로저 표현식(closure expression): 독릭적인 코드블록
let sayHello = { print("Hello") }
sayHello()
클로저 표현식을 선언 후 sayHello 상수로 할당
매개변수를 받아 결괏값을 반환
{(<매개변수 이름>: <매개변수 타입>, <매개변수 이름>: <매개변수 타입>, ...)
-> <반환 타입> in
// 클로저 표현식 코드
}
let multiply = {(_ val1: Int, _ val2: Int) -> Int in
return val1 * val2
}
let result = multiply(10, 20)
매개변수: 두 개의 정수, 반환: 하나의 정수
함수 선언과 비슷
이름을 갖지 않음
매개변수와 반환 타입은 괄호 안에 포함
코드의 시작을 가리키는 in 키워드 사용
매개변수, 반환값 타입 생략 가능 {(_ val1, _ val2) in
스위프트의 클로저
컴퓨터 공학 용어에서의 클로저(closure): 독릭접인 코드 블록과 코드 블록 주변에 있는 하나 이상의 변수가
결합된 것 = 함수, 클로저 표현식
func function() -> () -> Int {
var counter = 0
func functionB() -> Int {
return count + 10
}
return functionB
}
let myClosure = functionA()
let result = myClosure()
functionB는 functionB의 내부 영역 밖에 선언된 counter 변수에 의존
-> functionA는 클로저를 반환
functionB는 counter 변수를 잡고있다(captured), 또는 가두고 있다(closed over)
-> 클로저로 간주