본문 바로가기
프로그래밍/Swift

[Swift] 문자열과 문자 (Strings and Characters)

by 별준 2021. 12. 14.

References

Contents

  • String Literals
  • Initializing Empty String
  • String Mutability
  • Strings are Value Types
  • Working with Characters
  • Concatenating Strings and Characters
  • String Interpolation
  • Unicode
  • Counting Characters
  • Accessing and Modifying a String
  • Substrings
  • Comparing Strings
  • Unicode Representations of Strings

Strings(문자열)은 "Hello, world"와 같은 일련의 Character(문자)들입니다. Swift의 문자열은 String 타입으로 표현되고, String은 다양한 방법으로 액세스될 수 있습니다. Swift의 문자열과 문자 타입은 코드에서 텍스트를 다루는 빠르고 유니코드가 호환되는 방법을 제공합니다. 문자열을 생성하거나 조작하는 문법은 매우 가볍고 읽기 쉽습니다. 문자열을 결합하는 것은 '+' 연산자를 통해 매우 간단하게 결합할 수 있습니다. 또한, 문자열에 상수, 변수, 리터럴, 표현식을 삽입할 수 있는데, 이를 string interpolation이라고 합니다. 모든 문자열은 인코딩 독립적인 유니코드 문자로 구성되고, 다양한 유니코드 표현에서 해당 문자들에 액세스할 수 있도록 지원합니다.

Swift의 String은 Foundation 프레임워크의 NSString이 bridge된 타입이라고 합니다. 아직 Foundation 프레임워크나 NSString에 대해서 잘 알지 못하기 때문에 추후에 기회가 된다면 자세히 알아보겠습니다.

String Literals

