으니의 개발로그

[Swift] 함수(2) - 매개변수 본문

Swift/책 정리

[Swift] 함수(2) - 매개변수

아잉으니야 2021. 1. 27. 21:19

[Swift] 함수(2) - 매개변수

이 글은 Swift 프로그래밍 책을 읽고 요약한 내용입니다.

 

 

매개변수가 없는 함수와 매개변수가 여러 개인 함수

함수에 매개변수가 필요 없다면 매개변수 위치를 공란으로 비워둔다.

func helloWorld() -> String {
    return "Hello, world!"
}

print(helloWorld())
/* Hello, world! */

 

매개변수가 여러 개 필요한 함수를 정의할 때는 쉼표, 로 매개변수를 구분한다.

호출 시에 매개변수에 붙이는 이름은 매개변수 이름이라고 한다.

func sayHello(myName: String, yourName: String) -> String {
    return "Hello \(yourName)! I'm \(myName)"
}

print(sayHello(myName: "jieun", yourName: "seonho"))
/* Hello seonho! I'm jieun */

 

 

매개변수 이름과 전달인자 레이블

보통 함수를 정의할 때 매개변수를 정의하면 매개변수 이름과 전달인자 레이블을 같은 이름으로 사용할 수 있지만 전달인자 레이블을 별도로 지정하면 함수 외부에서 매개변수의 역할을 좀 더 명확히 할 수 있다. 전달인자 레이블을 사용하려면 함수 정의에서 매개변수 이름 앞에 한 칸을 띄운 후 전달인자 레이블을 지정한다.

 

