함수
- 특정 작업을 수행하기 위해 호출할 수 있게 이름 붙여진 코드 블록
매개 변수(parameter) vs 인자(argument)
- 매개변수 : 함수가 호출될 때 받게 되는 값
- 인자 : 실제로 함수가 호출되고 값이 전달되는 시점에서 인자로 부름
메서드
- 특정 클래스나 구조체 또는 열거형과 연관된 함수
- 클래스 내 함수 선언 → 메서드
- 특별한 언급 없으면 함수 설명과 규칙, 동작이 모두 메서드에도 동일하게 적용됨
함수 선언 방법
- 함수명, 매개변수, 반환 결과 타입의 조합 → 함수 시그니처
func 함수명 (매개변수 이름 : 매개변수 타입, ... ) -> 반환 결과 타입 {
// 함수 코드
}
// 매개변수로 문자열 하나와 정수 하나를 받으며 문자열 결과를 반환하는 함수
func buildMessageFor(name : String, count : Int) -> String {
// "\(name), you are customer number \(count)"
return "\(name), you are customer number \(count)"
}
print(buildMessageFor(name: "lee", count: 2)) // lee, you are customer number 2
→ 문자열 값을 반환하기 위해 return을 사용하지만, 함수가 단일 표현식을 가지고 있으면 생략 가능
지역 매개변수명과 외부 매개변수명
- 지역 매개변수명 : 함수를 선언할 때 함수 코드 내에서 참조할 수 있는 이름을 할당한 매개 변수
- 외부 매개변수명 : 함수가 호출될 때, 참조되는 매개변수의 이름
let message = buildMessageFor(name : "lee", count : 2)
→ name, count는 지역 매개변수명이자, 외부 매개변수명
- 매개변수에 할당된 디폴트 외부 매개변수명은 지역 매개변수명 앞에 밑줄(_) 문자를 써서 없앨 수 있음
// 외부 매개변수명, 지역 매개변수명
func buildMessageFor(_ name : String, _ count : Int) -> String {
"\(name), you are customer number \(count)"
}
let message = buildMessageFor("lee", 2) // "lee, you are customer number 2"
- 지역 매개변수명, 외부 매개변수명 다르게 지정
// 외부 매개변수명, 지역 매개변수명
func buildMessageFor(userName name : String, userCount count : Int) -> String {
"\(name), you are customer number \(count)"
}
let message = buildMessageFor(userName : "lee", userCount: 2) // "lee, you are customer number 2"
함수에 디폴트 매개변수 선언
- 함수가 호출될 때 인자로 쓸 값이 들어오지 않은 경우에 사용할 디폴트 매개변수 값 지정
- 디폴트 값을 매개변수의 끝에 둠
// 디폴트 매개변수
func buildMessageFor(_ name : String = "Customer", count : Int) -> String {
"\(name), you are customer number \(count)"
}
let message = buildMessageFor(count : 2)
print(message) // Customer, you are customer number 2
여러 결괏값 반환
- 결괏값들을 튜플로 래핑하면 여러 개의 결과값을 함수로 반환 가능
- 길이에 대하여 인치 단위의 측정값을 매개변수로 받음 → 이 값을 야드, 센치미터, 미터로 변환 후 하나의 튜플 인스턴스에 넣어 반환하는 함수
// 길이에 대하여 인치 단위의 측정값을 매개변수로 받음 → 이 값을 야드, 센치미터, 미터로 변환 후 하나의 튜플 인스턴스에 넣어 반환하는 함수
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) // 0.555556
print(lengthTuple.centimeters) // 50.8
print(lengthTuple.meters) // 0.508
가변 개수 매개변수 (variadic parameter)
- 함수가 호출될 때 함수가 받게 될 매개변수가 몇 개인지 알 수 없는 경우 사용
- 함수가 지정된 데이터 타입의 매개변수를 0개 또는 그 이상을 받는다는 의미 (… 점 3개 사용)
- 함수 내에서 매개변수는 배열 객체의 형태로 사용
- 문자열 값들을 매개변수로 받아 콘솔 패널에 출력하는 함수
//문자열 값들을 매개변수로 받아 콘솔 패널에 출력하는 함수
func displayStrings(_ strings: String...){
for string in strings {
print(string)
}
}
displayStrings("one","two","three","four")
변수인 매개변수
- 함수가 받는 모든 매개변수는 상수 취급 → 변경되는 것을 막음
- 함수 내에서 매개변수의 값을 변경하고 싶으면 섀도 복사본(shadow copy)을 반드시 생성해야 함
- 인치 단위의 길이와 너비를 매개변수로 전달받아 각각의 값을 센티미터로 변환 후 면적 계산 반환 함수
// 인치 단위의 길이와 너비를 매개변수로 전달받아 각각의 값을 센티미터로 변환 후 면적 계산 반환 함수
func calcuateArea(length : Float, width: Float) -> Float{
var length = length
var width = width
length = length * 2.54
width = width * 2.54
return length * width
}
print(calcuateArea(length: 10, width: 20)) // 1290.32
입출력 매개변수로 작업하기
- 함수가 값을 반한환 뒤에도 매개변수에 대한 변경을 유지하려면, 함수 선언부 내에서 매개변수를 입출력 매개변수 (in-out parameter)로 선언해야 함
// 입출력 매개변수 사용 전
var myValue = 10
func doubleValue(_ value : Int) -> Int{
var value = value
value += value
return value
}
print("Before function call myValue = \(myValue)") // 10
print("doubleValue call returns = \(doubleValue(myValue))") // 20
print("After function call myValue = \(myValue)") // 10
------------------------------------------------------------------------
// 입출력 매개변수 사용 후
var myValue = 10
func doubleValue(_ value : inout Int) -> Int{
value += value
return value
}
print("Before function call myValue = \(myValue)") // 10
print("doubleValue call returns = \(doubleValue(&myValue))") // 20
print("After function call myValue = \(myValue)") // 20
매개변수인 함수
// 매개변수인 함수
func inchesToFeet(_ inches: Float) -> Float{
inches * 0.0833333
}
let toFeet = inchesToFeet
print(toFeet(10)) // 0.833333
- 이 기능은 의미 없어 보이지만, 함수 내 매개변수로 함수를 이용할 때 효과적임
- 두 개의 단위 변환 함수를 상수에 할당
// 매개변수로 함수 할당
func inchesToFeet(_ inches: Float) -> Float{
inches * 0.0833333
}
func inchesToYards(_ inches : Float) -> Float{
inches * 0.0277778
}
let toFeet = inchesToFeet
let toYards = inchesToYards
- 새롭게 만든 함수는 inchesToFeet 함수 타입과 inchesToYards 함수의 타입 모두 일치하는 함수 타입과 함께 변환할 값을 매개변수로 받음
- 함수의 데이터 타입은 (Float) → Float
func outputConversion(_ converterFunc : (Float) -> Float, value : Float){
let result = converterFunc(value)
print("Result of conversion is \(result)")
}
outputConversion(toFeet, value: 10) // Result of conversion is 0.833333
outputConversion(toYards, value: 10) // Result of conversion is 0.277778
클로저 표현식
- 독립적인 코드 블록
- 클로저 표현식을 선언하고 그것을 sayHello라는 이름의 상수를 할당한 다음에 상수 참조를 통해 함수 호출
// 클로저 표현식
let sayHello = {print("Hello")}
sayHello() // Hello
{(매개변수 이름 : 매개변수 타입, ... ) -> 반환타입 in
// 클로저 표현식 코드
}
// 두 개의 정수를 받아 하나의 정수를 결과 반환
let multiply = {(_ val1: Int, _ val2 : Int) -> Int in
return val1 * val2
}
let result = multiply(10, 20)
print(result) // 200
- 함수를 선언할 때와 비슷하지만, 클로저 표현식은 이름을 갖지 않음
- 매개변수와 반환 타입은 괄호 안에 포함되며, 클로저 표현식 코드의 시작을 가리키기 위해 in 키워드 사용
- 함수는 이름이 있는 클로저 표현식
- 클로저 표현식은 비동기 메서드 호출에 대한 완료 핸들러를 선언할 때 종종 사용됨
- 어떤 작업을 백그라운드에서 작업하게 해서 애플리케이션이 다른 작업을 계속할 수 있도록 운영체제에게 요청해야 하는 경우가 종종 생김
- 이런 경우 시스템이 애플리케이션에게 작업이 완료된 것을 알리고 작업(메서드)를 호출할 때 선언했던 완료 핸들러를 호출하여 결과 반환
- 완료 핸들러에 대한 코드는 주로 클로저 표현식 형태로 구현
eventstore.requestAccess(to: .reminder, completion: {(granted: Bool, error : Error?) -> Void in
if !granted{
print(error!.localizedDescription)
}
})
클로저
- 함수나 클로저 표현식 같은 독립적인 코드 블록과 코드 블록 주변에 있는 하나 이상의 변수가 결합된 것
// 클로저
func functionA() -> () -> Int {
var counter = 0
func functionB() -> Int {
return counter + 10
}
return functionB
}
let myClosure = functionA()
let result = myClosure() // 10
- functionA는 functionB라는 이름의 함수를 반환
- functionB는 functionB의 내부 영역 밖에 선언된 counter 변수에 의존하기 때문에 functionA는 클로저를 반환하고 있음
- functionB는 counter 변수를 잡고 있다(captured), 또는 가두고 있다 (closed over) → 클로저
'Swift' 카테고리의 다른 글
Swift - 6. 서브 클래싱과 익스텐션 개요 (0) | 2023.12.28 |
---|---|
Swift - 5. 객체 지향 프로그래밍 기초 (0) | 2023.12.27 |
Swift - 3. 제어 흐름 (0) | 2023.12.26 |
Swift - 2. 연산자와 표현식 (0) | 2023.12.24 |
Swift - 1. 데이터 타입 (0) | 2023.12.24 |