[Swift] 헷갈리는 개념 정리

최승원·2022년 4월 6일
0

TIL (Today I Learned)

목록 보기
12/21

inout

Swift에서 함수의 파라미터는 상수(Constant)이므로 함수 내부에서 파라미터의 값을 변경할 수 없다. 이는 우리가 파라미터를 실수로라도 변경할 수 없다는 뜻이기도 하다. 만약 함수에서 파라미터의 값을 변경하고, 변경된 값이 함수 호출이 종료된 후에도 지속되길 원한다면 inout 파라미터를 사용하면 된다.

in-out 파라미터는 함수 정의시 파라미터의 타입 전에 inout 키워드를 추가하면 된다. in-out 파라미터는 변수(variable)만을 취급하며 함수의 인자로 전달할 때 &를 사용하여 해당 값이 함수내부에서 변경될 것임을 나타내야 한다.

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

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
// someInt = 107, anotherInt = 3

Function Type as a Return Types (반환 타입으로써의 함수 타입)

다른 함수에서 반환 타입을 함수 타입으로 사용할 수 있다. 반환하는 함수의 반환 화살표(->) 뒤에 완전한 함수 타입을 붙여 작성한다. 다음 예제는 값을 증가 또는 감소시키는 함수 예제.

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

이 함수의 반환 타입은 (Int) -> Int를 반환하는 함수. chooseStepFunction은 backwards 논리값 인자에 따라 stepForward함수와 stepBackward함수중 하나를 반환한다.

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

var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)

Nested Function(중첩 함수)

함수 내부에서 또다른 함수를 정의할 수 있으며 이를 중첩 함수라고 한다.
중첩 함수는 기본적으로 밖에서는 숨겨져 있으며 내부의 함수 중 하나를 반환하여 다른 범위에서 함수가 사용할 수 있게 한다. (물론 내부에 함수가 하나만 있을 수도 있다!)

다음은 chooseStepFunction에 중첩 함수로 작성된 예제.

func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backwards ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(currentValue > 0)

Sort Method(정렬 메소드)와 Closure(클로저)

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

func backward(_ s1: String, _ s2: String) -> Bool {
    return s1 > s2
}
var reversedNames = names.sorted(by: backward)
// reversedNames is equal to ["Ewa", "Daniella", "Chris", "Barry", "Alex"]

sorted(by:)by에 정렬 방법이 기술된 클로저를 넣으면 정렬된 배열을 얻을 수 있는 메소드이다. 클로저를 제공하는 일반적인 방법은 함수를 하나 만드는 것이다. 이 때 클로저는 names의 콘텐츠가 String 타입이므로 (String, String) -> Bool 의 타입의 클로저를 사용해야 한다.

이러한 함수는 다음과 같은 클로저 표현 문법을 이용해 아래와 같이 바꿀 수 있다.

// 클로저 표현 문법
{ (parameters) -> return type in
    statements
}
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
    return s1 > s2
})

sorted(by:)의 메소드에서 이미 (String, String) -> Bool 타입의 인자가 들어와야 하는 것을 알기 때문에 클로저에서 이 타입들은 다음과 같이 생략할 수도 있다.

reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )

self

self란 보통 클래스나 구조체 자신을 가리킬 때 사용한다. JavaScript의 this와 비슷한 개념이다.

아래 클래스 Student가 있다. name이라는 멤버 변수를 가지고 있다. setName이라는 메소드가 있는 데, 매개변수 이름으로 멤버변수와 동일한 name을 사용했다. 이때 setName 함수 내에 self.nameStudent 클래스의 멤버변수 name을 의미하고 name은 매개변수로 받아온 변수 name을 의미하게 됩니다.

class Student {
   var name = ""
   func setName(name: String) -> () {
      self.name = name
   }
}

참조

Swift - Inout 파라미터
[Swift] Function 정리
클로저 (Closures)
[Swift] self 키워드

profile
문의 사항은 메일로 부탁드립니다🙇‍♀️

0개의 댓글