본문 바로가기
swift

스위프트 자료형

by 승환파크 2024. 4. 3.

일반적으로 서로 다른 타입의 데이터끼리 연산을 시도할 때 처리하는 기준은 프로그래밍 언어마다 서로 다르다. 스위프트를 포함한 대다수 언어에서 실수와 정수는 일부 호환이 가능하며, 일반적으로 정수를 실수로 변환하여 연산을 처리하는 경우가 많다. 정수를 실수로 변환할 때에는 값의 손실이 발생하지 않지만, 실수를 정수로 변환하려면 값의 손실이 발생할 수 있기 때문이다.

 

문자와 숫자를 결합하는 경우에는 조금 더 주의해야 한다. 문자와 숫자 양쪽을 모두 문자로 간주하고 알아서 처리하는 자바스크립트 같은 편리한 언어도 있지만 스위프트에서는 문자와 숫자를 바로 결합할 경우 오류로 처리한다. 이는 방금 전에 언급한 것처럼 어느 쪽으로 타입을 맞추어야 할지 기준이 모호하기 때문이다.

 

여기서 말하고자 하는 것은 값의 종류가 일치해야만 그에 맞는 처리가 가능하다는 것이다. 단, 한 가지 전제가 있다. 변수나 상수에 할당되는 값은 모두 타입이 구분 될 수 있어야 한다. 또한 타입 별로 메모리 공간의 크기가 달라져야 하는 것도 하나의 이유이다.

 

이런 이유들 때문에 스위프트에서는 변수나 상수를 정의할 때 반드시 숫자, 문자, 문자열, 논리(참/거짓) 등 몇 가지 종류의 타입을 지정하고 그에 맞추어 사용해야 한다. 이를 데이터 타입(Data Type), 즉, 자료형이라고 한다. 변수나 상수는 일반적으로 처음 입력되는 값에 맞는 자료형으로 초기화되며, 이후로는 해당 자료형에 호환되는 형식의 값만 저장할 수 있다. 그렇지 않을경우 오류를 발생시킨다.

 

기본 자료형

Int

Int는 정수를 뜻하는 Integer라는 영어 단어의 줄임말로, 부호 있는 정수값을 저장하는데 사용되는 자료형이다. 부호 있는 정수값을 저장하려면 해당 변수나 상수를 이 타입으로 지정해야 한다는 것이다. 여기에서 부호가 있다는 말은 숫자 앞에 +나 -를 붙일 수 있다는 의미이다.

 

하지만 무한대에 가까운 모든 정수값을 저장할 수 있는 것은 아니다. Int 타입이 저장할 수 있는 정수값의 범위에는 제한이 있는데, 이 제한은 컴퓨터 CPU 사용에 따라 결정된다. 가령 8bit의 CPU를 가진 컴퓨터라면 2^8인 256개의 값을 저장할 수 있다. 이를 정수 범위로 환산하여 계산하면 Int 타입이 저장할 수 있는 값은 -128 ~ 127까지 이다.

 

지금은 8bit CPU에서 Int 를 사용하는 경우를 이야기해 보았지만, 사실 8bit 범위만 사용하는 Int의 경우 스위프트에서는 서브 자료형이 별도로 정의되어 있다. 바로 Int8이다. Int를 8bit 크기로 사용하겠다는 의미이다. 유사한 자료형으로 Int16, Int32, Int64도 있다. 각각 16, 32, 64bit의 Int 타입을 의미한다.

  • Int8 => 127 ~ -128
  • Int16 => 32,767 ~ -32,378
  • Int32 => 2,147,483,647 ~ -2,147,483,648
  • Int64 => 9,223,372,036,854,775,807 ~ -9,223,372,036,854,775,808

 

UInt

UInt는 Unsigned Integer를 줄인 단어로 부호가 없는 정수를 의미한다. Int처럼 정수값을 저장하는 데 사용되는 자료형이지만 Int가 양수부터 음수까지를 모두 저장할 수 있는 반면 UInt는 양수만 저장할 수 있다는 차이가 있다. 다시 말해, UInt는 0을 포함하여 1, 2, 3, 4, 5, ... 등 우리가 일반적으로 자연수라고 부르는 범위의 정수를 저장할 수 있다는 것이다.

  • UInt8 => 0 ~ 256

  • UInt16 => 0 ~ 65,535

  • UInt32 => 0 ~ 4,294,967,295

  • UInt64 => 0 ~ 18,446,744,073,709,551,615

 

