사용자 정의 함수
사용자 정의 함수를 정의하는 형식은 다음과 같다.
-기본적인 함수-
func 함수이름(매개변수1: 타입, 매개변수2: 타입) -> 반환타입 {
실행내용
return 반환값
}
-매개변수가 없는 함수-
func 함수이름() -> 반환타입 {
실행내용
return 반환값
}
-반환값이 없는 함수-
func 함수이름(매개변수1: 타입, 매개변수2: 타입) {
실행내용
}
💡 함수이름 - +, -, *, / 과같은 연산자는 사용불가하다.
사용자 정의 함수를 정의한 예시를 살펴보자.
-함수의 예시-
//매개변수x 반환값x
func printHello() {
print("안녕")
}
//매개변수x 반환값o
func sayHello() -> String{
let value = "안녕"
return value
}
//매개변수o 반환값x
func whoHello(name: String) {
print("안녕!, \(name)씨!")
}
//매개변수o 반환값o
func sayWhoHello(name: String) -> String {
let value = "안녕!, \(name)씨!"
return value
}
함수의 호출
printHello()
//안녕
whoHello(name: "김준수")
//안녕!, 김준수씨!
함수의 반환값과 튜플
- 튜플을 이용한 함수(튜플: 다양한 값(데이터)들의 묶음)
func getIndvInfo() -> (Int, Stirng) {
let height = 180
let name = "김준수"
return (height, name)
}
- 타입 얼리어스: 길거나 사용하기 복잡한 타입의 표현을 새로운 타입명으로 정의해주는 것
typealias 새로운 타입 이름 = 타입 표현
-----------------------------------
typealias getInfoType = (Int,String)
func getInfo() -> getInfoType { // typealias를 이용해 새로운 타입으로 적용한 모습
let height = 180
let name = "김준수"
return (height, name)
}
매개변수
- 내부 매개변수 : 함수의 내용을 실행할 때 함수의 인자값을 참조할 때 사용하는 변수
- 외부 매개변수 : 함수를 호출할 때 인자 레이블로 사용하는 변수
그렇다면 왜 외부 매개변수를 사용할까?
함수에 전달하는 각 인자의 목적을 나타내기 위해서 함수를 호출할 때 각 매개변수의 이름을 지정하는 것이 유용하다. (참고)
-외부 매개변수 프로토타입-
func 함수이름(외부매개변수1 내부매개변수1: 타입, 외부매개변수2 내부매개변수2: 타입) -> 반환타입 {
실행내용
return 반환값
}
-사용예시-
//외부 매개변수 x
func printHello(name: String, msg: String) {
print("\(name)님, \(msg)"
}
// printHello(name: "김준수", msg: "안녕하세요")
//외부 매개변수 o
func printHello(to name: String, Message msg: String) {
print("\(name)님, \(msg)"
}
// printHello(to: "김준수", Message: "안녕하세요")
위의 코드를 보면 외부 매개변수 사용 전과 후의 함수 호출명은 달라진 것을 볼 수 있다.
외부 매개변수 활용의 경우의 수
//2번 외부 매개변수 x
func printHello(to name: String, msg: String) {
print("\(name)님, \(msg)"
}
// printHello(to: "김준수", msg: "안녕하세요")
//1번 외부 매개변수 x
func printHello(name: String, Message msg: String) {
print("\(name)님, \(msg)"
}
// printHello(name: "김준수", Message: "안녕하세요")
외부 매개변수 생략
//2번 외부 매개변수 생략
func printHello(to name: String, _ msg: String) {
print("\(name)님, \(msg)"
}
// printHello(to: "김준수", "안녕하세요")
// printHello(to:_:)
//1번 외부 매개변수 생략
func printHello(_ name: String, Message msg: String) {
print("\(name)님, \(msg)"
}
// printHello("김준수", Message: "안녕하세요")
// printHello(_: Message:)
💡 Swift에서 언더바(_) 는 "문법은 적용하지만 사용하지 않는다.( 또는 생략하겠다.)"를 의미한다.
외부 매개변수를 생략하는 과정은 실제 Cocoa Touch Framework에서 많이 사용된다.
예를 들면 tableView(_:didSelectRowAt:)가 있다.
가변인자
함수는 때에 따라서 가변적인 개수의 인자를 입력 받아야할 때가 있는데 이때 사용하는 것이 가변인자이다.
정의 방식은 아래와 같다.
func 함수이름(매개변수명 : 매개변수 타입 ...)
이제 사용예시를 살펴보자.
-사용예시-
func agv(score : Int ...) -> Double{
var total = 0 // 점수 합계
for r in score {
total += r
}
return (Double(total) / Double(score.count)
}
avg(score : 10,20,30,40) // 함수호출
// 25.0
매개상수
사실상 Swift에서 매개변수는 변수가 아니라 상수이다. 즉, 값을 바꿀 수 없다는 뜻이다.
// 오류의 예시
func incrementBy(base: Int) -> Int {
base += 1 // 오류!! base는 상수이기 때문에 값을 바꿀 수 없다.
return base
}
// 올바른 예시
func incrementBy(base: Int) -> Int {
var base = base // 같은 이름으로 변수를 새로 선언과 동시에 초기화
base += 1 // 정상!!
return base
}
Inout 매개변수
Swift에서 매개변수는 함수 내부에서 값을 변경할 수 없다.
만약 함수에서 매개변수 값을 변경하고, 변경된 값이 함수 호출이 종요된 후에도 지속되길 원한다면 inout 매개변수를 사용하면 된다.
말로하면 이해가 잘 안되므로 inout을 사용하기 전 코드를 예시로 설명해보겠다.
var a = 10
func increment(_ num: Int) {
var num = num
num+=1
}
increment(a)
print(a) // 10, 값 변화 없음
위의 코드는 함수로 a 값을 10으로 만들어도 결국 a 자체를 출력하면 변화는 없다.
만약 우리가 a의 값의 변화가 함수 호출 종료후에도 지속되길 원한다면 아래와같이 inout 매개변수를 사용하면 된다.
var a = 10
func increment(_ num: inout Int) {
num+=1
}
increment(&a) // inout 매개변수에 값을 넘길때에는 &표시를 붙여야 합니다.
print(a) // 11, 값 변화 있음
이렇게 값을 복사해서 인자 값을 사용하는 것이 아니라 값의 주소를 이용해서 인자 값을 사용하므로써 본 값에도 영향을 주었다.
❌ Inout은 상수, 리터럴 그리고 가변 인자 또한 Inout을 적용할 수 없다. ❌
inout의 원리
- 함수가 호출되면, 매개변수로 넘겨진 변수가 복사된다.
- 함수 몸체에서 복사했던 값을 변화시킨다.
- 함수가 반환될 때, 이 변화된 값을 원본 변수에 재할당한다.
'문법관련 > Swift' 카테고리의 다른 글
클로저 (꼼꼼한 재은 씨의 Swift : 문법편 + babbab2) (0) | 2022.05.26 |
---|---|
함수(2) (꼼꼼한 재은 씨의 Swift : 문법편) (0) | 2022.05.26 |
익스텐션 (꼼꼼한 재은 씨의 Swift : 문법편) (0) | 2022.05.19 |
열거형 (꼼꼼한 재은 씨의 Swift : 문법편) (0) | 2022.04.11 |
옵셔널과 옵셔널 체인 (꼼꼼한 재은 씨의 Swift : 문법편) (0) | 2022.04.10 |