문자열 리터럴(String Literals)는 큰따옴표(")로 둘러싸인 문자들의 시퀀스입니다. 문자열 리터럴을 통해 상수나 변수의 초기값을 지정할 수 있습니다.

let someString = "Some string literal value"

(문자열로 초기화되기 때문에 Swift는 someString의 타입을 문자열로 추론합니다.)

 

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

이렇게 세 개의 큰따옴표를 처음과 끝에 위치시켜 그 사이에 포함하는 여러 줄에 걸친 모든 문자들을 포함합니다.

 

let singleLineString = "These are the same."
let multilineString = """
These are the same.
"""

멀티라인 문자열 리터럴 내부에 줄 바꿈이 포함된 경우, 줄 바꿈은 문자열의 값에 나타납니다. 만약 단지 읽기 쉽도록 줄 바꿈을 사용하려고 하지만, 줄바꿈을 실제 문자열의 값의 일부로 사용하지 않으려면 줄 끝에 백슬래시(\)를 사용하면 됩니다.

let softWrappedQuotation = """
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 (null character)
  • \\ (backslash)
  • \t (horizontal tab)
  • \n (line feed)
  • \r (carriage return)
  • \" (double quotation mark)
  • \' (single quotation mark)

유니코드 스칼라 값(Unicode scalar value)

  • \u{n} : n은 1-8자리의 16진수 (아래에서 조금 더 자세히 설명하겠습니다.)

아래 코드는 이러한 특수한 문자들의 예시를 보여주고 있습니다.

let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"
// "Imagination is more important than knowledge" - Einstein
let dollarSign = "\u{24}"        // $,  Unicode scalar U+0024
let blackHeart = "\u{2665}"      // ♥,  Unicode scalar U+2665
let sparklingHeart = "\u{1F496}" // 💖, Unicode scalar U+1F496

멀티라인 문자열은 세 개의 큰따옴표(""")를 사용하므로 큰따옴표(")를 사용할 때 이스케이프 문자를 사용하지 않고 사용할 수 있습니다. """을 포함하려면 다음과 같이 이스케이프 문자를 사용해야 합니다.

 

Extended String Delimiters

확장된 구분자(extended delimiters)를 사용하여 특수 문자(ex, 이스케이프 문자)를 문자열에 포함시킬 수 있습니다. 문자열을 큰따옴표(") 내에 위치시키고 숫자 기호(#)으로 또 한번 둘러쌉니다.

예를 들어, #"Line 1\nLin2"# 을 출력해보면, 문자열이 두 줄로 출력되지 않고 이스케이프 문자가 그대로 출력됩니다.

만약 특수 문자의 효과도 필요한 경우에는 문자열 내에서 숫자 기호(#)를 이스케이프 문자(\) 뒤에 추가합니다.

문자열을 둘러싼 #의 개수는 제한이 없는 것 같습니다. 다만, 그 개수는 문자열에서 일치시켜주어야 합니다.

여러 줄에 걸친 문자열도 가능합니다.

let threeMoreDoubleQuotationMarks = #"""
Here are three more double quotes: """
"""#

Initializing an Empty String

빈 String 값을 생성하려면 변수에 빈 문자열 리터럴을 할당하거나 초기화 구문을 사용하여 문자열 인스턴스를 초기화할 수 있습니다.

var emptyString = ""               // empty string literal
var anotherEmptyString = String()  // initializer syntax
// these two strings are both empty, and are equivalent to each other

그리고, isEmpty 속성을 사용하여 문자열값이 비어있는지 확인할 수 있습니다.

if emptyString.isEmpty {
    print("Nothing to see here")
}
// Prints "Nothing to see here"

String Mutability

문자열이 변수에 할당되어 있는 경우, 수정이 가능합니다. 상수인 경우에는 수정이 불가능합니다.

var variableString = "Horse"
variableString += " and carriage"
// variableString is now "Horse and carriage"

let constantString = "Highlander"
constantString += " and another Highlander"
// this reports a compile-time error - a constant string cannot be modified

Strings are Value Types

Swift의 문자열 타입은 value type입니다. 새로운 문자열 값을 생성하는 경우 해당 문자열 값은 함수 또는 메소드에 전달되거나 상수/변수에 할당될 때 복사됩니다. 따라서 기존의 문자열 값의 새로운 복사본이 생성되고 전달되거나 할당됩니다.

이러한 copy-by-default 동작은 함수나 메소드로 문자열 값을 전달할 때, 어디에서 전달되었는지간에 정확한 문자열의 값을 가지는 것이 확실하도록 합니다. 이렇게 전달한 문자열은 직접 수정하지 않는 한 수정되지 않습니다.

(반대로 할당받은 문자열을 수정해도 원본에 영향을 미치지 않습니다.)

Swift 컴파일러는 문자열 사용을 최적화하여 실제 복사가 꼭 필요할 때만 수행되도록 합니다. 따라서 문자열을 value type으로 사용할 때 항상 좋은 성능을 얻을 수 있습니다.


Working with Characters

문자열에서 for-in 루프를 사용해 개별 문자(Character) 값에 접근할 수 있습니다.

for character in "Dog!🐶" {
    print(character)
}
// D
// o
// g
// !
// 🐶

 

또는, Character 타입 annotation을 명시적으로 제공하여, 단일 문자열 리터럴로부터 문자 상수 또는 변수를 생성할 수 있습니다.

let exclamationMark: Character = "!"

 

문자열 값은 문자들의 배열을 initializer의 인수로 전달하여 생성할 수도 있습니다.

let catCharacters: [Character] = ["C", "a", "t", "!", "🐱"]
let catString = String(catCharacters)
print(catString)
// Prints "Cat!🐱"

Concatenating Strings and Characters

문자열 값을 + 연산자를 통해 추가하거나 연결하여 새로운 문자열 값을 생성할 수 있습니다.

let string1 = "hello"
let string2 = " there"
var welcome = string1 + string2
// welcome now equals "hello there"

또한 += 연산자를 사용하여 기존의 문자열 변수에 문자열 값을 추가할 수도 있습니다.

var instruction = "look over"
instruction += string2
// instruction now equals "look over there"

문자 값을 추가하려면 문자열 타입의 append() 메소드를 사용하여 추가할 수 있습니다.

let exclamationMark: Character = "!"
welcome.append(exclamationMark)
// welcome now equals "hello there!"

 

여러 줄 문자열을 사용하는 경우에는 모든 줄이 줄바꿈으로 끝나야 합니다.

let badStart = """
one
two
"""
let end = """
three
"""
print(badStart + end)
// Prints two lines:
// one
// twothree

let goodStart = """
one
two

"""
print(goodStart + end)
// Prints three lines:
// one
// two
// three

위 코드에서 badStart와 end를 연결하면 두 줄의 문자열이 생성되는데, 이는 의도한 결과가 아닙니다. goodStart의 경우에는 마지막 줄이 줄바꿈으로 끝났기 때문에 end와 결합하면 의도한 결과가 출력됩니다.


Single Interpolation

String interpolation은 문자열 리터럴 내에 상수,변수,리터럴,표현식이 혼합되어 새 문자열 값을 구성하는 방법입니다. 문자열 리터럴에 삽입되는 각 항목은 괄호로 감싸고 앞에 백슬래시를 붙여서 삽입할 수 있습니다.

let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
// message is "3 times 2.5 is 7.5"

 

extended delimiters를 사용하여 string interpolation 효과를 적용하지 않을 수 있습니다.

print(#"Write an interpolated string in Swift using \(multiplier)."#)
// Prints "Write an interpolated string in Swift using \(multiplier)."

위에서 설명한 extended delimiter과 동일하게, 효과를 유지하고 싶다면 백슬래시 뒤에 숫자 기호(#)을 추가해주면 됩니다.

print(#"6 times 7 is \#(6 * 7)."#)
// Prints "6 times 7 is 42."

Unicode

유니코드는 서로 다른 문자 시스템에서 텍스트를 인코딩하고 표현하고 처리하기 위한 국제 표준입니다. Swift의 문자열 및 문자 타입은 유니코드를 지원합니다.

Unicode Scalar Values

Swift의 native String type은 유니코드 스칼라 값으로 구성되어 있습니다. 유니코드 스칼라 값은 문자 또는 modifieer를 위한 고유한 21비트 숫자입니다. 예를 들어, U+0061은 'a'(LATIN SMALL LETTER A)이고, U+1F425는 FRONT-FACING BABY CHICK ("🐥") 입니다.

일부 21비트 유니코드 스칼라 값은 나중에 할당되거나 UTF-16 인코딩에서 사용하기 위해서 reserved 되어 있습니다. 일반적으로 문자로 할당된 스칼라 값은 LATIN SMALL LETTER A이나 FRONT-FACING BABY CHICK과 같은 이름을 가지고 있습니다.

Extended Grapheme Clusters

Swift 문자 타입의 모든 인스턴스는 하나의 extended grapheme cluster를 나타냅니다. Extended grapheme cluster는 하나 이상의 유니코드 스칼라로 구성된 시퀀스이며, 결합 시 사람이 읽을 수 있는 단일 문자를 생성합니다. 다시 말하면, 문자소를 나타내는 하나 이상의 유니코드 스칼라를 결합하여 하나의 문자를 생성합니다.

문자 é는 단일 유니코드 스칼라 LATIN SMALL LETTER E WITH ACUTE(U+00E9)로 나타낼 수 있습니다. 그러나 표준 문자 e(LATIN SMALL LETTER E, or U+0065)와 COMBINING ACUTE ACCENT(U+0301) 스칼라의 쌍으로 표현될 수도 있습니다. COMBINING ACUTE ACCENT는 e앞에 위치해서 e를 é로 변환시킵니다.

아래의 두 변수는 모두 동일한 문자를 표현합니다.

let eAcute: Character = "\u{E9}"                         // é
let combinedEAcute: Character = "\u{65}\u{301}"          // e followed by ́
// eAcute is é, combinedEAcute is é

이는 많은 복잡한 스크립트 문자를 단일 문자 값으로 표현할 수 있는 방법입니다. 한글로 예를 들면, 하나의 음절은 자음 모음으로 분해되어 순서대로 나타낼 수 있습니다. 

let precomposed: Character = "\u{D55C}"                  // 한
let decomposed: Character = "\u{1112}\u{1161}\u{11AB}"   // ᄒ, ᅡ, ᆫ
// precomposed is 한, decomposed is 한

 

COMBINING ENCLOSING (U+20DD)와 같은 enclosing mark를 사용하여 다른 유니코드 스칼라를 단일 문자 값의 일부로 사용될 수 있습니다.

let enclosedEAcute: Character = "\u{E9}\u{20DD}"
// enclosedEAcute is é⃝

지역을 표시하는 기호의 유니코드 스칼라를 쌍으로 결합하여 단일 문자 값을 만들 수도 있습니다.

let regionalIndicatorForUS: Character = "\u{1F1FA}\u{1F1F8}"
// regionalIndicatorForUS is 🇺🇸

Counting Characters

count 속성을 사용하여 문자열에서 문자값의 개수를 확인할 수 있습니다.

let unusualMenagerie = "Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪"
print("unusualMenagerie has \(unusualMenagerie.count) characters")
// Prints "unusualMenagerie has 40 characters"

 

extended grapheme clusters로 결합되거나 수정된 문자가 있는 경우, 문자 개수에 항상 영향을 미치지는 않습니다.

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"

위 코드에서 COMBINING ACUTE ACCENT 유니코드 스칼라 문자를 word 변수에 추가했지만, 문자의 개수는 그대로 4개인 것을 볼 수 있습니다.

extended grapheme cluster는 여러 유니코드 스칼라로 구성될 수 있습니다. 이는 같은 다른 문자(+ 같은 문자의 다른 표현)라면 저장하기 위한 메모리 양이 다릅니다. 이 때문에 스위프트의 문자들은 각 문자열에서 같은 크기의 메모리를 차지하지 않습니다. 따라서 extended grapheme cluster의 경계를 결정하지 않고 문자의 개수를 계산할 수 없습니다.

Accessing and Modifying a String

문자열 타입의 메소드나 속성 또는 subscript 문법을 사용하여 액세스하고 수정할 수 있습니다.

String Indices

각 문자열 값은 String.Index와 같은 연관된 인덱스 타입을 가지고 있습니다. 이들은 문자열에서 각 문자의 위치에 대응됩니다. Swift에서 서로 다른 문자는 저장하기 위해 서로 다른 크기의 메모리가 필요하므로, 어떤 문자가 특정 위치에 있는지 확인하려면 해당 문자열의 시작이나 끝부터 반복을 통해 확인해야합니다. 결과적으로 Swift 문자열을 정수 값으로 인덱싱할 수 없습니다.

startIndex 속성을 사용하면 문자열의 첫 번째 문자 위치에 액세스할 수 있습니다. endIndex 속성은 문자열의 마지막 문자 바로 뒤의 위치입니다. 따라서 endIndex 속성은 문자열의 유효한 subscript 인수가 아닙니다. 문자열이 비어있다면 startIndex와 endIndex는 동일합니다.

 

지정된 인덱스 앞이나 뒤를 인덱싱하려면 index(before:)과 index(after:) 메소드를 사용하면 됩니다. 주어진 인덱스에서 멀리 떨어진 인덱스에 액세스하려면 index(_:offsetBy:) 메소드를 사용하면 됩니다.

let greeting = "Guten Tag!"
greeting[greeting.startIndex]
// G
greeting[greeting.index(before: greeting.endIndex)]
// !
greeting[greeting.index(after: greeting.startIndex)]
// u
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index]
// a

 

문자열 범위를 벗어난 인덱스나 그 문자를 액세스하려고 하면 런타임 에러가 발생합니다.

greeting[greeting.endIndex] // Error
greeting.index(after: greeting.endIndex) // Error

indices 속성을 사용하여 문자열 내 모든 문자의 인덱스에 액세스할 수 있습니다.

for index in greeting.indices {
    print("\(greeting[index]) ", terminator: "")
}
// Prints "G u t e n   T a g ! "
startIndex, endIndex 속성과 index(before:), index(after:), index(_:offsetBy:) 메소드는 Collection 프로토콜을 따르는 모든 타입에서 사용할 수 있습니다. 이 프로토콜을 따르는 타입은 문자열뿐만 아니라 배열, 딕셔너리, 셋(Set)이 있습니다. 프로토콜에 관해서는 나중에 알아볼 예정입니다.

Inserting and Removing

지정된 인덱스에 하나의 문자를 삽입하려면 insert(_:at:) 메소드를 사용하면 되고, 지정된 인덱스에 다른 문자열의 내용을 삽입하려면 insert(contentsOf:at:) 메소드를 사용하면 됩니다.

var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)
// welcome now equals "hello!"

welcome.insert(contentsOf: " there", at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there!"

 

지정된 인덱스의 문자를 제거하려면 remove(at:) 메소드를 사용하고, 지정된 범위에서 substring을 제거하려면 removeSubrange(_:) 메소드를 사용합니다.

welcome.remove(at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there"

let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
welcome.removeSubrange(range)
// welcome now equals "hello"
insert(_at:), insert(contentsOf:at:), remove(at:), removeSubrange(_:) 메소드는 RangeReplaceableCollection 프로토콜을 따르는 모든 타입에서 사용할 수 있습니다. 이 타입에는 문자열뿐만 아니라 배열, 딕셔너리, 셋과 같은 Collection 타입이 포함됩니다.

Substrings

문자열에서 subscript나 prefix(_:)와 같은 메소드로 substring을 가져오는 경우, 그 결과는 다른 문자열이 아닌 Substring의 인스턴스입니다. Swift의 Substring은 대부분 문자열과 동일한 메소드를 사용하기 때문에 String 타입과 동일한 방식으로 Substring을 사용할 수 있습니다. 그러나 문자열과 달리 substring은 문자열에 대한 작업을 수행하는 동안(단시간)만 사용합니다. 만약 substring을 오랜기간 사용한다면 문자열 인스턴스로 바꿔서 사용하는 것이 좋습니다.

let greeting = "Hello, world!"
let index = greeting.firstIndex(of: ",") ?? greeting.endIndex
let beginning = greeting[..<index]
// beginning is "Hello"

// Convert the result to a String for long-term storage.
let newString = String(beginning)

단시간이 아닌 오랜시간 사용되는 substring을 String 인스턴스로 변환하여 사용되어야 하는 이유는 메모리 관리 때문입니다. 위 예제 코드에서 greeting은 문자열 타입이고, 구성하는 문자들을 저장하는 메모리 공간이 있습니다. beginning은 greeting의 substring이며, begging은 greeting이 사용하는 메모리를 재사용합니다. 반면, newString은 substring으로부터 생성된 새로운 문자열이고, 자체 메모리 공간을 가지게 됩니다.

만약 substring에서 인덱스로 접근하여 문자값을 변경하려고 하면, 아래처럼 에러가 발생합니다. Substring에서 subscript는 only-get에만 사용될 수 있습니다.

String과 Substring은 StringProtocol 프로토콜을 따릅니다.

Comparing Strings

Swift에서는 텍스트 값을 비교할 수 있는 3가지 방법을 지원합니다.

(string and character equality, prefix equality, suffix equality)

String and Character Equality

문자열과 문자 비교에는 동등(equal to)연산자 '=='과 부등(not equal to)연산자 '!='를 사용합니다.

let quotation = "We're a lot alike, you and I."
let sameQuotation = "We're a lot alike, you and I."
if quotation == sameQuotation {
    print("These two strings are considered equal")
}
// Prints "These two strings are considered equal"

만약 extended grapheme cluster가 동일한 경우, 두 문자열이나 문자는 동일한 것으로 간주됩니다. 비록 extended grapheme cluster가 서로 다른 유니코드 스칼라로 구성되어 있더라도 언어적 의미와 외형이 같다면 동일하다고 간주합니다.

 

예를 들어, LATIN SMALL LETTER E WITH ACUTE(U+00E9)는 COMBINING ACUTE ACCENT(U+0301)+LATIN SMALL LETTER E(U+0065)와 동일합니다.

// "Voulez-vous un café?" using LATIN SMALL LETTER E WITH ACUTE
let eAcuteQuestion = "Voulez-vous un caf\u{E9}?"

// "Voulez-vous un café?" using LATIN SMALL LETTER E and COMBINING ACUTE ACCENT
let combinedEAcuteQuestion = "Voulez-vous un caf\u{65}\u{301}?"

if eAcuteQuestion == combinedEAcuteQuestion {
    print("These two strings are considered equal")
}
// Prints "These two strings are considered equal"

 

반대로, 영어에서 사용되는 LATIN CAPITAL LETTER A(U+0041, "A")는 러시아어에서 사용되는 CYRILLIC CAPITAL LETTER A(U+0401, "A")는 동일하지 않습니다. 두 문자는 외형은 동일하지만 언어적 의미가 다르기 때문입니다.

let latinCapitalLetterA: Character = "\u{41}"

let cyrillicCapitalLetterA: Character = "\u{0410}"

if latinCapitalLetterA != cyrillicCapitalLetterA {
    print("These two characters aren't equivalent.")
}
// Prints "These two characters aren't equivalent."

 

Prefix and Suffix Equality

문자열에 특정 접두사나 접미사가 있는지 확인하려면 String의 hasPrefix(_:), hasSuffix(_:) 메소드를 사용하면 됩니다. 두 메소드는 모두 문자열 타입의 인수를 사용하고 Boolean 값을 반환합니다.

다음은 두 메소드를 사용하는 예제 코드입니다.

let romeoAndJuliet = [
    "Act 1 Scene 1: Verona, A public place",
    "Act 1 Scene 2: Capulet's mansion",
    "Act 1 Scene 3: A room in Capulet's mansion",
    "Act 1 Scene 4: A street outside Capulet's mansion",
    "Act 1 Scene 5: The Great Hall in Capulet's mansion",
    "Act 2 Scene 1: Outside Capulet's mansion",
    "Act 2 Scene 2: Capulet's orchard",
    "Act 2 Scene 3: Outside Friar Lawrence's cell",
    "Act 2 Scene 4: A street in Verona",
    "Act 2 Scene 5: Capulet's mansion",
    "Act 2 Scene 6: Friar Lawrence's cell"
]

var act1SceneCount = 0
for scene in romeoAndJuliet {
    if scene.hasPrefix("Act 1 ") {
        act1SceneCount += 1
    }
}
print("There are \(act1SceneCount) scenes in Act 1")
// Prints "There are 5 scenes in Act 1"

var mansionCount = 0
var cellCount = 0
for scene in romeoAndJuliet {
    if scene.hasSuffix("Capulet's mansion") {
        mansionCount += 1
    } else if scene.hasSuffix("Friar Lawrence's cell") {
        cellCount += 1
    }
}
print("\(mansionCount) mansion scenes; \(cellCount) cell scenes")
// Prints "6 mansion scenes; 2 cell scenes"

Unicode Representations of Strings

유니코드 문자열이 텍스트 파일이나 다른 저장소에 저장되면 그 문자열의 유니코드 스칼라는 다양한 인코딩 형식 중의 하나로 인코딩됩니다. 각 형식은 code unit인 작은 chunk로 문자열을 인코딩합니다. 이 형식에는 UTF-8 인코딩, UTF-16 인코딩, UTF-32 인코딩 형식이 있습니다.

for-in 구문을 사용하여 각 문자 값에 액세스할 수 있는데, 각 형식으로 어떻게 액세스할 수 있는지 알아보겠습니다.

다음의 변수를 통해 각 형식으로 변환되는 방법을 보여줍니다.

let dogString = "Dog‼🐶"

UTF-8 Representation

utf8 속성을 사용하여 UTF-8 표현에 액세스할 수 있습니다. 이 속성의 타입은 String.UTF8View이며 unsigned 8-bit(UInt8) 값들의 collection입니다.

for codeUnit in dogString.utf8 {
    print("\(codeUnit) ", terminator: "")
}
print("")
// Prints "68 111 103 226 128 188 240 159 144 182 "

위 예제 코드에서 문자 D, o, g의 UTF-8 변환 값은 아스키와 같습니다. 다음 3개의 10진수 codeUnit 값 (226, 128, 188)은 DOUBLE EXCLAMATION MARK 문자를 표현합니다. 마지막 4개의 codeUnit 값 (240, 159, 144, 182)는 DOG FACE 문자를 표현합니다.

 

UTF-16 Representation

utf16 속성을 사용하면 UTF-16 표현에 액세스할 수 있습니다. 이 속성은 String.UTF16View 타입이며 UInt16 값들의 collection 입니다.

for codeUnit in dogString.utf16 {
    print("\(codeUnit) ", terminator: "")
}
print("")
// Prints "68 111 103 8252 55357 56374 "

 

Unicode Scalar Representation

unicodeScalars 속성을 사용하여 Unicode scalar 표현으로 액세스할 수 있습니다. 이 속성은 UnicodeScalarView 타입이며 UnicodeScalar 타입 값들의 collection입니다. 각 UnicodeScalar는 value 속성을 가지고 있는데, 이 속성은 21-bit 값은 반환하고 UInt32 값으로 표현됩니다.

for scalar in dogString.unicodeScalars {
    print("\(scalar.value) ", terminator: "")
}
print("")
// Prints "68 111 103 8252 128054 "

 

각 UnicodeScalar 값은 새로운 문자열 값을 구성하는데 사용될 수도 있습니다.

for scalar in dogString.unicodeScalars {
    print("\(scalar) ")
}
// D
// o
// g
// ‼
// 🐶

 

'프로그래밍 > Swift' 카테고리의 다른 글

[Swift] Functions (함수)  (0) 2021.12.18
[Swift] Control Flow (제어문)  (0) 2021.12.16
[Swift] Collection Type (Array, Set, Dictionary)  (0) 2021.12.15
[Swift] Basic Operators  (0) 2021.12.12
[Swift] Basic 문법  (0) 2021.12.12

댓글