1. A Swift Tour (1)

문인범·2023년 10월 7일

Swift

목록 보기
2/9

오늘은 Swift Tour를 해보겠다!
왠 갑자기 투어를 하고 있냐?
우리의 애플님은 스위프트를 공부하려 하는 사람들을 위해 기본 지침서를 만들어 놓았다.

The Swift Programming Language (5.9)
한글 번역본


스위프트의 특징 부터 다양한 스위프트의 문법들을 정리해놓았다.
스위프트에 대해 공부를 하려 하면 이정도는 한번쯤은 다 읽어 보아야 하지 않겠는가?
물론 나도 지금 읽기 시작하긴 했다. ㅎㅎ;;

어쨋든 그 중에서 상단의 Welcome to Swift 문단에 보면 A Swift Tour가 있는 것을 볼 수 있다.
여기에선 Swift의 중점적인 기능들을 설명하고 있으며 이 항목만 보더라도 스위프트의 대략적인 이해를 할 수 있다고 생각한다.
그래서 A Swift Tour를 읽어보고 정리를 해 보겠다.

기본적인 내용들은 뛰어넘고 작성을 하겠다.

Simple Values

가장 기초적인 변수, 상수 선언이다.

내가 프로그래밍 입문으로 선택한 언어가 Java 여서 이 부분이 처음에는 적응이 안되었지만 지금은 이 방법이 더 편하다고 생각한다.

var = 변수 선언
let = 상수 선언

위 사진과 같이 변수 선언을 위해서는 var, 상수 선언에는 let 키워드를 사용한다.
변수와 상수의 차이점은 변수는 단어 그대로 값이 변할 수 있지만 상수는 한번 설정한 값을 변경시지키 못한다.

여기서 처음 스위프트를 볼 때 궁금한 점이 있었다.
이렇게 값을 대입하면 타입은 어떻게 하는겨??
여기에 해답은 컴파일러가 대입되는 값을 보고 타입을 추론한다.
정말 놀랍지 않을수가 없다!(전 처음에 보고 신기했습니다 ㅠㅠ)

하지만 초기값이 명확하지 않거나 없는 경우에는 내가 원하는 타입으로 선언이 안될 수 있다.
그래서 Type Annotation을 이용해 직접 타입을 선택할 수 있다.

변수나 상수 뒤에 : (타입 명)를 붙여 사용하면 된다.

문자열(String)도 똑같이 선언을 하면 된다.
만약 특정 문자열에 내가 원하는 다른 타입의 값을 넣을려면 어떻게 해야 할까?
다른 타입을 String으로 변환시켜 사용해도 되지만 스위프트에서는 더욱 쉽게 지원한다.

이렇게 \(원하는 값)을 이용해 원하는 값을 넣을 수 있다.
제대로 들어간 것을 확인 할 수 있다.
Java의 String.format과 비슷해 보이는데 자바의 것 보단 훨씬 간단해 보인다.


배열딕셔너리또한 손쉽게 선언할 수 있다.

대괄호([])를 이용해 배열과 딕셔너리를 선언할 수 있다.

단 여기서 처음에 빈 배열과 딕셔너리를 선언하려고 하면 무조건 타입을 지정해줘야 한다!

위에서 본 방식과 비슷하게 대괄호 안에 타입을 넣으면 해당 타입의 배열이 선언된다.



Control Flow(조건문, 반복문)

for, while, if, if-else, switch-case등등 조건문, 반복문에 관한 내용들이다.
이들 중에서 기존에 헷갈렸던 부분만 정리해보겠다.

for문

가장 헷갈렸던 부분은 for문이었다.
원래 자바에서 썻던 for문을 그대로 들고와서 쓰니
C스타일 for문은 지원 끝났다고 구박을 준다 ㅜㅜ

스위프트에서 for문 사용 방법은
반복하려 하는 배열이 있을 시 이런 식으로 활용이 된다.

for (변수) in (반복하려 하는 배열) { ... }

여기서 변수 부분에 배열의 값이 하나씩 들어온다.

만약 "엥 나는 저런거 필요없고 그냥 단순 반복을 하고 싶은데용?" 일 경우
이런 식으로 만들 수 있다.
여기서 0...10의 뜻은 0부터 10까지 +1로 반복하겠다는 말이다.
그러므로 위에 for문은 총 11번 반복이 될 것이다.
만약 마지막 숫자는 포함하고 싶지 않을 경우 ..<를 이용해 0부터 10미만까지 총 10번 반복이 된다.
이렇게 in 뒤에 시작값, 끝값을 설정하여 반복을 진행할 수 있다.

