# 함수형 프로그래밍 1 - 함수[스위프트]

스위프트의 함수는 일급객체

7.2.2 매개변수

매개변수와 전달인자

func hello(name: String) -> String {
    return "Hello \(name)"
}
let helloJenny: String = hello(name: "Jenny")
  • 매개변수(parameter): 외부에서 들어오는 값 hello(name: )의 name
    • 전달인자레이블 매개변수이름
  • 전달인자(argument): 실제 사용시 전달받는 값 "Jenny"

https://velog.io/@msi753/iOS-MVC-Pattern

  • external parameter: 전달인자 레이블
  • internal parameter: 매개변수 이름

함수 중복 정의 (오버로드)가 가능하다

  • 가변 매개변수
func sayHelloToFriends(friends names: String...) -> String {
    var result: String = ""
    
    for friend in names {
        result += "Hello \(friend)" + " "
    }
    return result
}

print(sayHelloToFriends(friends: "Johanssom", "Jay", "Wizplan"))
//Hello Johanssom Hello Jay Hello Wizplan 
  • 입출력 매개변수 inout &
    값이 아닌 참조타입을 전달할 때 사용
    • 매개변수 기본값을 가질 수 없으며
    • 가변 매개변수로 사용될 수 없으며
    • 전달인자로 상수를 사용할 수 없다
var numbers: [Int] = [1, 2, 3]

func noReferenceParameter(_ arr: [Int]) {
    var copiedArray: [Int] = arr
    copiedArray[1] = 1
}

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

noReferenceParameter(numbers)
print(numbers[1])   //2

referenceParameter(&numbers)
print(numbers[1])   //1

7.2.4 데이터 타입으로서의 함수

(매개변수 타입의 나열) -> 반환 타입
ex)
(Void) -> Void
() -> Void
() -> ()

typealias CalculateTwoInts = (Int, Int) -> Int

func addTwoInts(_ a: Int, _ b: Int) -> Int {
    return a + b
}

// 1. 함수 데이터 타입인 mathFunction변수에 함수addTwoInts을 할당한다
var mathFunction: CalculateTwoInts = addTwoInts
//var mathFunction: (Int, Int) -> Int = addTwoInts

// 2. 변수에 할당한 함수를 호출한다
print(mathFunction(2, 5))	// 7

3. 전달인자로 함수를 전달
func printMathResult(_ mathFunction: CalculateTwoInts, _ a: Int, _ b: Int) {
	print("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)

4. 조건에 따라 함수를 반환해주는 함수
func chooseMathFunction(_ toAdd: Bool) -> CalculateTwoInts {
	return toAdd? addTwoInts : multiplyTwoInts
}

printMathResult(chooseMathFunction(true), 3, 5)

전달인자 레이블은 함수 타입의 구성요소가 아니므로 함수 타입을 작성할 때는 전달인자 레이블을 써줄 수 없습니다
let someFunction: (lhs: Int, rhs: Int) -> Int //오류
let someFunction: ( lhs: Int, rhs: Int) -> Int //OK
let someFunction: (Int, Int) -> Int //OK

7.3 중첩함수

typealias MoveFunc = (Int) -> Int

func functionForMove(_ shouldGoLeft: Bool) -> MoveFunc {
    func goLeft(_ currentPosition: Int) -> Int {
        return currentPosition - 1
    }

    func goRight(_ currentPosition: Int) -> Int {
        return currentPosition + 1
    }

    return shouldGoLeft ? goLeft : goRight
}

var position: Int = -4

let moveToZero: MoveFunc = functionForMove(position > 0)
//let moveToZero: (Int) -> Int = functionForMove(position > 0)
/*
 
 functionForMove(_ shouldGoLeft: Bool) 함수는 Bool타입의 매개변수를 받아 MoveFunc를 리턴하는 함수이다.
 position>0 이 false 이므로 MoveFunc타입의 함수인 goRight함수를 리턴받아
 moveTozero: MoveFunc = goRight가 되고
 이것은 moveTozero: (Int) -> Int = goRight가 된다. (매개변수가 Int이고 리턴값이 Int인 moveTozero라는 함수타입의 변수가 goRight가 되는 것이다.)
 아래 while 문에서 moveTozero(position)을 넣으면 Int값을 리턴하게 된다.
*/

while position != 0 {
    print("\(position)")
    position = moveToZero(position)
}
print("원점도착!")

//-4
//-3
//-2
//-1
//원점도착!

print()함수의 원형
public func print(_ items: Swift.Any..., seperator: String = default, terminator: String = default)
seperator의 기본값은 " "
terminator의 기본값은 \n

7.4 종료return되지 않는 함수

비반환 함수(메서드)
반환 타입은 Never
오류를 던지거나 중대한 시스템 오류를 보고하고(guard의 else블록) 프로세스를 종료함

func crashAndBurn() -> Never {
    fatalError("Something very very bad happend")
}

func someFunction(isAllIsWell: Bool) {
    guard isAllIsWell else {
        print("마을에 도둑이 들었습니다")
        crashAndBurn()
    }
    print("All is Well")
}

someFunction(isAllIsWell: true)  //All is Well
someFunction(isAllIsWell: false) //마을에 도둑이 들었습니다
// Fatal error: Something very very bad happend

7.5 반환 값을 무시할 수 있는 함수

@discardableResult

func say(_ something: String) -> String {
    print(something)
    return something
}

@discardableResult func discardableResultSay(_ something: String) -> String {
    print(something)
    return something
}

say("hello")	//사용하지 않았다고 경고 띄움

discardableResultSay("hello")

좋은 웹페이지 즐겨찾기