아리의 iOS 탐구생활

Swift의 String index는 왜 정수가 아니지? 왜 구하기 어려울까? 본문

Swift/문제해결

Swift의 String index는 왜 정수가 아니지? 왜 구하기 어려울까?

Ari Lee 2021. 9. 13. 14:42
반응형
 

Strings and Characters — The Swift Programming Language (Swift 5.5)

Strings and Characters A string is a series of characters, such as "hello, world" or "albatross". Swift strings are represented by the String type. The contents of a String can be accessed in various ways, including as a collection of Character values. Swi

docs.swift.org

 

Strings and Characters — The Swift Programming Language (Swift 5.5)

Strings and Characters A string is a series of characters, such as "hello, world" or "albatross". Swift strings are represented by the String type. The contents of a String can be accessed in various ways, including as a collection of Character values. Swi

docs.swift.org

String index를 공부하다가 왜 index를 정수로 구하는 것이 까다로운지 찾아보았다. 공식문서에는 “유니코드의 독립적인 형태로 문자열을 처리하기 때문에” 라고 기재가 되어있는데, 유니코드의 독립적인 형태라는 것이 정확하게 어떤 뜻인지 이해가 잘 가지 않았다.

 

그래서 찾아보았는데 Swift의 문자열은 유니코드에 준수하여 표기되기 때문이다. 유니코드로 표현한 문자는 크기가 일정하지 않다.

 

유니코드 부분에서 위 사진처럼 문자는 분명 ‘1개’지만 어떤 문자이냐에 따라 먹는 바이트 갯수가 틀리기 때문에, 즉 ‘가변적’이기 때문에 인덱스 조회하는 것이 어렵다고 이해가 되었다.

 

유니코드는 특정 문자 인코딩 방식을 뜻하는 것이 아니라 여러 인코딩 방식의 묶음 이라고 이해하는 것이 맞는 것 같다.

 

유니코드 스칼라(Unicode Scalars)

Swift의 네이티브 문자열 타입은 유니코드 스칼라 값에서 만들어진다. 유니코드 스칼라는 21bit 이다.

그리고 이런 유니코드 스칼라를 조합하여 하나의 문자를 만들어 낼 수도 있다.

예를 들어 두 개의 유니코드 스칼라를 조합하면 하나의 문자가 되는 경우도 존재하다.

아래는 공식 문서의 한 예제이다.

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 한

let str = "\u{1112}\u{1161}\u{11AB}국"
let str2 = "한국"

 

위 처럼 여러개의 유니코드 스칼라를 조합하게 되면 서로 다른 유니코드 스칼라이지만 하나의 문자로 표현될 수 있다.

 

이렇게 각기 다른 유니코드 스칼라는 서로 다른 메모리 크기를 필요로 하기 때문에 특정 문자가 어떤 위치에 있는지 알기 위해서는 문자열의 처음부터 끝까지 유니코드 스칼라를 체크해야 한다. 그렇기 때문에 Swift에서는 정수 값으로 인덱스에 접근이 불가능하다.

 

 

 

 

그렇다면 다른 언어, 유니코드를 사용하는 다른 언어(golang, javascript, java)에서는 문자열 인덱스를 정수로 받아내고 있는데 스위프트는 이러한 기능을 개선 하지못했는지 알아보았다

 

 

Get nth character of a string in Swift programming language

How can I get the nth character of a string? I tried bracket([]) accessor with no luck. var string = "Hello, world!" var firstChar = string[0] // Throws error ERROR: 'subscript' is unavailable:

stackoverflow.com

위 링크에서는 하위호환성 문제 때문에 개선하지 못했다고 이야기를 하는거 같다. 아래 답글을 보면 사용자가 직접 extension을 통해 구현하는 법을 추천한다고 되어있다.

 

 

이 궁금증에 대한 더 깊은 이해를 하려면 유니코드와 아스키코드에 대해서 공부해보아야 할 것 같다.

반응형
Comments