[Swift 문법] 함수

!·2022년 6월 23일
0

Swift 문법

목록 보기
6/27

함수의 선언

  • 함수 선언의 기본형태
func 함수이름(매개변수1 이름 : 매개변수1 타입, 매개변수2 이름 : 매개변수2 타입 ... ) -> 반환타입 
{
	함수 구현부
    return 반환값
}

func sum(a : Int, b : Int) -> Int
{
	return a+b
}
  • 반환값이 없는 경우 (return; 은 생략 가능)
func 함수이름(매개변수1 이름 : 매개변수1 타입, 매개변수2 이름 : 매개변수2 타입 ...) -> Void
{
	함수 구현부
    return 
}

// 이렇게 해도 된다.
func 함수이름(매개변수 이름 : 매개변수 타입) 
{
	함수 구현부
    return
}

func sayHello(name:String)
{
	print("hello \(name)!")
}
  • 매개변수가 없는 경우
func 함수이름() -> 반환타입
{
	함수 구현부
    return
}

func maximumIntegerValue() -> Int
{
	return Int.max
}

함수 호출

sum(a:3, b:5) // 8
sayHello(name : "Lee") // hello Lee!
maximumIntegerValue() // Int의 최대값

매개변수 기본값

  • 함수의 매개변수에 전달인자를 할당하지 않아도 기본적으로 갖게되는 값
  • 이 때 매개변수 기본값을 갖는 매개변수는 매개변수 목록의 마지막에 위치하는 것이 좋다.
func 함수이름(매개변수1 이름 : 매개변수1 타입, 매개변수2 이름 : 매개변수2 타입, 매개변수3 이름 : 매개변수3 타입 = 매개변수3 기본값 ...) -> 반환타입
{
	함수구현부
    return 반환값
}

func greeting(friend : String, me : String = "lee")
{
	print("Hello \(frined)! i'm \(me)!")
}
  • 매개변수 기본값을 가지는 매개변수는 호출 시 생략할 수 있다.
greeting(friend : "eric", me : "lee") // Hello eric! i'm lee!
greeting(friend : "eric") // Hello eric! i'm lee!

전달인자 레이블

  • 함수를 호출할 때 매개변수의 역할을 명확하게 할 떄 사용한다.
  • 또한 함수 사용자 입장에서 표현하고자 할 떄 사용한다.
func 함수이름 (전달인자 레이블 매개변수1 이름 : 매개변수1 타입, 전달인자 레이블 매개변수2 이름 : 매개변수2 타입...) -> 반환타입
{
	함수 구현부
    return 반환값
}
  • 전달인자 레이블을 사용해 함수를 정의하면, 함수의 오버로딩이 가능하다.
  • 함수 내부에서는 매개변수 이름으로 내용을 구현해야 하며, 함수 외부에서는 전달인자 레이블을 통해 호출해야 한다.
func greeting(to name : String, from me : String)
{
	print("Hello \(name)! i'm \(me)!")
}

greeting(to : "hana", from : "lee") // Hello hana! i'm lee!

가변 매개변수

  • 매개변수로 들어올 값의 개수를 명확히 알기 힘들떄 사용한다.
  • 가변 매개변수는 함수당 하나만 가질 수 있다.
func 함수이름(매개변수1 이름 : 매개변수1 타입, 전달인자 레이블 매개변수2 이름 : 매개변수2 타입...) -> 반환타입
{
	함수 구현부
    return 반환값
}

func sayHelloToFriends(me : String, friends : String...) -> Void
{
	return "Hello \(frineds)! i'm \(me)"
}

sayHelloToFriends(me : "lee" , friends : "eric","hana","son") // Hello ["eric","hana","son"]! i'm lee!

sayHelloToFrineds(me : "lee") // Hello []! i'm lee!

입출력 매개변수

  • 기본 데이터 타입의 경우에는 함수애 인자로 전달될 시 값에 의한 복사가 이루어진다.
  • 입출력 매개변수 키워드 inout 을 통해 참조로 값을 전달할 수 있다. 이 때의 과정은 다음과 같다.
    1. 함수를 호출할 때, 전달 인자의 값을 복사한다.
    2. 해당 전달인자의 값을 변경하면, 함수 내에서 복사한 값을 변경한다.
    3. 함수를 반환하는 시점에 2에서 복사한 값을 원래의 매개변수에 할당한다.
