컴퓨터언어/Swift

[Swift] 함수에 인수가 뭐이리 많아? _ 는 무엇? (feat. Parameter vs Argument)

bbanpro 2020. 4. 12. 22:52
728x90
반응형

#1. 함수에 인수가 뭐이리 많아 보이는 경우

// 함수 정의부
func 함수이름(함수호출시사용할인수별명 실제인수이름: 인수데이터타입) {
	
}

// 함수 호출부
함수이름(함수호출시사용할인수별명: 인수데이터타입)

#2. _가 껴있는 경우

// 함수 정의부
func 함수이름(_ 인수: 인수데이터타입) {

}

// 함수 호출부
함수이름(인수)

 

함수는 언어를 막론하고 친해질? 수 밖에 없는 타입인데,

 

Swift에서는 사뭇 다른 함수 모양 때문에 혼란스러울 것이다.

 

왜냐하면 Swift에서는 다른 언어들과는 달리 함수이름 옆의 소괄호() 속에 뭔가 더 많이 들어있는 경우가 많기 때문이다,

 

사실 이는 가독성을 높이기 위한 차원에서 Argument에 이름을 붙여주기 때문에 나타나는 현상이다.

 

Parameter와 Argument 차이?▼

더보기

Parameter : 함수를 정의해놓은 구역(func 키워드로 시작하는 줄)에서 그 함수에 넣은 입력값이 내부에서 어떻게 동작하는지를 보여주는, 받아온 입력값.

 

Argument : 정의된 함수를 실제로 사용하려고 호출할 때 () 속에 집어넣어지는, 넣는 값

 

이해를 위해, UILabel에 해당 국가 정보를 표시해주는 아래 예제를 살펴보자.

struct Country {
    let capital: String
    let president: String
    let population: Int
    
    init(capital: String, president: String, population: Int) {
        self.capital = capital
        self.president = president
        self.population = population
    }
}

let southKorea = Country(capital: "Seoul", president: "Moon", population: 5000)

var capitalLabel = UILabel()
var presidentLabel = UILabel()
var populationLabel = UILabel()


func setUI(data: Country) {
    capitalLabel.text = data.capital
    presidentLabel.text = data.president
    populationLabel.text = "\(data.population)"
}

setUI(data: southKorea)

예제는 Country라는 Struct가 정의되어 있고, southKorea는 그중 하나의 객체이다.

 

그리고 원래 ViewController에서는 IBOutlet을 사용하지만, 여기서는 빠른 이해를 위해 UILabel을 간단히 생성했다.

 

UILabel 밑에, func 키워드와 함께 새로 정의한 setUI 함수는 southKorea 같은 Country 객체들을 각 UILabel에 표시해주는 역할을 담당한다.

 

따라서 맨 마지막 줄처럼 setUI를 호출할 때는 위에서 정의한 대로 Country 타입을 인수로 넣어주어야 한다.

setUI(data: southKorea)

 

그런데 지금은 코드가 짧고 쉬워서 그냥 이렇게 써도 직관적으로 보일 수 있고, 또한 함수 이름도 setUI여서 UI를 세팅해주는 것이겠구나 하고 대강 짐작이 가능하다.

 

하지만 이것이 대형 프로젝트여서 개발자마다 이름짓는 습관이 다르고 취급하는 데이터도 많다면,

 

압도적인 코드의 늪에서 setUI라는 글자 옆의 "data"라는 키워드는 그다지 직관적이라고 할 수 없다.

 

이러한 이유로 Swift에서는 함수를 호출하는 사람의 입장에서, 또는 함수를 사용하는 사람의 입장에서 가독성을 높이기 위해,

 

Argument에도 이름을 지을 수 있게 해주었다.

setUI(pleaseCountryNameIs: southKorea)

 

물론 이렇게 장황하게 이름지을 일은 많이 없겠지만, 다음과 맥락으로 쉽게 쓰인다는 것을 예로 들어보았다.

"setUI 해주세요! 셋팅할 나라의 이름은 바로 : "

 

다시 말해, 함수를 호출할 때 어떤 타입을 넣어야 하는지 쉽게 설명해주기 위한 것이라고 볼 수 있다.

 

주의할 것은, 원래 func을 정의할 때와는 달리 이름을 따로 지어준 것이기 때문에,

 

func 정의부에도 () 안에 해당 이름을 또 써주어야 한다.

func setUI(pleaseCountryNameIs data: Country) {
    capitalLabel.text = data.capital
    presidentLabel.text = data.president
    populationLabel.text = "\(data.population)"
}

 

 

모든 코드를 정리하면 다음과 같다.

struct Country {
    let capital: String
    let president: String
    let population: Int
    
    init(capital: String, president: String, population: Int) {
        self.capital = capital
        self.president = president
        self.population = population
    }
}

let southKorea = Country(capital: "Seoul", president: "Moon", population: 5000)

var capitalLabel = UILabel()
var presidentLabel = UILabel()
var populationLabel = UILabel()


func setUI(pleaseCountryNameIs data: Country) {
    capitalLabel.text = data.capital
    presidentLabel.text = data.president
    populationLabel.text = "\(data.population)"
}

setUI(pleaseCountryNameIs: southKorea)

 


 

지금까지 인수가 많이 보이던 사례였고, 이어서 _(언더스코어)가 쓰이는 사례를 살펴보자.

 

인수가 많이 보이던 사례가 가독성을 위해 별명을 추가해주었다면,

 

언더스코어는 반대로 가독성을 위해 사족을 빼는 것이라고 보면 된다.

 

즉 인수의 데이터타입이 명확해서 굳이 또 쓸 필요가 없거나, 혹은 별명이 오히려 방해가 될 때가 이에 해당하는데,

 

함수를 호출할 때 ":"와 그 앞의 데이터타입을 모두 지워줌과 동시에, func 함수 정의부에서 인수 앞에 _를 붙여주면 끝난다.

 

func setUI(_ data: Country) {
    capitalLabel.text = data.capital
    presidentLabel.text = data.president
    populationLabel.text = "\(data.population)"
}

setUI(southKorea)

 

완성된 코드는 다음과 같다.

struct Country {
    let capital: String
    let president: String
    let population: Int
    
    init(capital: String, president: String, population: Int) {
        self.capital = capital
        self.president = president
        self.population = population
    }
}

let southKorea = Country(capital: "Seoul", president: "Moon", population: 5000)

var capitalLabel = UILabel()
var presidentLabel = UILabel()
var populationLabel = UILabel()


func setUI(_ data: Country) {
    capitalLabel.text = data.capital
    presidentLabel.text = data.president
    populationLabel.text = "\(data.population)"
}

setUI(southKorea)

정리

둘중에 어떤 것을 사용할 것인가는 그때그때 상황에 맞게 판단하면 될 것 같다.

 

다만 쓸거면 친절하게 써주거나, 아니면 아예 _로 생략해버리는 게 좋을 것이다.

728x90
반응형