Swift

Swift) About Function

행복하고 싶은 사람 2022. 8. 10. 16:13

Swift에서는 함수를 이렇게 정의합니다. 

함수는 특정한 task를 수행하는 코드를 가진 코드 뭉치입니다. 우리가 함수를 식별할수 있는 이름을 지정하면 함수가 수행하는 특정 task를 해야하는 상황이 생기면 이름을 호출하면 됩니다.

함수?

→ 특정 작업을 수행하는 코드 모음. 필요할때 작업을 수행하기 위해 함수를 호출하면 사용됨 즉 swift에서 func 키워드를 사용하는 모든것!

func funcName(ArgumentLabel ParameterName:Type) -> ReturnType {
		//code
}

기본적인 함수의 형태는 이러함

func sayHelloWorld() -> String {
	return "hello, world"
}

이렇게 파라미터가 없는 함수도 있고

func greet(person: String) {
	print("hello, \\(person)!")
}

이렇게 Return type이 없는 경우도 존재할 수 있음. (Void)

  • ArgumentLabel?

funName (ArgumentLabel ParameterName:Type)

기본적인 함수의 형태에서는 ArgumentLabel, ParameterName 두개가 있는데 예시에서는 왜 하나만 적혀있음? → Argument Label과 Parameter Name을 한번에 명시한것임

func hello(to name: String) {
	print("Hello, \\(name)")
}
sayHello(to: "HS")

여기서 Argument Label은 to에 해당되고 parameterName은 name에 해당됨.

Argument Label은 함수를 호출할때 사용되고 Parameter Name은 함수 내부에서 사용되는 것임.

만약 Argument Label을 생략하고 싶으면 _을 이용해 생략할 수 있는데 이것을 Wildcard pattern이라고 함

func sayHello(_ name: String) {
	print("Hello, \\(name)")
}

sayHello("HS") 

이렇게 사용되는 것임. (호출할때 Argument Label을 생략)

만약 파라미터가 없다면

func sayHello() {
	print("Hello")
}

이렇게 비워두면됨. 파라미터가 없어도 ()는 생략하면 안됨!

파라미터 기본값

함수 파라미터 타입 뒤에 파라미터 값을 할당하면 함수 파라미터에 default value를 줄 수가 있음. default value가 있는 파라미터는 함수 호출할때 생략할 수 도 있음.

func sayHello(name: String = "HS")
{
	print("Hello \\(name)"
}

sayHello(). // Hello HS

가변 파라미터

가변 파라미터는 0개 이상 특정 타입의 값을 허용.

즉 몇개의 입력값이 전달 될 지 모를때 사용합니다. (단 하나의 타입만 가능!)

예시를 보면

func arithmeticMean(_ numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8.25, 18.75)
// returns 10.0, which is the arithmetic mean of these three numbers

이렇게 타입 뒤에 …을 붙여서 사용합니다.

numbers 파라미터는 0개 이상의 값을 받을 수 있습니다.

5.4 버젼 패치로인해 가변파라미터 여러개고 가능!

In-Out 파라미터(In-Out Parameters)

함수 파라미터는 기본적으로 값타입의 상수임. 즉 값을 복사해서 상수로 사용함.

하지만 함수 호출이 종료된 후에도 변경된 값을 사용하고 싶다면 In-Out 파라미터를 사용하면 됨.

in-out 파라미터는 값을 변경할 수 있는 것이기에 상수가 아닌 변수만 전달이 가능함 그리고 수정 가능함을 알리기 위해 변수의 이름앞에 &를붙임.

그리고 in-out 파라미터는 default value를 가질 수 없고 가변 파라미터는 inout으로 표기할 수 없음!

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \\(someInt), and anotherInt is now \\(anotherInt)")
// Prints "someInt is now 107, and anotherInt is now 3"

이렇게 함수 호출 후에도 바뀌어 있는 값을 볼 수 있음.

함수 타입

모든 함수는 파라미터 타입과 반환 타입으로 구성된 특정 함수 타입이 있음

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

이렇게 두 함수의 타입은 모두

(Int, Int) → Int 이고

func printHelloWorld() {
    print("hello, world")
}

이 함수의 타입은 () → Void 타입인것임.

Swift에서는 이런 함수타입도 String, Int같이 타입으로 사용됨.

var mathFunction: (Int, Int) -> Int = addTwoInts

print("Result: \\(mathFunction(2, 3))")
// Prints "Result: 5"

이렇게 상수 또는 변수로 정의해서 적절한 함수를 넣어주고 사용할 수도 있음.

반환 타입으로 함수 타입

리턴 타입으로 함수 타입을 반환할 수도 있음.

func stepForward(_ input: Int) -> Int {
    return input + 1
}
func stepBackward(_ input: Int) -> Int {
    return input - 1
}

두 함수는 (Int) → Int 형태인데 stepForward는 inut에 1을 더해 return하고 stepBackward는 input에 1을 빼서 return.

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    return backward ? stepBackward : stepForward
}

이 함수는 반환 타입이 (Int) → Int인 함수임. 이 함수는 Bool 타입 파라미터를 토대로 stepForward 함수 또는 stepBackward함수를 반환함.

var currentValue = 3
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero now refers to the stepBackward() function
print("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
    print("\\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// 3...
// 2...
// 1...
// zero!

이런 식으로 사용 할 수 있음!

중첩함수

지금까지 본 모든 함수는 전역 함수의 예시였음.

중첩함수라고 하는 다른 함수 내에 함수를 정의할 수도 있음.

중첩함수는 바깥에서 보이지 않지만 중첩 함수를 둘러싼 함수는 중첩 함수 중 하나를반환하여 중첩 함수를 다른 범위에서 사용할 수도 있음.

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backward ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
    print("\\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!

이런 식으로 사용될 수 있답니다! 

 

참고: https://docs.swift.org/swift-book/LanguageGuide/Functions.html