for (변수) in (시작 값)...(끝 값) { ... } (끝 값 포함)
for (변수) in (시작 값)..<(끝 값) { ... } (끝 값 미포함)

if 와 guard-else, '??'

if

다른 부분은 거의 다 비슷한데 if의 쓰임새가 조금 다르게도 쓰인다.
바로 옵셔널 바인딩으로 활용이 된다.

이게 뭔 소리냐고?? 나도 처음엔 잘 몰랐다.
나중에 자세히 다루긴 할건데 대충 알아보자면
스위프트에는 Optional이란 개념이 있다.
공부를 하다보면 타입명 뒤에 ?가 붙은 경우가 있을것이다. (ex String?, Int?)
이런 타입의 변수는 옵셔널 변수로 해당 변수에 값이 있을수도 있고 없을수도(nil) 있는 것이다.
그래서 옵셔널 변수에 경우에는
이렇게 Optional이란 타입으로 씌어져있다.
이런 값을 이용하기 위해서는 Optional을 벗겨내야 하는데 그 방법중 하나가 옵셔널 바인딩이다.

if를 활용한 옵셔널 바인딩은

if let (변수) = (옵셔널을 벗겨낼 변수) { 실행할 구문 }

으로 사용이 가능하다. 여기서 만약에 옵셔널을 벗겨낼 변수가 nil일 경우 if문은 실행이 되지 않고 nil값이 아닐 경우 if문 안에서 언래핑된 변수를 사용할 수 있다.

위와 같이 이용할 수 있다.

guard-else

이와 비슷한 것이 guard-else 문이다.
guard문도 if let 과 비슷하게 옵셔널 바인딩에 쓰이지만 차이가 있다면 if문의 경우 해당 구문이 nil이 아닐 경우 실행이 되므로 nil이 아닌 값을 활용하려 하면 if문이 계속 중첩되어 nesting 코드가 될 수 있다.
(지옥이 탄생한다)

이런 현상을 방지하기 위해 guard-else문은 해당 변수가 nil 값일 경우 else문이 실행되는 형태로 코드가 깔끔해진다.

guard let (변수) = (옵셔널을 벗겨낼 변수) else { nil일 경우 실행할 구문 }

이렇게 활용이 되므로 상황에 따라 알맞게 사용하면 될것이라 생각한다.

'??'

또한 간단한 방법으로 '??'가 사용된다.
Nil Coalescing Operator라고 하며 한국어로 번역하면 nil 병합 연산자?로 번역이 될 듯 하다.
어쨋든 이름은 중요한게 아니고 어떻게 쓰이는가 하면

var a = (옵셔널 변수) ?? (nil일 경우 대입할 변수)

방식으로 사용한다.
예를 보면 쉽게 이해가 될 것이다.optionalInt가 nil이기 때문에 unwrappingInt에 10이 대입된 것을 확인 할 수 있으며, optionalInt2의 경우에는 nil이 아니기 때문에 unwrappingInt2에 그대로 대입이 된 것을 알 수 있다.




Functions and Closures(함수와 클로져)

일반적으로 모든 언어에 있는 함수와 스위프트의 특징이라고 할 수 있는 클로져에 대해 소개한다.
클로져에 경우 살펴본 결과 내용이 상당히 방대해 나중에 따로 공부를 해야할 것으로 보인다.
일단 함수부터 살펴보도록 하자!

Functions(함수)

기본 사용법

스위프트의 함수 선언은 다음과 같은 형식으로 이루어진다.

func 함수명 (인자1: 타입, 인자2: 타입) -> 반환 값 타입 { ... }

대충 이런 느낌이다.
여기서 만약에 반환값이 없는 함수일 경우 반환 값 타입에 Void를 넣거나 아얘 생략이 가능하다.

위에 코드를 보면 만든 함수를 사용할 때 라벨이 붙는 경우를 확인할 수 있다.

testFunc(arg1: 5, arg2: "Hello~") << arg1:, arg2, 이 부분

함수를 만들 때 인자 앞에 라벨 이름을 작성하여 따로 라벨 이름을 만들 수 있다.

func 함수명 (라벨이름 인자1: 타입, 라벨이름 인자2: 타입) -> 반환 타입 { ... }

