[Swift] 함수의 in-out 파라미터, guard문, attribute 키워드

swimmer_o3o·2022년 11월 16일
0
post-thumbnail

in-out 파라미터


함수를 선언할때 사용하는 파라미터의 경우, 기본적으로 값타입 이며, ‘임시 상수’ 이기 때문에, 함수 내에서 변경이 불가능하다.

func swap(a: Int, b: Int){
	let temp = a
	a = b
	b = temp
} // (잘못된 코드)

따라서 위와 같은 표현을 사용해 두개의 파라미터를 받아서 파라미터의 값을 서로 바꾸는 함수를 작성할수는 없다.

이처럼 일반적으로 함수 내에서 파라미터의 값을 변경 불가능하지만, in-out 파라미터를 사용하면 가능해진다.

in-out 파라미터란

함수를 사용해서 입력되는 값을 직접 수정하고 싶을 때 사용하는 파라미터 이며, 파라미터의 데이터를 값 타입이 아닌 참조타입 으로 전달하기 때문에, 함수 내에서 파라미터 값에 직접 접근하여, 변경이 가능하다.

구현 방식은, 파라미터 이름 앞 (아규먼트 레이블이 있다면 그 앞)에 inout 키워드를 붙이는 것이다.

func swap(inout a: Int, inout b: Int){
	let temp = a
	a = b
	b = temp
} 

// inout 파라미터는 참조 타입이기 때문에, 함수 호출할때, 아규먼트 앞에 & 붙여준다.

var c = 5
var d = 7
swap(a: &c, b: &d) 

위 코드처럼 swap 함수의 선언 시, 파라미터 앞에 in-out 키워드를 붙여줌으로서, 직접 파라미터에 접근해 값을 변경하는 것이 가능해졌다. 또한, inout 파라미터를 가진 함수를 호출할 때에는, 해당 파라미터가 참조타입 이므로, 반드시 아규먼트 앞에 앰퍼센트 기호 (&) 를 붙여준다.

in-out 파라미터 사용시 주의점

in-out 파라미터를 사용할 때는 다음과 같은 점을 주의한다.

  • in-out 파라미터로 상수(let) 이나, 리터럴을 전달하는것은 불가능하다.
    • in-out 파라미터는 변수의 값이 직접적으로 바뀌는 것을 시사하는 파라미터이고, 참조타입이기 때문에, 값이 바뀌지 않는 상수 타입이나, 어떤 변수에 할당된 값이 아닌 리터럴 값을 전달할수는 없기 때문이다.
  • 파라미터의 기본값 선언을 할 수 없다.
  • 가변 파라미터로 선언을 할 수 없다.

guard 문


guard 문이란

guard 문은 Swift 에만 있는 조건문으로, 기본적으로는 if 문과 같은 기능을 수행한다.

guard 문은 if 문과는 다르게, 해당 조건을 만족하지 않을 경우 스코프 안의 구문이 실행된 후, 해당 구문이 조기 종료되는 형식으로 구현된다.

guard 문의 특징

  • guard {조건} else {예외시 코드+조기종료} 형식으로, 조건을 만족하지 못하면 무조건 조기종료 (Early Exit) 될 수 있도록 한다.
  • 조건을 만족하는 경우, 코드가 다음 줄로 넘어가 계속 실행된다.
  • guard문에서 선언된 변수를, 스코프를 벗어난 후에도 계속 사용 가능하다 (서로 동일한 스코프 안에 있는것처럼 취급된다.)
  • 함수나 매서드, 반복문 안에서만 사용 가능하다!!

guard 문의 이점

if문을 중첩해서 사용하는 경우, 스코프 안에 계속해서 코드를 들여써야 한다는 점이 불편한데, guard문은 이러한 단점을 보완한다는 장점이 있다.

예를 들어, 정수가 2의 배수이자, 4의 배수, 그리고 8의 배수인지 쭉쭉 확인하는 코드를 구현한다고 할때, if 문으로 구현하면

func checkNum(num:Int){
    if num%2 == 0{
        print("2의 배수")
        if num%4 == 0 {
            print ("4의 배수")
            if num%8 == 0 {
                print("8의 배수")
            }
        }
    }
    else {
        print("짝수 아님")
    }
} 

이처럼 중첩되는 if 문으로 구현하는 기능의 경우, 지속적으로 들여쓰기를 해줘야하는 불편함이 생기는데

func checkNum2(num:Int){
    guard num%2 == 0 else {
        print("짝수 아님")
        return
    }
    print("2의 배수")
    guard num%4 == 0 else {
        return
    }
    print("4의 배수")
    guard num%8 == 0 else {
        return
    }
    print("8의 배수")
}

이처럼 guard문을 사용해서 같은 기능을 구현해주면, 더 가독성이 좋아진다.

guard 문 사용시 유의점

  • guard문은 반드시 함수 / 매서드 혹은 반복문 안에서만 쓰인다.
  • guard문의 스코프 안의 내용은 반드시 Early Exit 과 관련된 구문(return, throw)으로 완결한다. (guard body must not fallthrough!)

attributes 키워드(@) 와 discardableResult


attributes 키워드

attribute 키워드는 컴파일러에게, 직접 특정 대상에 대한 추가적인 정보를 제공하는 키워드로, ‘@’ 키워드를 앞에 붙여서 사용한다. attributes 키워드는 크게 아래와 같은 두가지 타입이 있다.

  • 선언에 추가정보를 제공해주는 attributes 키워드
    @available(iOS 13.10, *) // iOS 버전을 지정
    class Myclass {
        // 코드
    }
  • 타입에 추가정보를 제공하는 attributes 키워드
    func doSomth(completion:@escaping()->()){
        // 코드
    }

attributes 키워드 의 종류들

Swift에는 대표적으로 다음과 같은 attributes 키워드들이 있다.

  • @discardableResult
  • @escaping
  • @autoclosure
  • @objc

@discardableResult

그중, @discardableResult의 경우, 함수 앞에 사용해 주는 attributes 키워드인데, 해당 함수의 리턴값을 사용하지 않더라도 컴파일러가 경고창(노란색)을 보여주지 않게 하는 역할을 한다.

@discardableResult
func doDiscardResult()->String {
		print("함수의 동작 구현")
    return "Discard this result" // 함수의 리턴값.
}

doDiscardableResult() 

위 코드와 같이 @discardableResult와 함께 선언된 함수를 호출하면, 리턴값은 사용하지 않고, 동작만 수행하게된다.

profile
서비스 기획과 개발을 아우르며, IT 생태계를 유영하는 물고기🐠. 무한한 가능성이 잠재된 IT의 바다속으로 깊게 잠수하는 큰 고래🐋 로 성장하고 싶습니다.

0개의 댓글

관련 채용 정보