일반 함수
: 프로그래밍 언어나 프레임워크 수준에서 제공하는 함수, 기본적인 데이터의 처리나 연산 등을 수행하기 위한 목적, ex:print()
사용자 정의 함수
: 필요한 함수를 직접 만들어서 사용하는 것
// 매개변수와 파라미터는 같은 말
func 함수이름(매개변수1: 타입, 매개변수2: 타입: ....) -> 반환타입 {
실행내용
return 반환값
}
// 1. 매개변수와 반환값이 모두 없는 함수
func printHello() {
print("안녕하세요")
}
// 2. 매개변수는 없지만 반환값은 있는 함수
func sayHello() -> String {
let returnValue = "안녕하세요"
return returnValue
}
// 3. 매개변수는 있으나 반환값이 없는 함수
func printHelloWithName(name: String) {
print("\(name)님, 안녕하세요")
}
// 4. 매개변수와 반환값이 모두 있는 함수
func sayHelloWithName(name: String) -> String {
let returnValue = "\(name)님, 안녕하세요"
return returnValue
}
// 5. 반환값이 없으나 함수의 실행을 명시적으로 종료할 목적으로 return 사용
func hello(name: String?) {
guard let _name = name else {
return
}
print("\(_name)님, 안녕하세요")
}
함수의 이름에 괄호를 붙이면 된다.
// 매개변수가 없는 경우
printHello()
// 출력값: 안녕하세요
// 매개변수가 있는 경우
let inputName = "홍길동"
printHelloWithName(name: inputName)
// 출력값: 홍길동님, 안녕하세요
함수가 여러 개의 값을 반환해야 한다면 집단 자료형에 담아 반환해야한다.
// 반환값이 여러개일 때 튜플사용
func personalInfo() -> (Int, String) {
let height = 163
let name = "sol"
return (height, name)
}
// 튜플의 인덱스 사용
var sol = personalInfo()
print(sol.1) // 출력값: sol
// 변수에 대입해서 사용
var (a, b) = personalInfo()
print(a) // 출력값: 163
// 튜플 요소 각각을 변수로 받아서도 사용 가능
func getIndvInfo() -> (h: Int, n: String) {
let height = 100
let name = "Peter"
return (height, name)
var uInfo = getIndvInfo()
uInfo.h // 100
uInfo.n // Peter
// 타입 알리어스 사용
typealias infoList = (h: Int, n: String, g: Character)
func info() -> infoList {
let height = 163
let gender : Character = "W"
let name = "sol"
return (height, name, gender)
}
내부 매개변수
: 입력된 인자값을 함수 내부에서 참조하기 위해 사용하는 변수
외부 매개변수
: 함수를 호출할 때 인자값에 대한 레이블 역할, 식별자 일부로 사용한다.
가변 인자
가변적인 인자와 매개변수를 입력받을 때 매개변수명 다음에 '...' 연산자를 추가하여 사용한다.
기본값을 갖는 매개변수
반드시 직접 입력받아야 하는 값이 아니라면 인자값을 생략할 수 있도록 함수 정의 시 매개변수에 기본값을 지정할 수 있는 문법을 제공한다.
매개변수의 수정
파라미터의 값을 변경해서 사용하려면 파라미터를 변수화 해야한다.
InOut 매개변수
함수 내부에서 발생하는 사건은 단순히 같은 값을 가질 뿐 단절된 객체이기 때문에 함수 외부에 영향을 미칠 수 없다.
함수에서도 내부에서 수정된 인자값이 외부까지 영향을 미치게 하려면 inout
키워드를 사용해야한다.
// 1. 외부 매개변수, 내부 매개변수 사용
func welcome(to name: String){
print("\(name)아, 안녕~")
}
welcome(to: "hansol") // 출력값: hansol아, 안녕~
// 외부 매개변수 생략 가능 (일부 매개변수만 생략도 가능)
func welcomeMessege(_ name: String) {
print("\(name)아, 안녕~")
}
welcomeMessege("hansol") // 출력값: hansol아, 안녕~
// 2. 가변인자 사용
func average(_ score: Int...) -> Double {
var total = 0
for i in score {
total += i
}
return Double(total) / Double(score.count)
}
print(average(10, 20, 30, 40)) // 출력값: 25.0
// 3. 기본값을 갖는 매개변수
func person(_ name: String,_ gender: String,_ fact: Bool = true){
if fact == true {
print("\(name)이는 \(gender)가 맞습니다.")
}
else {
print("\(name)이는 \(gender)가 아닙니다.")
}
}
var result = result("한솔", "여자")
// 출력값: 한솔이는 여자가 맞습니다.
var result2 = result("웅", "여자", false)
// 출력값: 웅이는 여자가 아닙니다.
// 4. 매개변수의 수정
func incrementBy(base: Int) -> Int {
var base = base
base += 1
return base
}
// 5. InOut 매개변수
var cnt = 30
func autoIncrement(value: Int) -> Int {
var value = value
value += 1
return value
}
// 외부에서 입력한 인자값의 참조값이 직접 함수 내부로 전달되는 것이 아니라 그 값이 복사된 다음 전달되기 때문에 인자값으로 전달된 cnt 와 value 는 서로 다른 변수다. (값에 의한 전달)
print(autoIncrement(value: cnt)) // 출력값: 31 (함수 내부의 value 변수값)
print(cnt) // 출력값: 30 (외부에서 정의된 cnt 변수값)
var count = 30
func foo(paramCount: inout Int) -> Int {
paramCount += 1
return paramCount
}
// inout키워드와 주소 추출 연산자인 &연산자 사용하면 값이 아닌 주소가 전달됨 (참조에 의한 전달)
// 예외적으로 클래스(Class)로 구현된 인스턴스는 inout 키워드를 사용하지 않아도 항상 참조에 의해 전달된다.
print(foo(paramCount: &count)) // 출력값: 31 (함수 내부의 paramCount 변수값)
print(count) // 출력값: 31 (외부에서 정의된 count 변수값)
// 상수는 inout 매개변수에 인자값으로 전달할 수 없다.
let count1 = 30
foo(paramCount: &count1) // 불가능
// 리터럴은 inout 매개변수에 인자값으로 전달할 수 없다.
foo(paramCount: &30) // 불가능
// 변수는 inout 매개변수에 인자값으로 전달할 수 있다.
var value = 30
foo(paramCount: &value) // 가능