Double & Float

프로그래밍을 하다 보면 소수점이 포함된 실수 값을 저장해야 하는 경우도 무척 많다. 두 장소 사이의 거리나, 기온, 환율 또는 키, 몸무게 등 수많은 종류의 데이터가 정수가 아닌 실수 값을 요구한다.

 

이 때 사용할 수 있는 자료형이 double 타입과 Float 타입이다. 둘 다 실수값을 저장할 수 있는 자료형이라는 공통점이 있지만, Double 타입은 64bit 부동 소수점 자료형으로써 32bit 부동 소수점 자료형인 Float 타입보다 더 넓은 범위의 소수점 아래 값을 저장할 수 있기 때문에, 특별히 매우 정확해야 하는 부동 소수점 값이나 또는 매우 넓은 범위의 실수값을 저장할 때 사용된다. 그 이외의 부동 소수점 값에는 Float 자료형이 사용된다.

 

일반적으로 Float 타입이 소수점 아래 7 ~ 8 자리까지의 값을 정확하게 저장할 수 있는 반면, Double 타입은 소수점 아래 15 ~ 16 자리의 값에 대한 정확도를 보장하기 때문에 훨씬 더 세밀한 값을 저장하는 데에 유리하다. 당연히 메모리에서 차지하는 크기도 Double 타입이 더 크다.

 

Bool

Bool 타입은 true/false 두 가지 종류의 값만 가질 수 있는 자료형으로써 주로 논리값을 저장하기 위해 사용된다.

// Bool 타입 저장 변수
var close = true

// Bool 타입 저장 상수
let success = true
let fail = false

 

 

String

String 타입은 Int와 더불어 프로그래밍에서 가장 많이 사용되는 자료형으로, 문자열을 저장할 때 사용한다.

 

스위프트는 String 타입 데이터의 값을 표현할 때 큰따옴표를 사용한다.

// String 타입 저장 변수
var projectName = "iOS study"

// String 타입 저장 상수
let language = "swift"

 

 

Character

앞서 소개한 String은 여러 글자로 이루어진 문자열을 저장할 수 있는 일종의 집단 자료형이지만, Character는 한 개의 문자를 저장할 수 있는 단일 자료형이다. String 타입에 저장된 문자열을 하나씩 분해하면 Character 타입이 된다.

 

스위프트는 Character 타입의 데이터 값을 표현할 때도 String 타입과 마찬가지로 큰따옴표를 사용한다.

// Character 타입 저장 변수
var firstLetter : Character = "s"

// Character 타입 저장 상수
let lastLetter : Character = "t"

 

 

타입 추론과 타입 어노테이션

타입 어노테이션(Type annotation)이란, 변수나 상수를 선언할 때 그 타입을 명시적으로 선언해 줌으로써 어떤 타입의 값이 저장될 것인지를 컴파일러에 직접 알려주는 문법이다. 변수나 상수명 뒤에 콜론(:)을 붙이고, 이어서 저장될 값의 타입을 작성해주면 된다.

var year : Int // 명시적인 Int 타입
var name : String // 명시적인 String 타입
var firstChar : Character // 명시적인 Character 타입
var distance : Double // 명시적인 Double 타입
var pi : Float // 명시적인 Float 타입
va flag : Bool // 명시적인 Bool 타입

 

앞에서는 변수나 상수를 선언할 때 타입을 명시해 준 적이 없었고, 그냥 값만 넣어서 초기화 해주었는데, 여기서는 타입이 명시되어 있다.

 

그 이유를 알기위해서는 먼저 타입 추론에 대해서 알아야 한다. 스위프트의 특성중에는 설계에 의한 안전성(Safety by design)이라는 항목이 있다. 아키텍처적인 안전성을 담보하기 위해 스위프트가 여러 장치를 도입했다는 것이 핵심 내용이다. 그 중 하나가 바로 타입 추론 기능이다.

 