스위프트에서 기본적으로 사용하는 키워드 대부분은 매개변수 이름으로 사용할 수 없다. 하지만 이름을 지정해줄 때 강세표 혹은 `` ` 로 이름을 감싸주면 대부분의 키워드를 이름으로 사용할 수 있다.

 

func 함수 이름(전달인자 레이블 매개변수 이름: 매개변수 타입, 전달인자 레이블 매개변수 이름: 매개변수 타입...) -> 반환 타입 {
  실행구문
  return 반환 값
}

 

// from 과 to 라는 전달인자 레이블이 있으며
// myName 과 name 이라는 매개변수 이름이 있는 sayHello 함수
func sayHello(from myName: String, to name: String) -> String {
    return "Hello \(name)! I'm \(myName)"
}

print(sayHello(from: "seonho", to: "jieun"))
/* Hello jieun! I'm seonho */

전달인자 레이블을 사용하면 함수 내부에서는 전달인자 레이블을 사용할 수 없으며, 함수를 호출할 때는 매개변수 이름을 사용할 수 없다.

 

전달인자 레이블을 사용하고 싶지 않다면 와일드카드 식별자를 사용하면 된다.

func sayHello(_ name: String, _ times: Int) -> String {
    var result: String = ""

    for _ in 0..<times {
        result += "Hello \(name)!" + " "
    }

    return result
}

print(sayHello("Chope", 2))

/* Hello Chope! Hello Chope! */

 

전달인자 레이블을 변경하면 함수의 이름 자체가 변함. 그렇기 때문에 전달인자 레이블만 다르게 써주더라도 함수 중복 정의(오버로드)로 동작할 수 있다.

func sayHello(to name: String, _ times: Int) -> String {
    var result: String = ""

    for _ in 0..<times {
        result += "Hello \(name)!" + " "
    }

    return result
}

func sayHello(to name: String, repeatCount times: Int) -> String {
    var result: String = ""

    for _ in 0..<times {
        result += "Hello \(name)!" + " "
    }

    return result
}

print(sayHello(to: "Chope", 2))
/* Hello Chope! Hello Chope!  */
print(sayHello(to: "Chope", repeatCount: 2))
/* Hello Chope! Hello Chope!  */

 

 

매개변수 기본값

스위프트의 함수에서는 매개변수마다 기본값을 지정할 수 있다. 즉, 매개변수가 전달되지 않으면 기본값을 사용한다. 매개변수 기본값이 있는 함수는 함수를 중복 정의한 것처럼 사용할 수 있다.

// times 매개변수가 기본값 3을 갖는다
func sayHello(_ name: String, times: Int = 3) -> String {
    var result: String = ""

    for _ in 0..<times {
        result += "Hello \(name)!" + " "
    }

    return result
}

// times 매개변수의 전달 값을 넘겨주지 않아 기본값 3을 반영해서 세 번 출력한다.
print(sayHello("seonho"))
/* Hello seonho! Hello seonho! Hello seonho! */

// times 매개변수의 전달 값을 2로 넘겨주었기 때문에 전달 값을 반영해서 두 번 출력한다.
print(sayHello("Joe", times: 2))
/* Hello Joe! Hello Joe! */

기본값이 없는 매개변수를 기본값이 있는 매개변수 앞에 사용하는게 좋다. 기본값이 없는 매개변수는 대체로 함수를 사용함에 있어 중요한 값을 전달할 가능성이 높다. 기본값이 있는지와 상관 없이 중요한 매개변수는 앞쪽에 배치하는 것이 좋다.

 

print 함수

콘솔 로그를 남길 때 사용하는 print() 함수의 원형을 살펴보면 public func print(_ items: Swift.Any..., separator: String = default, terminator: String = default) 로 정의되어 있다. 단순히 print() 함수에 items 전달인자만 넘겨도 자동으로 동작할 수 있는 이유이다. terminator 매개변수의 default 값은 줄바꿈 문자(\n)이다. 그래서 문자열 끝에 줄바꿈을 해주지 않아도 print() 함수를 통해 로그를 생성하면 자동으로 줄이 바뀐다. separator 매개변수는 items 매개변수를 통해 들어온 값을 분리해서 표시해주는 문자열을 뜻한다. 기본적으로는 공백(띄어쓰기)으로 동작한다.

 

 

가변 매개변수와 입출력 매개변수

매개변수로 몇 개의 값이 들어올지 모를 때, 가변 매개변수를 사용한다. 가변 매개변수는 0개 이상의 값을 받아올 수 있으며, 가변 매개변수로 들어온 인자 값은 배열처럼 사용할 수 있다. 함수마다 가변 매개변수는 하나만 가질 수 있다.

func sayHelloToFriends(me: String, friends names: String...) -> String {
    var result: String = ""

    for friend in names {
        result += "Hello \(friend)!" + " "
    }

    result += "I'm " + me + "!"
    return result
}

print(sayHelloToFriends(me: "jieun", friends: "seonho", "donghae", "hero"))
/* Hello seonho! Hello donghae! Hello hero! I'm jieun! */

print(sayHelloToFriends(me: "jieun"))
/* I'm jieun! */

 

  • 입출력 매개변수의 전달 순서
    1. 함수를 호출할 때, 전달인자의 값을 복사한다.
    2. 해당 전달인자의 값을 변경하면 1에서 복사한 것을 함수 내부에서 변경한다.
    3. 함수를 반환하는 시점에 2에서 변경된 값을 원래의 매개변수에 할당한다.

 

참조는 inout 매개변수로 전달될 변수 또는 상수 앞에 앰퍼샌드(&) 를 붙여서 표현한다.

var numbers: [Int] = [1, 2, 3]

func nonReferenceParameter(_ arr: [Int]) {
    var copiedArr: [Int] = arr
    copiedArr[1] = 1
}

func referenceParameter(_ arr: inout [Int]) {
    arr[1] = 1
}

nonReferenceParameter(numbers)
print(numbers[1])
/* 2 */

referenceParameter(&numbers)    // 참조를 표현하기 위해 &을 붙여준다.
print(numbers[1])
/* 1 */

입출력 매개변수는 매개변수 기본값을 가질 수 없으며 가변 매개변수로 사용될 수 없다. 또한 상수는 변경될 수 없으므로 입출력 매개변수의 전달인자로 사용될 수 없다.