var numbers: [Int] = [1,2,3]

func nonR(_ arr: [Int]){
    var copyA: [Int] = arr
    copyA[2] = 1
}

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

nonR(numbers)
print(numbers)
yesR(&numbers)
print(numbers)

입출력 매개변수 사용시 주의할 점은 다음과 같다.

  1. 입출력 매개변수는 매개변수 기본값을 가질 수 없다.
  2. 입출력 매개변수는 가변 매개변수를 가질 수 없다.
  3. 입출력 매개변수는 상수를 인자로 전달할 수 없다.

데이터 타입으로의 함수

  • 스위프트는 함수형 프로그래밍 패러다임을 포함하는 다중 패러다임 언어다.
  • 스위프트 함수는 일급객체로써 변수, 상수 등에 저장이 가능하다.
  • 또한 매개변수로써 잔달할 수도 있다.
  • 쉽게 생각하자면, 함수라는 타입을 갖는 변수, 상수를 사용할 수 있다는 것이다.

함수의 타입 표현

  • 함수의 타입은 반환형을 생략할 수 없다.
  • (매개변수1 타입, 매개변수2 타입...) -> 반환타입
var someFunc : (String, String) -> Void = greeting(to:from:)
someFunc("eric","lee") // Hello eric! i'm lee!
someFunc = greeting(friend:me:)
someFunc("eric","lee") // Hello eric! i'm lee!

//타입이 다른 함수는 할당할 수 없다.
someFunc = sayHelloToFriend(me:friends:) // 컴파일 에러, 가변 매개변수를 갖는 함수이기 때문에 타입이 다르다.

func runAnother(function : (String, String) -> Void)
{
	fuction("jenny", "mike")
}

runAnother(fuction:greeting(friend:me:)) // Hello Jenny! i'm mike!

runAnother(fuction:someFunc) // Hello Jenny! i'm mike!
var pos = 3

typealias moveFuction = (Int) -> Int

func functionForMove(_ shouldGoLeft: Bool)-> moveFuction
{
    func goLeft(_ curPosition: Int) -> Int{
        curPosition - 1
    }

    func goRight(_ curPosition: Int) -> Int{
        curPosition + 1
    }
 
    return shouldGoLeft ? goLeft : goRight
}


let moveToZero: moveFuction = functionForMove(pos > 0)

while pos != 0 {
    print("pos : \(pos)....")
    pos = moveToZero(pos)
}

print()함수

print() 함수의 구현부는 다음과 같이 되어있다.

public func print(_ items: Swift.Any...., seperator: String = default, terminator: String = default)

로 정의되어 있다. items 매개변수에 문자열이 할당이 되고 terminator 매개변수에는 기본적으로 '\n'가 할당되어 있기 때문에, 개행이 되는 방식이다. 따라서 terminator: "" 를 통해 개행을 하지 않거나, terminator: " " 를 전달해 띄어쓰기를 하는 방법이 있다.


종료되지 않는 함수

스위프트에는 종료되지 않는 함수를 정의할 수 있다. 이는 함수가 정상적으로 끝나지 않는 다는 의미로, 프로그램 오류 발생을 시킨다. Never 를 반환타입으로 한다면 종료되지 않는 함수를 정의할 수 있다.

func crashAndBurn() -> Never{
	fatalError("something is wrong")
}

crashAndBurn()

func someFunction(isAllIsWell: Bool){
	guard isAllIsWell else{
    	print("집에 도둑이 들었습니다.")
        crashAndBurn()
    }
    print("AllisWell")
}

someFuction(isAllIsWell: true) // AllisWell
someFuction(isAllIsWell: false) // 집에 도둑이 들었습니다 및 프로세스 종료

Never 타입이 반환되는 대표적인 함수로는 fatalError 함수가 있다.


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

함수가 값을 반환함에도 불구하고 프로그래머가 의도적으로 반환값을 사용하지 않는 경우가 존재한다. 이때 @discardableResult 속성을 이용해 함수를 정의하면 컴파일러의 경고를 받지 않을 수 있다.

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

say("hello") // 컴파일러가 경고를 표시할 수도 있음
discardableResultFunc("hello") //  컴파일러가 경고를 표시하지 않는다.
profile
개발자 지망생

0개의 댓글