타입 추론은 변수나 상수를 초기화할 때 입력된 값을 분석하여 변수에 적절한 타입을 컴파일러가 스스로 추론하는 기능이다. 초기값으로 "Hello, World"가 입력되었다면 '이 변수의 타입은 String 이겠구나' 라고 추론하는 것 등이 이에 해당한다. 이 덕분에 변수나 상수에 명시적으로 타입을 지정해 주지 않아도 가능한 것 이었다.

// 타입을 명시한 변수 선언
var name : String = "홍길동"
var year : Int = 1999

// 타입을 명시한 상수 선언
let firstName : String = "이"
let birthYear : Int = 1980

// 타입을 명시하지 않은 변수 선언
var name = "홍길동"
var year = 1999

// 타입을 명시하지 않은 상수 선언
let firstName = "이"
let birthYear = 1980

 

 

타입 어노테이션을 써야할 지 말아야 할지 고민이 될 경우에는 반드시 타입 어노테이션을 사용해야 하는 아래의 두가지 경우를 제외하면 타입을 명시적으로 선언하지 않아도 된다.

  1. 선언과 초기화를 분리할 경우
  2. 타입 추론으로 얻어지는 데이터가 아닌, 다른 타입을 직접 지정할 필요가 있을 때
// 선언 + 타입 어노테이션
var year : Int

// 초기화
year = 1999

// Int 타입으로 정의
var temper1 = 3
// Float 타입으로 정의
var Temper2 : Float = 3

var stringValue = "문자열" // String 타입
var charValue : Character = "문" // Character 타입

var cValue : Character = "C" // Character 타입
var sValue = "C" // String 타입

 

앞의 두가지 경우를 제외한 나머지는 타입 어노테이션을 생략하고 타입 추론에 의존하면 된다. 하지만 다른 이유로 타입 어노테이션을 무조건 사용하려는 사람도 존재한다.

 

타입이 다른 변수끼리의 결합

프로그래밍 과정에서는 서로 다른 타입의 변수나 상수를 결합해야 하는 경우가 종종 발생한다. 하지만 스위프트에서 서로 다른 타입의 변수나 상수끼리의 결합 연산은 허용되지 않는다. 변수의 타입을 변경해서 결합해 보려고 해도, 한 번 타입이 정해지고 나면 다른 타입으로 변경할 수도 없다. 이 때 서로 다른 변수를 결합하려면 아래와 같다.

 

변수의 값을 다른 타입으로 변경해야 할 필요가 있다면, 바꾸고자 하는 타입의 새로운 객체를 명시적으로 생성해야 한다. 이 때 객체는 보통의 변수나 상수를 의미한다. 다행히 스위프트 기본 자료형 객체들은 다른 타입의 값을 자신의 타입에 맞게 변환하여 새로운 객체를 만드는 방법을 제공한다. String의 경우 String()이라는 형식으로 이를 지원한다. 괄호 안에 원하는 정수값을 넣으면 문자열이 만들어지는 방식이다. 정수값이나 기존의 변수를 문자열 타입으로 바꾸는 것이 아니라, 새로운 문자열 인스턴스를 마드는 것이다 .기존의 변수에는 아무런 영향 없이, 새로 생성하는 것 이라는 점에 주의해야 한다.

 

문자열을 정수형이나 실수형으로 바꿀 때에도 이와 비슷한 방식이 적용된다. 문자열을 정수형으로 바꾸려면 다음과 같이 Int() 구문을 사용하면 된다. 앞의 문자열 방식처럼 새로운 정수 인스턴스가 생성되는 것이다.

 

문자열 템플릿

서로 다른 타입의 변수를 문자열로 결합하는 것만 생각한다면 문자열 템플릿을 사용하여 쉽게 처리할 수 있다. 문자열 템플릿은 변수나 상수의 값을 문자열 속에 포함시키는 방식으로, 정수나 실수 등 문자열이 아닌 값도 변환 괒어 없이 사용할 수 있도록 스위프트가 제공하는 기능이다.

 

