사실 반복문 쓰기 전에 변수랑 상수 먼저 설명해야 이해하기 쉬웠을 텐데 뭐 지금이라도 쓰는 게 어디야 🙂
변수랑 상수의 개념은 다들 알거라 생각하고 간단하게 넘어가야지라고 하기엔 내가 알고 있는건 밑에 있는 게 전부..?
1. 변수와 상수
- 변수 : 데이터형에 맞는 값이 변경이 가능한 메모리 공간
- 상수 : 변하지 않는 값, 고정되어 있는 수
다시 본론으로 넘어가서 스위프트는 데이터가 저장되는 메모리 내 주소 공간을 개발자가 쉽게 인식하고 사용할 수 있도록 변수와 상수를 제공한다.
📝 설명 할 만한 사진이 없어 직접 만들어봤지 하핳..
간단한 예시로 연도를 의미하는 2023이라는 숫자 데이터가 메모리 주소 0x1234567 ~ 0x123457C까지 걸쳐 저장되었다고 해보자.
이 데이터를 꺼낼 때마다 항상 이 주소값을 사용할 수 없다. 사용하기엔 주소값이 너무 길고, 단순히 16진수 숫자들로만 돼 있어 외우기도 어렵다. 그렇기 때문이 이 주소값을 "Year"라는 이름으로 연결하는것 이다.
이름으로 메모리 주소를 등록해두지 않았다면 저장된 값을 꺼내기 위해서는 주소 공간 하나하나를 직접 찾아 값을 합쳐서 사용해야 하지만, 이름을 저장해 놓는다면 Year 단어 하나로 저장된 값을 쉽게 불러올 수 있다.
이렇게 값을 저장한, 혹은 저장할 메모리 주소값을 이름으로 연결해 놓은 것을 변수와 상수라고 한다.
변수와 상수는 값을 저장할 수 있다는 공통점이 있지만 상수는 한 번 저장된 값을 다른 값으로 변경할 수 없는 반면에 변수는 필요에 따라 저장된 값을 몇 번이라도 다른 값으로 변경할 수 있다. 그래서 보통 변수에는 프로그램의 실행에 따라 변하는 값, 상수에는 변하지 않을 값을 저장한다.
그렇다고 변수라고 해서 아무 값이나 저장해도 되냐 하면 답은 X 라고 할 수 있다. 변수의 값을 변경할 때에는 처음 저장했던 값과 일치하는 타입이어야 한다.
📝 Int -> Int ⭕️, float -> float ⭕️, String -> String ⭕️, String -> Int ❌
😡 : 그럼 상수는 왜 필요하냐 변수에 값을 저장해 놓고 변경하면 그만이지 !!
이렇게 말을 한다면 성능이나 기타 다른 기술적 이점을 차지하더라도, 프로그래밍 소스 관리 목적상 변하지 않는 값은 상수에 저장하는 것이 훨씬 효율적이기 때문이다.
어떠한 경우에 변수를 사용하고 어떤 경우에 상수를 사용할지 기준이 모호하다면 일단 변수로 작성하면 된다.
스위프트에서는 변수에 한번 할당된 이후 소스코드에서 변경되지 않은 값이 있을 경우 상수로 바꾸도록 컴파일러가 조언해준다고 한다.
📝 신기... 사실 공부해서 컴파일러 조언 안 받고 할 수 있는 게 목적 하다보면 이해되겠지
2. 변수와 상수를 정의하는 방법
스위프트에서 변수와 상수를 선언하려면 키워드를 사용해야 하는데, 변수는 var, 상수는 let 키워드를 사용한다.
- 변수 선언 : var + 변수명
- 상수 선언 : let + 상수명
변수를 정의하는 방법부터 살펴보자.
// 정수형 변수
var year = 1999
// 문자열 변수
var name = "Sheep1sik"
같은 var 키워드를 사용해 변수에 각각 다른 값을 넣었지만 year 변수는 정수형 타입으로 name 변수는 문자열 타입으로 정해졌기 때문에 그 이후에도 year 변수에는 정수, name 변수에는 문자열 타입으로만 값을 넣을 수 있다.
한 번 정해진 타입은 바꿀 수 없다는 규칙이 적용되는 것이다.
var 키워드로 선언된 변수에 처음으로 값을 대입하는 과정을 초기화(Initialize) 라고 한다.
스위프트는 대부분 초기화 과정에서 변수의 타입이 결정되는데, 컴파일러는 변수에 대입될 값을 검토하여 가장 적절한 타입으로 추론하고 그에 맞는 메모리 공간을 확보한 다음 값을 저장한다.
스위프트가 아닌 다른 일부 프로그래밍 언어에서는 변수를 선언하는 과정과 초기화 과정을 반드시 분리하여 작성하도록 강제하기도 한다.
📝 먼저 선언을 한 다음 초기화를 하는 거를 말하지?
// 변수 정의 2단계
// 1단계 - 변수 선언
var year
// 2단계 - 변수 초기화
year = 1999
위처럼 단계를 보다 명확하게 나눌 수 있겠지만 불편하고 번거로운 과정이다.
📝 물론 귀차니즘이 심한 나도 그렇게 생각하기도 한다 한번 써도 될걸 두 번 쓰잖아 😇
하지만 스위프트에서는 이 두 과정을 나눌 필요 없이 한꺼번에 처리할 수 있다.
📝 선언과 초기화가 함께 들어있는 셈 매우 편함!! 👏🏻👏🏻👏🏻 사실 C나 C++ 할 때도 선언과 초기화 같이 하긴 했지.. 그냥 찬양하고 싶었어
상수의 경우를 살펴보자. 상수도 큰 차이는 없고 선언 키워드가 var가 아니라 let이라는 점이 다를 뿐이다.
// 상수 정의
// 정수형 상수
let year = 1999
// 문자열 상수
let name = "Sheep1sik"
종종 '=' 연산자와 초기값 사이에 가독성을 위해 공백을 두기도 하는데 스위프트에서는 연산자 바로 뒤에 연이어 나오는 공백들은 모두 무시한다. 단, 공백의 여부는 연산자의 앞과 뒤가 모두 동일하기 적용되어야 한다.
// 예시
let year =1999 // X
let year= 1999 // X
let year = 1999 // O
상수는 먼저 저장된 값은 변경할 수 없다고 했는데, 억지로 변경하면 어떤 일이 일어나는지 코드로 확인해 보자.
vValue에 먼저 3을 대입하여 초기화한 다음, 이어서 7을 대입했다. vValue는 변수이므로 같은 타입의 값이라면 얼마든지 변경이 가능하므로 오류가 없이 실행이 되는 걸 볼 수 있다.
하지만 동일한 코드라도 상수의 경우에는 오류가 뜨는 것을 볼 수 있다.
Cannot assign to value 'cValue' is a 'let' constant
해석하자면 cValue는 상수로 선언되었기 때문에 새로운 값을 할당할 수 없다는 뜻이다.
메시지에서 보여주듯이, 초기화된 상수의 값은 결코 변경할 수 없다.
플레이그라운드에서는 오류 메시지의 표기뿐만 아니라 간단한 해결 방법까지 권고해 준다.
변수의 타입과 일치하지 않는 값을 대입했을 때 어떤 일이 일어나는지 확인해 보자.
가장 먼저 2행에서 intValue 변수의 초기값으로 3을 대입했다. 초기화한 값이 Int 타입이므로 intValue에 대입할 수 있는 건 Int 타입으로 제한된다. strValue도 동일하게 String 타입으로 초기화했으므로 String 타입으로 제한된 상황이다.
6행에서는 intValue의 값을 String 타입으로, strValue의 값은 Int 타입으로 변경하려고 했지만 초기화한 타입과 다르기 때문에 오류가 뜨는 걸 볼 수 있다.
이처럼 스위프트에서 상수는 처음 값을 할당한 이후 값을 변경할 수 없으며, 변수의 값을 변경하고자 할 때에는 타입이 맞는 값을 사용해야 한다.
📝 생각보다 정리할게 많아서 2탄으로..
📝 2탄 업로드 완료 ! 바로 2탄 보러 가자구~~😆😆
Swift 변수와 상수 2
쓰다 보니 말이 길어질 거 같아 2편으로 시작!! 1편을 안보고 왔으면 보고 오는 걸 추천합니다 🙂 Swift 변수와 상수 1 사실 반복문 쓰기 전에 변수랑 상수 먼저 설명해야 이해하기 쉬웠을 텐데 뭐
sheep1sik.tistory.com
'메모장' 카테고리의 다른 글
Swift 기본 자료형 1 (2) | 2023.03.04 |
---|---|
Swift 변수와 상수 2 (2) | 2023.03.02 |
Swift 반복문 [ while 편 ] (5) | 2023.02.28 |
Swift 반복문 [ for - in 편 ] (5) | 2023.02.27 |
Swift 와 Objective-C 차이 (4) | 2023.02.27 |