본문 바로가기

iOS/Swift

Swift 공식 문서 3. Strings and Characters (1)

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/stringsandcharacters

 

Documentation

 

docs.swift.org

 

 

Swift 공식 문서 보면서 내 맘대로 정리


 

  • Swift에서 문자열 및 문자 타입은 코드에서 텍스트를 유니코드 호환 방법으로 제공하고 문법적인 부분은 C와 비슷하다.
  • Swift의 String은 Foundation 프레임워크의 NSString이 bridge된 타입이기 때문에 NSString의 메서드를 String에서 캐스팅 없이 사용이 가능하다.

String Literals

  • 문자열을 여러줄에 쓰고 싶다면 """을 사용
  • """안의 문장 안에서 가독성을 위해 줄 바꿈 하고 싶지만, 문자열에는 반영 안하려면 백슬래시 \ 를 사용
  • 문자열의 시작과 끝에 각각 빈줄을 넣고 싶다면 한 줄을 띄워서 문자열을 입력
let quotation = """ 

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." 

"""

/*
"
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."
"
*/

Special Characters in String Literals

  • 문자열은 다음과 같은 특수문자를 포함할 수 있다.
  • \0 : 널문자
  • \\ : 백슬래시를 문자열에 사용
  • \t : 탭
  • \r : 캐리지 리턴, 커서를 줄의 맨 처음으로 보내는 기능
  • \" :  "를 문자열에 사용
  • \' : '를 문자열에 사용
  • \u{n} : 유니코드 사용 n은 1~8자리의 16진수 ex: 0F1A

Extended String Delimiters

  • 특수문자를 쓰는 것이 귀찮거나 \n과 같은 문자열을 사용하고 싶다면 #을 이용하라
let text1 = #"Line 1 \nLine 2"# // Line1 \nLine2 출력 
let text2 = #"Line 1 \#nLine 2"# // Line1 개행 Line2 출력 
let text3 = ###"Line 1 \###nLine 2"### // Line1 개행 Line2 출력

 

Initializing Empty String

  • 빈 문자열은 "" 또는 String() 으로 만들 수 있다.
  • 빈 문자열인지 확인하는 함수는 isEmpty()

String Mutability and Strings Are Value Types

  • var로 선언하면 수정할 수 있고 let으로 선언하면 수정할 수 없다.
  • String은 value 타입이다. 새로운 String을 만들면 그 값은 함수에 사용될 때 복사되어 사용된다.
  • 즉 아예 기존과 다른 새로운 값이 만들어지고 함수나 메서드로 전달된 문자열은 직접적으로 수정하지 않으면 변하지 않는다.
  • Swift 컴파일러는 문자열 사용을 최적화하여 실제 복사가 꼭 필요한 경우에만 이루어진다
  • → Copy On Write : 전달된 문자열이 수정 또는 복사가 필요한 경우만 실제 복사가 이루어진다.

Working with Characters

  • for-in 구문을 사용하면 한 글자씩 사용 가능
for character in "Dog!" { print(character) }
  • 만약 한 글자만 사용한다면 Character 타입으로 선언 가능
let mark : Character = "!"
  • String 은 Character 배열로 초기화할 수 있다.
let charArray : [Character] = ["D","o","g","!"] 
let dogString = String(charArray)
  • Character 값을 string에 추가하고 은 경우 append 메서드 사용. String에 String을 추가할 때는 + 또는 append 사용 가능.
    • + 는 새로운 문자열을 반환
    • append는 기존 문자열에 이어 붙인다.
let str1 = "hello"
let str2 = " there"
var welcome = str1 + str2
let exclamationMark: Character = "!" 
welcome.append(exclamationMark) // welcome now equals "hello there!"

String Interpolation

  • 문자열 보간이란 String에 상수, 변수, 리터럴, 연산 등의 값을 넣는 것을 의미한다.
  • \()를 문자열에 넣어주면 된다.
let multiplier = 3 
let message = "\\(multiplier) times 2.5 is \\(Double(multiplier) * 2.5)"

 

