모호한 함수 참조 해결 방법
본 문서는 Swift에서 함수 시그니처가 어떻게 작동하는지 이해하고 있다고 가정합니다. 그렇지 않은 경우에는 계속하기 전에 Swift에서 함수 시그니처와 오버로딩에 대한 제 게시물을 먼저 읽어보시기를 권장합니다.
함수 참조는 괄호 앞부분인 함수의 이름으로 형성됩니다. 빠진 괄호가 함수 참조를 함수 호출과 구분짓는 요소입니다.
Swift는 함수를 참조하는 데 모호함이 없으면 기능 참조를 허용합니다.
그러나 불확실한 상황에서는 Swift가 특정 함수를 참조하기 위해 함수의 전체 이름 또는 서명을 사용할 수 있도록 선택권을 제공합니다.
여기에 작동 방식이 나와 있습니다
문제
class MessageUser {
func message(_ guestUser:String) {
print("Welcome, \(guestUser)!")
}
func message() {
print("Nice to see you again!")
}
func sendMessage() {
var messenger = message // error: Ambiguous use of 'message'
}
}
MessageUser 클래스에는 인사말을 출력하는 message 라는 두 함수와 sendMessage라는 함수가 있습니다.
sendMessage 내부에서 messenger 변수에 message를 할당하려고 시도합니다.
이 할당은 'message'의 모호함 사용으로 인해 오류를 발생시킵니다.
Swift은 할당된 함수가 어떤 함수를 참조하는지 모르는 것 같아요.
우리가 원하는 함수를 정확하게 참조하려면 함수의 전체 이름 또는 서명을 사용해야 해요.
전체 이름 솔루션:
- 함수의 전체 이름은 괄호를 포함한 이름으로 구성되며 각 이름은 콜론으로 구분된 외부 매개변수의 이름을 포함해야 합니다.
- 쉼표와 공백은 사용할 수 없어요.
- 억제된 외부 매개변수 이름은 밑줄로 표시돼요.
서명 솔루션:
- 함수의 이름(또는 전체 이름) 뒤에 키워드로 as가 오고 그 다음에 함수의 서명이 옵니다.
함수 전체 이름 및 서명 예시
func helloWorld(_ greeting: String, country: String) {
print("\(greeting), from \(country)")
}
helloWorld()
함수는 두 개의 String 타입 매개변수를 가져와 아무것도 반환하지 않습니다.
함수 몸체에서는 greeting과 country 매개변수를 로컬 변수로 사용하여 보간된 문자열을 출력합니다.
// helloWorld 전체 이름:
helloWorld(_:country:)
이것이 helloWorld()의 전체 이름입니다. suppressed external parameter name은 밑줄로 표시되고 매개변수 이름은 콜론으로 구분됩니다. 공백이나 쉼표가 없습니다.
// helloWorld 시그니처:
helloWorld(_:country:) as (String, String) -> ()
helloWorld as (String, String) -> ()
이것은 시그니처별로 함수를 참조할 수 있는 두 가지 방법입니다.
첫 번째 옵션은 전체 이름을 가지고 있고, 두 번째 옵션은 이름만 가지고 있습니다.
두 가지 옵션 모두 함수 뒤에 as 키워드와 함수 시그니처가 따릅니다.
우리 코드를 고치는 두 가지 옵션을 살펴보죠.
전체 이름과 시그니처 솔루션
class MessageUser {
func message(_ guestUser:String) {
print("Welcome, \(guestUser)!")
}
func message() {
print("Nice to see you again!")
}
func sendMessage() {
var messenger = message(_:)
}
}
여기서 특정한 String 타입의 매개변수를 받는 함수를 참조하기 위해 fullName인 message(_:)을 사용했습니다.
하지만 우리는 매개변수가 없는 메시지 기능을 참조할 때 전체 이름을 사용할 수 없습니다. 왜냐하면 전체 이름은 이름 그 자체이기 때문에 이로 인해 우리는 처음 문제로 다시 돌아가게 됩니다.
이 문제를 해결하기 위해 함수 시그니처 솔루션을 사용해야 합니다.
class MessageUser {
func message(_ guestUser:String) {
print("환영합니다, \(guestUser)님!")
}
func message() {
print("다시 뵙게 되어 반가워요!")
}
func sendMessage() {
var messenger = message as () -> ()
}
}
이제 함수 시그니처를 지정하여 매개변수가 없는 메시지 기능을 참조하고 있습니다.
물론, 이름을 신중하게 선택해야 합니다. 하지만 함수에 관한 참조가 모호한 상황에 대처할 수 있는 해결책을 갖게 되셨군요.
이 기사가 마음에 드셨다면 구독하여 새로운 글을 지금 바로 이메일로 받아보세요!