문자열 템플릿을 사용하는 방식은 매우 간단하다. 문자열에서 원하는 위치에 백슬래시(\)를 입력하고, 포함하려는 값이 들어있는 변수나 상수를 괄호로 감싸면 된다.

// 상수와 변수를 정의
let name = "꼼꼼한 재은씨"
let year = 2014
let month = 10
let day = 1

// 문자열 템플릿을 사용한 문자열 결합
let profile = "\(name)는 \(year)년 \(month)월 \(day)일에 출간되었습니다."

print(profile)

// 결과값
// 꼼꼼한 재은씨는 2014년 10월 1일에 출간되었습니다.

 

문자열 템플릿의 기능은 이뿐만이 아니다. 문자여 템플릿을 이용하면 괄호 내부에서 값을 연산할 수도 있다.

// 상수 정의
let apple = 3
let banana = 2
let orange = 4

// 출력할 구문을 문자열 템플릿으로 구성
let desc = "과일은 총 \(apple + banana + orange)개 입니다."

print(desc)

// 결과값
// 과일은 총 9개 입니다.

 

스위프트 4에서의 문자열 처리

스위프트 4에서는 새로운 쿼우팅 문법이 추가되었다. 이른바 트리플 쿼우팅(Triple Quoting), 또는 멀티 라인 문자열(Multi-line String)이라고 불리는 것으로, 연속한 세 개의 따옴표를 이용하여 여러 줄에 걸친 긴 문자열을 손쉽게 작성하는 문법이다.

 

쿼우팅(Quoting)

쿼우팅이란 문자열을 따옴표로 묶어 표시하는 방법으로, 프로그래밍 코드 뿐만 아니라 쉘 커맨드에서도 사용된다. 프로그래밍 코드에서 쿼우팅은 대부분 문자열을 정의하거나 표현하는 용도로 사용된다.

var message = "Hello"

 

멀티 라인 스트링(multi-line String)

큰따옴표 세 개를 연속으로 붙여서 쿼우팅 영역의 시작과 끝을 정의하고(""" ~~ """) 그 내부에서 자유롭게 작성된 문자열을 그대로 실제 내용으로 처리하는 방식이다.

 

멀티 라인 스트링으로 작성된 문자열은 띄어쓰기나 줄바꿈 등이 작성된 그대로 반영되기 때문에, 문자열에 형식을 부여하기 위해 복잡한 코드를 처리할 필요가 없다. 단순히 트리플 쿼우팅으로 시작과 끝을 지정한 다음, 범위 내에서 원하는 문자열을 작성하면 된다.

 

멀티 라인 스트링을 사용할 때에는 몇 가지 주의사항이 있는데 주로 아래와 같다.

  • 시작 쿼우팅 다음에는 반드시 줄바꿈 후 값을 작성해야 한다. 쿼우팅이 시작된 라인에서는 쿼우팅 이후 어떤 값도 들어가서는 안된다.
  • 멀티 라인 스트링의 입력을 끝낼 때에는 반드시 줄바꿈 이후 쿼우팅 처리를 해야한다. 쿼우팅을 종료하는 라인에서는 쿼우팅 앞에 어떤 값도 들어가서는 안된다.
  • 멀티 라인 쿼우팅 내부에 특수문자, 또는 이스케이프 코드가 들어가면 문자 그대로 출력된다.
let poem = """
계절이 지나가는 하늘에는
가을로 가득 차 있습니다.
나는 아무 걱정도 없이 가슴 속의 별들을
다 헬 듯 합니다.
"""

print(poem)

// 결과값
// 계절이 지나가는 하늘에는
// 가을로 가득 차 있습니다.
// 나는 아무 걱정도 없이 가슴 속의 별들을
// 다 헬 듯 합니다.

'swift' 카테고리의 다른 글

스위프트 조건문  (0) 2024.04.06
스위프트 반복문  (1) 2024.04.05
스위프트 연산자  (1) 2024.04.03
스위프트 변수와 상수  (2) 2024.04.03
스위프트 기초 문법  (0) 2024.04.02