Swift - 함수 (1_정의, 호출, 반환값, 매개변수)

이한솔·2023년 7월 31일
0

Swift 문법 🍎

목록 보기
9/32

함수

일반 함수: 프로그래밍 언어나 프레임워크 수준에서 제공하는 함수, 기본적인 데이터의 처리나 연산 등을 수행하기 위한 목적, ex:print()
사용자 정의 함수: 필요한 함수를 직접 만들어서 사용하는 것

함수 사용의 장점

  1. 동일한 코드가 여러 곳에서 사용될 때 함수화하면 함수 호출만으로 처리 가능하다.
  2. 전체 프로세스를 연속적으로 작성하는 것보다 기능 단위로 함수화하면 가독성이 좋아지고 코드와 로직을 이해하기 쉽다.
  3. 비즈니스 로직을 변경해야 할 때 함수 내부만 수정하면 되므로 유지보수가 용이하다.



함수 정의 방식

  1. function의 약자인 func 키워드를 사용한다.
  2. 함수의 이름에 [+, , *, /] 같은 연산자와 예약어는 사용불가하다.
  3. 첫 글자는 반드시 영어 또는 언더바(_)로 시작한다.
  4. 일반적으로 함수명을 지을 땐 숫자를 사용하지 말고 의미를 잘 전달할 수 있는 문자로만 만드는것이 좋다.
// 매개변수와 파라미터는 같은 말
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)
}



함수의 매개변수

내부 매개변수: 입력된 인자값을 함수 내부에서 참조하기 위해 사용하는 변수
외부 매개변수: 함수를 호출할 때 인자값에 대한 레이블 역할, 식별자 일부로 사용한다.

  1. 가변 인자
    가변적인 인자와 매개변수를 입력받을 때 매개변수명 다음에 '...' 연산자를 추가하여 사용한다.

  2. 기본값을 갖는 매개변수
    반드시 직접 입력받아야 하는 값이 아니라면 인자값을 생략할 수 있도록 함수 정의 시 매개변수에 기본값을 지정할 수 있는 문법을 제공한다.

  3. 매개변수의 수정
    파라미터의 값을 변경해서 사용하려면 파라미터를 변수화 해야한다.

  4. 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) // 가능

0개의 댓글