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이 메모리에 남아 있어야 하기 때문이다.
참고 : 컴파일 시점에 그 크기를 명확히 알기 어려운 String 또는 Collection 타입들은 Value Type이지만 Heap 영역에 값을 저장할 수 있다
ㄴ 출처
- https://bit.ly/3sXSx6x
- https://medium.com/@jungkim/스위프트-타입별-메모리-분석-실험-4d89e1436fee
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 값들의 컬렉션
- 특징
- 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
- 특징
- Unicode Scalar Representation : 문자열을 21 bit 유니코드 스칼라 값으로 인코딩
- 특징
- 고정 길이 인코딩 방식
- 모든 문자를 4바이트로 인코딩
- 장점
- 모든 문자를 동일한 크기로 표현하므로, 인덱싱과 같은 작업에서 단순하고 빠름
- 단점
- 메모리 사용 비효율
- Swift
- string의 unicdeScalars 프로퍼티 ( UnicodeScalarView 타입)
- UInt32 값들의 컬렉션
- 특징
'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 |