iOS 앱 개발 부트캠프/TIL

TIL 7일차 - 간단한 데이터 타입 연습

iosstudyletsgo 2024. 9. 20. 19:12

오늘은 몇가지 과제를 해결하는 시간을 가졌다. 첫 번 째는 단순히 여러 종류의 변수를 선언하는 단순한 문제이기에 지금까지 배운 걸 토대로 출력해보고자 했는데 에러가 났다. 다른 변수 선언은 괜찮은데 Character 변수와 Any 변수를 선언하라고만 써있어서 초기값 없이 정말 선언만 했더니 우리의 swift는 바로 에러가 났다. 읽어보니 초기화를 하라기에 잘 모르겠어서 일단 초기값을 지정하고 넘어갔다. swift에선 초기화를 꼭 하지 않으면 에러가 나는듯 하다.

단순히 더해서 대입했더니 에러가 난다.

이어서 2번 문제는 age 변수와 interesRate 변수를 더해서 출력하라는 문제였다. 이 역시 매우 단순한 문제여서 익숙한 방식대로 더한 값을 저장할 변수 plusFirst를 선언한 다음 age변수와 interesRate 변수끼리 더하여 대입하면 되는 줄 알았는데, 변수 값을 초기화하라고 에러가 났다. 

이미 선언과 동시에 초기화 했는데 무슨 말인가 이해가 안되어서 찾아보니 내가 배웠던 언어인 c나 java, python 등에선 int total = a + b 형식으로 바로 계산식의 결과를 변수에 대입하여 선언과 동시에 초기화 할 수 있었지만 swift는 안되는듯 하다..

초기화 순서가 중요하다는데 무슨 말인지 정확히 이해가 안된다. age와 interestRate를 이미 선언과 동시에 초기화 했는데 결과값을 대입할 plusFirst 변수가 age와 interesRate의 값을 참조하려니 초기화가 안되어 있어서 에러가 난단다. 초기화를 했는데 초기화가 안되어 있다니 무슨 말인가 도대체.

이해되지 않는다면 일단 그렇다치고 넘어가는 것도 한 방법이라고 생각한다. 여러 코드를 작성해보다 보면 어느순간 이해되기도 하니까. 찾아보니 이를 해결하려면 연산 프로퍼티를 사용해야 한다고 한다. 연산 프로퍼티는 초기화 순서에서 자유로워 에러가 나지 않는다고 한다.

인터넷으로 찾은 연산 프로퍼티 방식으로 다시 선언해 계산 값을 반환한 다음, 배웠던대로 IBOutlet 방식으로 연결한 레이블에 출력값을 String 형태로 변환하여 출력하였다. 이것도 그냥 출력하니 레이블은 또 무조건 문자열로 출력해야해서 에러가 나서 String으로 형변환을 해야했다.

이후 튜플을 사용해 두 개의 숫자를 선언한뒤 더하는 코드를 작성하였다.

또 연산 프로퍼티 안쓰고 단순히 더해서 대입했다가 에러나서 아차싶었다. 습관의 무서움

튜플의 사용법 자체를 처음 알게된거라 찾아봐야 했지만 어려운 건 없었고, 값을 참조할 때 인덱스를 사용하길래 배열처럼 사용할 수 있는가 했는데, 배열이랑 달리 요소가 고정되어 있어서 배열처럼 동적으로 참조해 반복문으로 활용하는 건 안되고 굳이 하겠다면 배열 안에 여러 개의 튜플을 넣는다든가 하는 방식으로 활용이 가능한 것 같다. 예를 들어
tuples = [(1,”one”), (2,”two”), (3,”three”)]
식으로 선언하면 tuples는 배열이고 안의 (1,”one”)은 튜플인 식이다. 이걸 활용해
for myTuple in tuples { print("Number: \(tuple.0), Text: \(tuple.1)") } 이런 식으로 활용할 수 있는듯 하다.
이렇게 하면 첫 번째 줄에 Number:1, Text: one 두번째줄에 Number: 2, Text: two 이런 식으로 나올 것이다.

? 를 붙여 옵셔널로 선언하기

이어서 Any타입의 변수에 숫자를 대입하고 int형태로 출력하는 문제를 풀었다. 초기값을 넣어놓고 하는 건 의도한 방식이 아닌 것 같아서 초기값을 없애니 역시 에러가 났다. 어떻게 해야하나 찾아보니 옵셔널이라는 방법을 써서 초기화를 하지 않고 선언만 하는 것이 가능하고 나중에 값을 대입 하는 것도 가능한데, 나 같은 입문자는 거기서 문제를 겪을테니 고생해보는게 아마 문제가 의도한 내용이지 않았을까 한다.

그리고 출력하는 것도 이전 문제처럼 레이블로 출력하려니 무조건 String 타입이라 문제의 의도인 Int로 출력하라는 것도 안 맞는듯 해서 어떻게 할까 찾아보니 type(of: anyValue) 형식으로 타입도 Int임을 보일 수 있을 것 같았다.

정직하게 int로 대입하면 당연히 안되겠지 했지만 혹시나해서 해보니 정말로 안됐다..

아무 타입이나 저장할 수 있으니 그냥 하면 당연히 에러가 나겠지만 Int라고 지정해서 대입했는데도 왜 에러가 날까? 처음에 난 이것을 짧디 짧은 내 문제 풀이 코드만 생각해서 이해가 안됐는데, 코드가 길어져 복잡해지고 여러 사람과 협업해서 코드를 짜다보면 내가 지정해서 넣어놓더라도 변수는 언제든 값이 바뀔 수 있을 것이다. 그렇게 값이 변할 때 다른 변수와 달리 Any 타입의 변수는 어느 타입의 값도 대입할 수 있는 변수이니 int로 변할 수도, float으로 변할 수도, String으로 변할 수도 있는 것이니 당연히 예외처리를 해야 하는 것이다.

해결책을 찾아보니 항상 옵셔널 바인딩이란 걸 하지 않아서 런타임 에러가 난 것이라고 한다. 이 해결책을 찾는 과정에서 언래핑과 옵셔널 바인딩이라는 개념이 나왔는데 생소했다.

언래핑(Unwrapping)은 옵셔널에 저장된 값을 안전하게 추출하는 과정이고, 옵셔널 바인딩(Optional Binding)은 if let 구문을 사용하여 옵셔널의 값을 안전하게 추출하는 방법이라고 한다. 즉 예외처리를 언래핑, 그 방법 중 하나를 옵셔널 바인딩이라고 하는듯 하다.

숫자를 대입했을때 값과 자료형이, 문자열을 대입하니 int가 아니라는 문구가 의도대로 나왔다.

anyValue에 바로 숫자를 넣었고, 옵셔널 바인딩인 if let ~ as? 구문을 통해 값이 int형인지 확인 후 맞다면 값과 타입이 출력되도록, 아니라면 else 구문이 작동하도록 작성하여 값이 원하는 대로 출력됨을 확인하였다.

코딩을 배우면 어떤 언어든 맨 처음에 변수의 데이터 타입을 배우는 걸로 아는데, swift도 예외는 아니었다. 그러나 직관적으로 선언하고 가져다 쓰는 다른 언어와 달리 생각해야 할 게 많아 매우 단순한 코드를 작성하는데도 에러를 많이 겪었다. 연산 프로퍼티, 초기화 순서, 옵셔널, 언래핑, 옵셔널 바인딩, Any타입까지. 기초중의 기초인 데이터 타입가지고 이렇게 어려움을 겪을 줄은 몰랐는데 생각보다 공부가 많이 필요한 상태인듯 하다.