이와 반대로 라벨 생략 또한 가능하다.
이 경우에는 위의 라벨이름 란에 '_'를 삽입하여 사용할 수 있다. (이 '_' 와일드카드 식별자 라고 한다고 합니다.)

func 함수명 ( 인자1: 타입, 인자2: 타입) -> 반환 타입 { ... }

이렇게 생략을 할 수 있다.
개인적으로는 함수 이름으로 인자에 어떤 값을 넣는지 쉽게 알 수 있는 경우에는 생략하지만 그렇지 않을 경우 라벨을 포함시키는게 좋다고 생각한다.

First-class Citizen(1급 객체)

스위프트에 특징 중 하나로 함수를 1급 객체로 처리를 합니다.
이게 무슨말이냐고요??
저도 잘 모릅니다. ㅎㅎ;;

하지만 단어를 보면 왠지 다른 객체와 똑같이 다룬다는 것을 예상할 수 있습니다.
함수를 1급 객체로 처리함으로써 3가지 특징을 가질 수 있습니다.

  1. 함수를 변수에 저장이 가능하다.
  2. 함수의 인자로 함수를 사용할 수 있다.
  3. 함수의 반환 값으로 함수를 사용할 수 있다.

예시를 보면서 이해해봅시다.

1. 함수를 변수에 저장이 가능하다.

말 그대로 변수에 함수를 저장하는 것이다.
위 사진대로 c라는 변수에 함수를 저장하고 그 변수를 사용하는 것을 볼 수 있다.
여기서 변수의 타입이 (String) -> String으로 나와있다.

2. 함수의 인자로 함수를 사용할 수 있다.

함수에 인자로 함수를 넣을 수 있다.
두번째 함수를 보면 인자 부분이 (Int) -> Bool이라고 되어있다.
Int 인자를 가지는 Bool 타입의 반환값을 가지는 함수의 타입을 인자로 가진다고 이해하면 된다.
그래서 두번째 함수에서 인자를 사용할 때 arg(1)를 함으로써 argFunc(1)를 실행하는 것이 되는 것이다.

3. 함수의 반환 값으로 함수를 사용할 수 있다.

간단하게 숫자가 1인지 아닌지 확인하는 함수를 만들었다.
보시면 isNumber1 함수에 반환 타입이 (Int) -> Bool 인 것을 볼 수 있다.
말그대로 해당 함수의 반환 타입을 Int 타입의 인자와 Bool 타입의 반환 값을 가진 함수를 뱉어 내겠다는 거다.

그렇게 하여 firstClass 변수에 isNumber 함수 실행값을 대입하여 firstClass 변수는 함수가 되어 제일 밑에 firstClass(1)을 함으로써 반환된 함수를 실행하게 됩니다.

이러한 조건들을 만족한 것이 1급 객체인 것이다!!

여기서 이러한 1급 객체인 함수를 활용한 것이 있는데

Closure(클로져)

이 친구다.
이 친구를 공부해보니 내용이 상당히 방대하다....
그래서 나중에 따로 정리해 보기로 하며 간단하게 어떤 녀석인지만 알아보자

뭐 이런 녀석이라고 하는데
실행 가능한 코드들을 모아놓은 그룹이라고 볼 수 있다.
쉽게 말해 우리가 쓰던 함수와 같은 개념이다.

다만 위에서는 without creating a named function이라고 나와있는데
'그럼 함수와 다르지 않나요??'라고 할 수 있다.

Closure에는 크게 두가지로 나뉘어 지는데

  • Named Closure : 이름이 있는 클로져, 함수가 이에 해당함
  • Unnamed Closure : 이름이 없는 클로져, 익명 함수, 보통 클로져라 하면 이것에 해당함

대충 이렇게 생긴 친구이다.
함수와 비슷하게 작성되지만 함수와 다르게 이름이 없는 것을 알 수 있다.

이 클로져들도 함수이기 때문에 1급 객체의 특성을 그대로 가지고 있다.
그래서 스위프트는 이 클로져를 이용해 다양한 곳에 활용하는것으로 보인다.

자세한 내용은 따로 다뤄보도록 하겠다. A Swift Tour를 보시면 어떤 느낌인지 가늠이 올거라 생각한다!
너무 내용이 많더라 ㅜㅜ

profile
월클 개발자를 향한 도전일지

0개의 댓글