본문 바로가기

iOS/Swift

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

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

 

Documentation

 

docs.swift.org

 

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


 

String Indices

문자열의 인덱스와 String.Index 타입

  • String에는 각 Character의 위치를 나타내는 String.Index 타입이 있다.
  • Swift 문자열은 정수 값으로 직접 인덱싱할 수 없다.
    • 문자들이 차지하는 메모리 크기가 다를 수 있기 때문에, 특정 위치의 문자를 찾기 위해서는 문자열의 시작 또는 끝에서 부터 유니코드 스칼라를 하나씩 탐색해야 한다.

 

startIndex와 endIndex

  • startIndex : 문자열의 첫 번째 문자의 위치
  • endIndex : 문자열의 마지막 문자 바로 다음 위치
    • subscript시에 valid 하지 않은 범위임에 유의
    • 빈 문자열이면 startIndex와 endIndex 같음

 

인덱스 접근 및 subscript

  • index(before:) : 주어진 인덱스의 뒤를 접근
  • index(after:) :  주어진 인덱스의 앞에 접근
  • index(_:offsetBy:) : 주어진 인덱스에서 떨어진 위치 
  • subscript : 특정 String.Index에 위치한 문자에 접근
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

  • 컬렉션에서 subscript를 사용해 접근할 수 있는 모든 유효한 인덱스들을 오름차순으로 반환
  • 이 indicies는 Collection을 채택한 타입들에서 사용할 수 있음
  • 다만 여기 Discussion을 보면 indices와 Collection이 강한 참조를 가질 수 있다고 하니, 유의하여 사용하는게 좋을 듯
for index in greeting.indices {
    print("\(greeting[index]) ", terminator: "")
}

 

Inserting and Removing

삽입

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

 

삭제

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"

 

Substrings

  • String과 동일하게 StringProtocol 을 준수
    • 문자열 조작 메서드들이 StringProtocol을 받고는 한다.
  • String의 문자열 중 일부를 추출할 때 반환되는 결과는 String이 아닌 Substring 인스턴스이다.
  • String과 거의 유사하게 다룰 수 있지만 단기적인 사용 목적으로 설계되었다.
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과 동일하게 Character들이 저장된 메모리 영역을 갖는다.
  • 성능 최적화를 위해 원본 String에 사용된 메모리의 일부를 재사용하거나 다른 Substring에 사용된 메모리의 일부를 재사용할 수 있다.
    • String 또는 Substring이 수정하기 전까지 메모리를 복사하는데 드는 성능 비용을 지불하지 않아도 된다.
    • 단기적인 사용 목적인 이유는 Substring이 남아있는 한 원본 String이 메모리에 남아 있어야 하기 때문이다.

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

 

 

참고 : 컴파일 시점에 그 크기를 명확히 알기 어려운 String 또는 Collection 타입들은 Value Type이지만 Heap 영역에 값을 저장할 수 있다

ㄴ 출처

Comparing Strings

String & Character Equality

  • 비교 연산자(==, !=)를 통해 비교 가능
  • Extended graphme Cluster가 동일한 언어적 의미와 외형을 갖는 경우 갖다고 판단
  • Swift에서 문자열 비교는 지역/언어 설정에 따라 달라지지 않는다.
// "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"

 

Prefix and Suffix Equality

  • hasPrefix(_:)
  • hasSuffix(_:)

 

Unicode Representations of Strings

유니코드 문자열이 텍스트 파일이나 저장소에 기록될 때, 유니코드 스칼라는 여러 유니코드 인코딩 방식 중 하나로 인코딩 된다.

let dogString = "Dog‼🐶"

print("UTF-8 Code Units:")
for codeUnit in dogString.utf8 {
    print(codeUnit, terminator: " ")
}

//68 111 103 226 128 188 240 159 144 182


print("\n\nUTF-16 Code Units:")
for codeUnit in dogString.utf16 {
    print(codeUnit, terminator: " ")
}

// 68 111 103 8252 55357 56374


print("\n\nUnicode Scalars:")
for scalar in dogString.unicodeScalars {
    print(scalar.value, terminator: " ")
}
// 68 111 103 8252 128054
  • UTF-8 : 문자열을 8 bit 코드 유닛으로 인코딩
    • 특징 
      • 가변 길이 인코딩 방식
      • 각 문자를 1바이트에서 4바이트 사이의 가변 길이로 인코딩
    • 장점
      • ASCII 문자와 호환
      • 메모리 사용 효율 높음
    • 단점
      • 복잡한 문자나 이모지 표현시 3~4 바이트를 사용하므로 처리 속도가 좀 더 느릴 수 있음
    • Swift
      • string의 utf8 프로퍼티 (String.UTF8View 타입)
      • UTF-8 표현을 나타내는 UInt8 값들의 컬렉션

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/stringsandcharacters/#UTF-8-Representation

  • UTF-16 : 문자열을 16 bit 코드 유닛으로 인코딩
    • 특징 
      • 가변 길이 인코딩 방식
      • 대부분의 문자들은 2바이트로 인코딩. 일부 복잡한 문자는 4바이트(surrogate pair)로 인코딩
    • 장점
      • 대부분의 문자들을 2바이트로 표현할 수 있어, 다양한 언어에 대한 균형 잡힌 크기와 처리 속도 제공
    • 단점
      • ASCII와 호환되지 않음
      • surrogate pair를 처리하는 추가 로직이 필요
    • Swift
      • string의 utf16 프로퍼티 (String.UTF16View 타입)
      • UTF-16 표현을 나타내는 UInt16 값 들의 컬렉션
      • DOG FACE 문자는 surrogate 페어로 표현됨
        • high-surrogate value : U+D83D > 55357
        • low-surrogate value : U+DC36 > 56374

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/stringsandcharacters/#UTF-16-Representation

  • Unicode Scalar Representation : 문자열을 21 bit 유니코드 스칼라 값으로 인코딩
    • 특징
      • 고정 길이 인코딩 방식
      • 모든 문자를 4바이트로 인코딩
    • 장점 
      • 모든 문자를 동일한 크기로 표현하므로, 인덱싱과 같은 작업에서 단순하고 빠름
    • 단점
      • 메모리 사용 비효율
    • Swift
      • string의 unicdeScalars 프로퍼티 ( UnicodeScalarView 타입)
      • UInt32 값들의 컬렉션

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/stringsandcharacters/#Unicode-Scalar-Representation

 

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

Swift - Strideable Protocol  (0) 2024.09.19
Swift 공식문서 4. Collection Types  (0) 2024.09.08
Swift API Design Guidelines  (0) 2024.08.29
Swift 공식 문서 3. Strings and Characters (1)  (0) 2024.08.29
Swift 공식 문서 2. Basic Operator  (0) 2024.08.28