Swifter {Swift Developer}

메뉴

문자열 사용하기

프로그래밍을 한다면 아마도 문자열이 가장 많이 사용되는 데이터형중 하나라고 생각된다. 이번에 큰 마음을 먹고 Swift 언어의 문자열을 좀 자세히 다루어 보려고 한다. 다만 The Swift Programming Language를 읽어본 분이라면 아시겠지만 이를 유념하고 시작해 보자.

Swift ‘s String and Character types provide a fast, Unicode-compliant way to work with text in your code

“스위프트의 String과 Character형은 고속으로 유니코드 호환 텍스트 처리를 제공한다.” 여기서 말하는 고속은 유니코드를 준수한다는 것이 생각보다 개발자에게는 곤혹스러운 일이기도 하다.  이유를 알기 위해서는 컴퓨터가 나오면서 문자열 처리의 역사를 이해하고 있지 않으면 안된다.

문자의 역사

문자열 == 문자의 열. 이라고 얼마전까지 문자열이라는 것을 이해하기 위해 아래 표를 참고하자.

  • 1963 EBCDIC (최초의 문자코드 규격)
  • 1963 ASCII (대중적인 문자코드 규격)
  • 1974 KS X 1001 (첫번째 한국어 문자코드, KS C 5601)
  • 1985 EUC-KR (8비트 한글 완성형 인코딩으로 완성형이라고 불림)
  • 1991 Unicode 1.0 (사실상 현재 문자코드 표준)
  • 1992 UTF-8 (ASCII기반 유니코드 확장)
  • 1993 ISO-2022-KR
  • 1995 Java 1.0 (16bit Character)
  • 1995 JavaScript 1.0
  • 1996 Unicode 2.0 (써로게이트페어 표준화)
  • 2000 Python 2.0 (바이트!=문자열)
  • 2002 Perl 5.8 (유니코드를 언어로 완벽화게 지원)
  • 2007 Ruby 1.9
  • 2008 Python 3.0 (UCS2 사실상 폐지)
  • 2010 Unicode 6.0 (이모티콘 추가)
  • 2014 Swift 1.4 (1.0에서 유니코드 완벽지원)

0과 1의 두가지 숫자만 근원적으로 취급할 수 없는 전자계산기에서 문자를 취급함에 있어 연구자들이 한 것은 다음과 같다.

  • 각 문자에 번호 설정하기
  • 그 번호를 일렬로 정리

그 옛날 개발자들에게 다행하게도 대우를 받던 문자열은 영어였다. 그리고 사실 영어라는 것이 필요한 문자 종류가 제일 적은 언어였기 때문이기도 하다. 알파벳 26자, 대소문자 구별시 52문자, 아라비아 숫자를 포함해도 62문자, 그리고 공간이나 데이터관련 추가해서 7bits = 128종류로 구성되게 되었다. 이것이 현재에도 사용하고 있는 ASCII값이며 일반적으로 사용하는 CPU도 취급하는 가장 작은 데이터형이 1byte = 8bits에 그대로 넣어도 1비트가 많이 있다.

2바이트 문자의 탄생

문자는 1바이트에 들어가며 그것을 늘어 놓은 것이 문자열이다. 그런 시대가 오랫동안 지속되어 왔다. 그 원칙이 깨진 것은 사실 이웃나라 일본이었는데 일본어 문자가 48가지로 히라가나와 카타가나로 나뉘어져 8비트에 맞지 않고 수천가지의 한자도 사용해야 한다는 것이 이슈였다. 한 문장의 글자를 표현하는데 12~13비트가 필요하다. 또한 단순하게 늘여 놓은 것이 아니라 ASCII와의 공존도 고려하면서 하나의 문자를 표기하는데 필요한 2바이트로 인해 EUC-JP, EUC-KR등이 나오게 된다. 여기서 기억해야할 점은 각 문자에 표기된 번호는 단일 규격이지만 그것을 어떻게 나열할지에 대한 여러가지 규격이 난립하게 된다. 물론 각각의 장단점이 있는데, 사실 그 당시 인터넷도 활성화된 시기도 아니고 심지어 PC통신도 크게 사용하지 않았던 시절이었고 데이터 호환성조차도 각각의 업체끼리 자사의 제품에만 집중하던 시절이었다.

유니코드의 탄생

그런 상황에서 인터넷이 보급됨에 따라 상황은 급변하게 된다. 컴퓨터를 로컬에서만 사용되면서 다른 컴퓨터의 사용끼리 연결하는 것이 일반적이었다. 그런 시대에 각각의 규격을 사용하였다. 난립된 문자코드에서 전세계 공통의 문자코드로 전환하자는 의견들이 많아지면서 나온 것이 바로 유니코드이다.

처음 등장한 단계에서는 유니코드는 과거의 호환성은 거의 고려하지 않았다. EUC-KR과 같은 ASCII호환 한국어 문자코드가 가변길이인 반면 1.0버전에서는 16비트 고정길로 한국어 및 한자모두 포함할 예저잉었다. 이를 위해 각국에서 사용되는 문자코드를 한번에 할당하지 않고 정렬해야 했다.

