함수와 메서드는 기본적으로 같다. 다만 상황이나 위치에 따라 다른 용어로 부르는것 뿐이다.
메서드 : 구조체, 클래스, 열거형 등 특정타입에 연관되어 사용하는 함수
함수 : 모듈전체에서 전역적으로 사용할 수 있는 함수
func f_name(arg_name1 : type, arg_name2 : type ...) -> return_type {
/* function*/
return return_value
}
func sum(a : Int, b : Int) -> Int { return a + b }
func f_name(arg_name1 : type, arg_name2 : type ... ) -> Void {
/* fuction */
}
Void 생략안한 경우
func printName(name : String) -> Void { print(name) }
Void 생략한 경우
func printName(name : String) { print(name) }
func f_name() -> return_type {
//function
return val
}
func maxIntegerValue() -> Int { return Int.max }
func f_name() -> Void {
//function
}
func hello() -> Void { print("hello") }
func hello() { print("hello") }
sum(a : 3, b : 5) //8
printName(name : "dnstlr") //dnstlr
hello() // hello
func f_name(arg_name1 : type, arg_name2 : type = value...) -> return type {
//function
return value;
}
func greeting(friend : String, me : String = "woonsik") -> Void { print("Hello \\(friend)! I'm \\(me).") }
생략 및 변경 가능
greeting(friend : "byeori") //Hello byeuri! I'm woonsik.
greeting(friend : "byeori", me : "kim") // Hello byeori! I'm Kim.
func f_name(`전달인자레이블` arg_name1 : type, `전달인자레이블` arg_anme2 : type...) -> rt_type {
//function
return value;
}
func greeting(to friend : String, from me : String) {
print("Hello \(friend)! I'm \(me).")
}
greeting(to: "byeori", from: "woonsik")
// Hello byeori! I'm woonsik.
func f_name(arg_name1 : type, arg_name2 : type...) -> rt_type {
//function
return value;
}
func sayHelloToFriends(me : String, friends : String...) -> String { return ("Hello \\(friends)! I'm \\(me).") }
print(sayHelloToFriends(me : "woonsik", friends : "byeori", "etc1", "etc2"))
// Hello \\\["byeori", "etc1", "etc2"]! I'm woonsik.
print(sayHelloToFriends(me: "woonsik")
// Hello \\\[]! I'm woonsik.
반환값이 없는 함수, 매개변수 기본 값, 전달인자 레이블, 가변 매개변수 등 모두 섞어서 사용 가능
var someFunction: (String, String) -> Void = greeting(to:from:)
someFunction("byeori", "woonsik")
//Hello byeori! I'm woonsik.
someFunction = greeting(friend:me:)
someFunction("byeori", "woonsik")
//Hello byeori! I'm woonsik.
func runAnother(function: (String, String) -> Void) {
function("byeori", "woonsik")
}
runAnother(function: greeting(friend:me:))
//Hello byeori! I'm woonsik
runAnother(function: someFunction)
//Hello byeori! I'm woonsik
스위프트에서 함수는 일급객체로서 함수를 데이터 타입으로 사용할수 있고, 이는 전달인자로 받을수도 반환값으로 돌려줄수도 있다.
typealias calcTwoInt = (Int, Int) -> Int
func sumTwo(_ a: Int, _ b: Int) -> Int {
return a + b
}
func multiTwo(_ a: Int, _ b: Int) -> Int {
return a * b
}
//더하기
var calc: calcTwoInt = sumTwo
print(calc(10, 32))
//곱하기
calc = multiTwo
print(calc(10, 32))
//
42
320
//전달인자로 함수 주기
print("\n전달인자로 함수 전달 후 함수 사용\n")
func printCalcResult(_ clacMethod: calcTwoInt, _ a: Int, _ b: Int) {
print(clacMethod(a, b))
}
printCalcResult(sumTwo, 10, 42)
//특정 조건에 따라 적절한 함수 반환하는 함수
print("\n특정 조건에 따라 적절한 함수 반환하는 함수\n")
func returnCalcFunc(_ isAdd: Bool) -> calcTwoInt {
return isAdd ? sumTwo : multiTwo
}
printCalcResult(returnCalcFunc(true), 10, 32)
스위프트는 데이터 타입의 중첩으로부터 자유롭다. 열거형안에 열거형, 클래스안에 클래스 등 다양한 패턴을 자유롭게 만들수있다
중첩함수
는 일반적인 함수들이 전역함수 인것과 달리 상위 함수의 몸통 블록 내부에서만 사용할 수 있다. 다만 내부에서 반환값으로 중첩함수를 사용할 경우 외부에서도 사용할수 있다
//중첩 함수
print("\n중첩함수 구현\n")
typealias MoveFunc = (Int) -> Int
func functionForMove(_ shouldGoLeft: Bool) -> MoveFunc {
func goRight(_ n: Int) -> Int {
return n + 1
}
func goLeft(_ n: Int) -> Int {
return n - 1
}
return shouldGoLeft ? goLeft : goRight
}
var currentPos: Int = 5
let move: MoveFunc = functionForMove(currentPos > 0)
while currentPos != 0 {
print("...\(currentPos)")
currentPos = move(currentPos)
if currentPos == 0 {
print("원점 도착!")
}
}
정상적으로 끝나지 않는 함수로 비반환 함수
또는 비반환 메서드
라고 부른다
비반환 함수(메서드)의 반환타입은 Never
//비반환 함수의 정의와 사용
print("\n비반환 함수의 정의와 사용\n")
func crashAndBurn() -> Never {
fatalError("something very, very bad happend")
}
//crashAndBurn() // 프로세스 종료 후 오류 보고
func someFunc(isAllisWell: Bool) {
guard isAllisWell else {
print("마을에 도둑이 들었습니다!")
crashAndBurn()
}
print("all is well")
}
someFunc(isAllisWell: true)
someFunc(isAllisWell: false)
// 출력
all is well
마을에 도둑이 들었습니다!
Fatal error: something very, very bad happend: file /Users/choeunsig/OneDrive - SangMyung University/CodingFile/swift/Swift_study.playground/Sources/basic_3.swift, line 305
Never타입이 스위프트 표준 라이브러리에서 사용되는 대표적인 예 : fatalError
함수앞에 @discardableResult
속성을 붙여줌으로서 해당함수의 반환값을 사용하지 않더라도 오류를 체크하지 않게 해준다
//반환값을 무시할수 있는 함수
print("\n반환값을 무시할수 있는 함수\n")
@discardableResult func sayHello(Hello: String) -> String {
print("\(Hello)")
return Hello
}
func say(Hello: String) -> String {
print("\(Hello)")
return Hello
}
sayHello(Hello: "hi")
//say(Hello: "hi say") //func say(Hello:)의 반환값이 사용되지 않았으므로 에러가 표시된다
}
스위프트 전반적인 문법에서 띄어쓰기를 신경써야한다