Unicode

  • Swift의 String, Character 타입은 유니코드 스칼라 값으로 구성된다.
  • 고유한 21 bit 숫자
    • 'a' -> U+0061
    • '🐥' -> U+1F425
  • 문자에 할당된 스칼라 값은 이름을 갖는다
    • U+0061 -> LATIN SMALL LETTER A
    • U+1F425 -> FRONT_FACING BABY CHICK
  • 모든 21 bit 유니코드 스칼라 값이 문자에 할당되는 것은 아님
    • 일부는 향후 할당을 위해 또는 UTF-16 인코딩에서 사용하기 위해 예약됨
    • 예를 들면 U+1F425 는 21bit 이므로 UTF-16에서 바로 16bit로 표현할 수 없음
    • U+D83D, U+DC25 두 개를 결합하여 원래의 문자를 표현하게 됨 (surrogate pair)

Extended Graphme Cluster

  • Swift의 Character 타입의 각 인스턴스는 하나의 확장된 문자소 클러스터를 갖는다.
  • 확장된 문자소 클러스터는 하나 이상의 유니코드 스칼라로 이뤄진 시퀀스
  • 이들이 결합되어 하나의 사람 눈에 보이는 문자로 표현된다.

Ex. é

  • LATIN SMALL LETTER E WITH ACUTE, U+00E9
  • 'e' 문자 (LATIN SMALL LETTER E, U+0065) 뒤에 COMBINING ACUTE ACCENT(U+0301)를 붙여서 표현
  • 위 . 두경우 모두 하나의 'Character'로 처리된다.
let eAcute: Character = "\u{E9}"               // é
let combinedEAcute: Character = "\u{65}\u{301}" // e +

eAcute == combinedEAcute // true
let precomposed: Character = "\u{D55C}"                  // 한 (사전 조합)
let decomposed: Character = "\u{1112}\u{1161}\u{11AB}"   // ᄒ, ᅡ, ᆫ (분해된 형태)
// precomposed is 한, decomposed is 한

 

Counting Characters

  • Extended Graphme Clusters 를 사용하기 때문에 문자열을 연결하거나 수정할 때 문자열의 문자 개수가 항상 예상대로 변하지 않을 수 있다.
  • 예를 들어, 'cafe' 문자열에 COMBINING ACUTE ACCENT를 문자열 끝에 추가해도 여전히 4개의 문자로 카운트 된다.
var word = "cafe" 
print("the number of characters in \(word) is \(word.count)")
// Prints "the number of characters in cafe is 4"

word += "\u{301}"    // COMBINING ACUTE ACCENT, U+0301
print("the number of characters in \(word) is \(word.count)")
// Prints "the number of characters in café is 4"

 

메모리 및 문자 개수 계산

  • Extended Graphme Clusters 는 여러 유니코드 스칼라로 구성될 수 있다.
  • 따라서 동일한 문자라도 다른 방식으로 표현이 가능하고 이를 저장하는데 필요한 메모리 양도 달라질 수 있다.
  • = Swift 문자열 내 각 문자는 동일한 메모리 공간을 차지하지 않는다.
  • 문자열의 문자 개수는 Extended Graphme Clusters의 경계를 파악하기 위해 문자열을 반복해서 계산해야 한다.
  • 매우 긴 문자열을 처리할 때 count 프로퍼티가 문자열의 모든 유니코드 스칼라를 반복하며 문자를 계산한다는 점을 염두에 두어야 한다.

NSString과 차이점

  • String의 count와 NSString의 length는 동일하지 않다.
  • NSString의 길이는 UTF-16 표현에서 16비트 코드 유닛의 개수에 기반
  • Extended Graphme Clusters의 개수에 기반하지 않는다.
let swiftString: String = "café"
let nsString: NSString = "café"

print("Swift String count: \(swiftString.count)") // 4
print("NSString length: \(nsString.length)") // 4

 

 

 

 

 

'iOS > Swift' 카테고리의 다른 글

Swift 공식문서 4. Collection Types  (0) 2024.09.08
Swift 공식 문서 3. Strings and Characters (2)  (1) 2024.08.31
Swift API Design Guidelines  (0) 2024.08.29
Swift 공식 문서 2. Basic Operator  (0) 2024.08.28
Swift 공식 문서 1. The Basics  (0) 2024.08.28