유니코드의 우울함

유니코드 진영도 1.0을 제정할 당시 처음부터 문자열을 다시 정의하는 방식이 그대로 잘 되지 않는다는 것을 발견한다. 우선 같은 문자에 같은 번호라는 원칙이 깨졌다. 유니코드 컨소시엄은 그때까지의 문자코드에서 유니코드로 변환한 뒤에 역변환이 제대로 성립할 것을 요구했기 때문이다. 다음은 16비트로는 상당히 부족하다는 걸 알게 된다. 이를 해결하기 위해 써로게이트 페어라는 것이 나오게 된다. 16비트에서 1개의 문자에서 문자에 따라 16비트 2개로 하나의 문자로 표현하기로 한다. 이렇게 원칙이 무너지면서 그 대가로 유니코드는 최대 (16+1)*2**16 == 1,114,112자까지 취급할 수 있게 되었다. 그리고 ASCII호환도 UTF-8으로 해결하였다. 1문자의 길이는 1~4바이트 가변되는 대신 ASCII는 지금까지 1바이트로 사용된다. ASCII를 전제로 하던 다양한 소프트웨어들, 특히 개발자 입장에서 많이 사용하던 C컴파일러에서도 그대로 취급했다. 이것이 우리들에게는 우울함을 주게 되는데 유니코드 2.0이 나오기 전까지 인터넷이 확산되면서 Java, JavaScript등이 1문자 16비트로 되어버려 지금까지 이어져 왔다.

문자코드의 통일

써로게이트 페어(Surrogate pairs)와 UTF-8와 같이 어느정도 희생함에 따라 유니코드로 바꾸는 것이 가치가 있는 일인지 의문이 생길 수 있지만, 오래전에 필자도 잠시 사용했던 Perl 5.8의 유니코드화와 같이, 운영체제 및 개발언어 및 소프트웨어 모두 단일화된 문자코드는 가치가 있다고 판단한다. 그리고 최근에 가장 많이 사용하는 아이폰과 안드로이드에 와서는 유니코드를 기본으로 사용하게 되었다. 또한 인터넷의 보급으로 인해 TCP/IP 이외의 통신프로토콜은 사실상 사라졌지만 이를 통해 획일화되었다고 보지는 않는다.

스위프트 언어의 문자열

서론이 길었지만 스위프트의 문자를 실제로 살펴보자. 다음은 간단하게 플레이그라운드 또는 REPL에서 실행해보자.

  • 형 선언은 필요없다. 리터럴에서 알맞게 추론한다.
  • 형이름은 String이다. Xcode의 경우 식별자를 [Option] + 클릭하면 확인할 수 있다.
  • 문자열 리터럴은 ” ~ “로 둘러싸임
  • \( )에서 변수 열기 (interpolation)
  • 식별자에 ASCII가 아닌 유니코드 사용

이 정도의 리소스는 이미 10년전부터 실현되었고 스위프트가 이를 적용하고 있는 것이 대단하다.

 s1 == s2가 참이면 s1 == s3도 참이 되는가?

문자가 무엇인지? 동일한 캐릭터란 무엇인지? 문자열을 문자로 처리하는 방법을 알아보자.

스위프트의 문자 = Character는 1바이트가 아니고 1코드 포인트조차도 1grapheme이다. grapheme이란 말은 macOS에 따르면 서기소(자소)라는 말로 문자의 최소 결합단위라고 한다. 문자열 비교는  grapheme로 하라고 하는 것은 확실히 유니코드 콘소시엄 문서에도 나오는 내용으로 이를 제대로 구현한 언어는 필자가 아는 기준으로는 스위프트밖에 없다. 이것은 1.0버전부터 유니코드 이념을 실현하기 위한 모습으로 보여진다.

유니코드의 깔끔함?

스위프트 2.2부터는 유니코드 서브스크립트를 볼 수 있다. EC5이후 자바스크립에서는 아래와 같은 형태로 문자열을 문자배열로 간주하고 문자를 검색할 수 있지만 스위프트에서는 오류로 인식하기 위해 다음과 같이 사용할 수 있다.

 

사실 스위프트에서는 작은 따옴표(‘~’)가 사용되지 않는 것이 이슈였는데 이는 스위프트의 현재 문자열 처리에 대한 시행착오가 있다고 본다. 사실 스위프트의 문자열 처리는 C/C++/Objective-C언어보다 더 좋지만 Ruby, Javascript에 비해서는 한참 떨어진다. 이는 모바일 앱 개발을 고려하여 Objective-C언어만 사용할 수 밖에 없었던 시절에 비하면 천국이다. 그렇지만 최근 오픈소스화가 되면서 서버사이드에서도 사용됨에 따라 문자열처리가 약해질 것 같다는 생각이 든다. 반대로는 더 다양한 라이브러리들이 나올 것으로 예상된다.

Facebook Comments

카테고리:   Swift 3.0

댓글

죄송하지만 댓글은 닫혀 있습니다.