part1. 함수

구름코딩·2020년 8월 16일
0

함수

함수와 메서드는 기본적으로 같다. 다만 상황이나 위치에 따라 다른 용어로 부르는것 뿐이다.

메서드 : 구조체, 클래스, 열거형 등 특정타입에 연관되어 사용하는 함수
함수 : 모듈전체에서 전역적으로 사용할 수 있는 함수

함수 선언의 기본형태

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.

가변 매개변수

  • 전달 받을 값의 개수를 알기 어려울때 사용
  • 가변 매개변수는 함수당 하나만 가질수 있다
  • 기본값이 있는 매개변수와 같이 가변 매개변수 또한 뒤에 위치하는것이 좋다
  • 0개 이상의 값(0개 포함)을 받아올수 있고, 가변 매개변수로 들어온 인자값은 배열처럼 사용할 수 있다
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:)의 반환값이 사용되지 않았으므로 에러가 표시된다
}

스위프트 전반적인 문법에서 띄어쓰기를 신경써야한다

profile
내꿈은 숲속의잠자는공주

0개의 댓글

관련 채용 정보