스위프트는 문자열 타입을 통해 일련의 캐릭터로 C와 유사한 리터럴 문법으로 문자열을 표현한다. 스위프트가 제공하는 문자열 타입의 특징은 다음과 같다.
+
연산자를 통해 가능하다.스위프트는 Foundation의 NSString 클래스를 통해 문자열을 캐스팅하지 않고 접근한다. 이후 클래스를 다룰 때 Foundation을 공부해보자.
문자열 리터럴을 "
로 감싸 상수 또는 변수로 선언할 수 있다.
한 줄이 넘어가는 문자열 리터럴을 쓰고 싶을 때에는 """
로 감싸주자. """
로 줄을 닫는 부분까지 모든 문자열이 포함된다.
let multi_str = """
The White Rabbit put on his spectacles. "Where shall I begin, \
please your Majesty?" he asked.
"Begin at the beginning," the King said gravely, "and go on \
till you come to the end; then stop."
"""
널, 백슬래쉬, 탭, 라인피드나 캐리지 리턴 등 다양한 특수문자 앞에 \
를 붙여 표현할 수 있다.
\u{n}
을 통해 표현한다. 이때 n
은 16진법 수다. $, ♥ 등 다양한 특수문자를 유니코드를 통해 표현할 수 있다.\n
, \t
등 특수 문자의 효과가 아니라 이 문자 자체를 출력할 때 #
을 사용한다.
""
또는 String()
을 통해 빈 문자열을 선언할 수 있다. 이때 isEmply 함수를 통해 확인하면 True가 return된다.
문자열 타입의 값이 바뀔 수 있다면 변수에, 그렇지 않기를 원하면 상수로 표현하자.
스위프트가 문자열을 상수와 변수로 표현해 mutability를 구분하는 방법은 Objective-C와 Cocoa에서 두 개의 문자열 클래스를 사용해야 하는 것과 차이가 있는데, 보다 간편하다.
문자열 값을 생성할 때 함수나 메소드, 상수나 변수에 할당될 때 값이 복사된다. 즉 지금 존재하는 문자열 값이 그대로 옮겨가는 게 아니라, 새로 만들어진 복사본이 사용된다.
스위프트가 지원하는 문자열 타입이 참조 타입이 아니라 값 타입이라는 사실에 주의하자.
문자열을 통해 문자열을 이루는 캐릭터 하나에 접근할 수 있다.
for character in "Dog!🐶" {
print(character)
}
// D
// o
// g
// !
// 🐶
캐릭터 하나만을 "
로 감싸 표현할 수도 있다.
let questionmark:Character = "?"
캐릭터 배열을 통해 문자열을 구성할 수 있다.
let arr_char: [Character] = ["C", "a", "t"]
let car_str = String(arr_char)
print(car_str)
// "Cat" printed
+
연산자를 통해 두 개 이상의 문자열 값을 합칠 수 있다. 복합 대입 연산자 +=
역시 응용할 수 있다.
let str1 = "Hello"
let str2 = "Swift"
var str3 = str1 + " " + str2 + "!"
print(str3)
// "Hello Swift!" printed
문자열 값에 캐릭터를 더해주는 append 메소드는 문자열 마지막 부분에 그대로 캐릭터를 더해준다. 이때 문자열이나 캐릭터를 캐릭터 변수에 append할 수 없음을 주의하자. 기본적으로 캐릭터 값 크기는 1개의 캐릭터이기 때문이다.
var str1:String = "Hello"
var str2:Character = "!"
str1.append(str2)
print(str1)
// "Hello!" printed
문자열 합성을 할 때 출력값을 확인할 때 라인 피드/캐리지 리턴도 신경쓸 필요가 있다.
보간법이라 불리는 interpolation을 통해 간단하게 문자열 리터럴 안에 (이미 상수나 변수로 표현한) 다른 문자열 값을 넣을 수 있다. \(str)
을 통해 "
안에 들어갈 문자열을 감싸준다.
만일 \()
이라는 표현을 인터폴레이션 용도가 아니라 리터럴 그 자체로 표현하고 싶다면, 앞서 다룬 #
을 통해 풀어 쓰자.
let speed = 100
var msg = "Do not exceed speed limit: \(speed)km/h"
print(msg)
// "Do not exceed speed limit: 100km/h" printed
리터럴을 간편하게 출력할 때도 사용되지만, 사용자 입력값을 다루는 데 매우 편리한 방법이다.
유니코드는 다양한 문자 체계를 지원하는 국제 표준 코드로 텍스트를 인코딩, 표현, 가공하는 데 사용된다. 유니코드를 통해 표준화된 형태로 지구 상의 어떤 언어든 표현할 수 있다.
텍스트 파일과 웹 페이지의 외부 소스 파일에서 유니코드 문자를 사용해 문자열과 캐릭터를 사용할 수 있다. 스위프트의 문자열과 캐릭터 타입 또한 완전히 유니코드와 호환 가능하다.
스위프트의 네이티브 문자열 타입은 유니코드 스칼라 값으로 이루어져 있다. 유니코드 스칼라 값은 21비트로 된 고유 수를 통해 캐릭터 또는 모디파이어를 표현한다. 이때 일부는 다른 값을 할당하기 위해 남겨두거나 UTF-16 인코딩에 사용된다.
확장된 문자소 클러스터는 하나 이상의 유니코드 스칼라 값을 결합한 형태로 인간이 읽을 수 있는 캐릭터를 만든다. 즉 이 하나의(single) 클러스터가 스위프트의 캐릭터 타입으로 표현된다.
예를 들어 é
는 é
를 표현하는 단일한 클러스터가 아니라 e
와 ́
두 스칼라 값을 합친 형태로 표현된다. 한글 또한 마찬가지로 한
은 ㅎ
, ㅏ
, ㄴ
을 조합한 형태이다.
문자열을 이루는 캐릭터가 몇 개인지 count를 사용해 알 수 있다.
let unusualMenagerie = "Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪"
print("unusualMenagerie has \(unusualMenagerie.count) characters")
// Prints "unusualMenagerie has 40 characters"
위 문자열에서 사용된 🐨 등은 확장된 문자소 클러스터이기 때문에 각 스칼라 값을 따로 카운트할 것 같지만, 그렇지 않다. 한
의 글자 수를 count할 때 3이 아니라 1이 return됨을 기억하자.
NSString의 length 메소드를 통해 반환된 문자열 내 캐릭터 개수는 UTF-16 내 16비트 코드 단위 개수이기 때문에 확장된 문자소 클러스터 형태로 유니코드 개수를 반환하는 스위프트의 count 메소드가 반환하는 길이와는 다를 수 있다.