달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

이전 포스트에 이어서, 작성되는 포스트이다.

 

 

1. Swift String에서의 Unicode

: é문자를 통해, Swift String에서 주의할 점들을 설명하고자 한다. é는 e에 acute accent를 붙인 것인데, 이를 표현하는 방법은 한가지 이상이다. 한 문자를 표현하는 방법이 한가지 이상이면, 비교는 어떻게 할 수 있을까? 표현하는 방법마다 문자의 크기는 같을까? 아래의 코드를 보고 하나씩 알아보자.

 

1
2
3
4
5
6
7
8
9
10
11
let firstString = "\u{00E9}lite"
print("1) output: \(firstString)") // => élite
print("1) count: \(firstString.count)") // => 5
print("1) utf16.count: \(firstString.utf16.count)") // => 5
        
let secondString = "e\u{0301}lite"
print("2) output: \(secondString)") // => élite
print("2) count: \(secondString.count)") // => 5
print("2) utf16.count: \(secondString.utf16.count)") // => 6
 
print("isSame: \(firstString == secondString)") // => true
cs

 

 firstString과 secondString은 lite를 제외한, 나머지 부분이 다르다. 그런데 출력시켜 보면, 둘 다 élite가 출력된다. count도 동일하다. 두 String을 비교한 결과는 true다. 하지만, code unit을 16bits로 하고 count를 보면 firstString과 secondString이 다르다.

 

 firstString과 secondString의 *.utf16.count는 다른데, 어째서 비교한 결과는 같은 것일까? Swift Language Guide에서 이유가 설명되어 있었다(링크).

 

 "Two String values (or two Character values) are considered equal if their extended grapheme clusters are canonically equivalent. Extended grapheme clusters are canonically equivalent if they have the same linguistic meaning and appearance, even if they’re composed from different Unicode scalars behind the scenes."

 

 대략 다음과 같이 해석할 수 있다.

 

 "Swift에서 두 String을 비교할 때 두 String의 Extended Grapheme Clusters가 canonically equivalent하면, 두 String은 equal하다. Extended Grapheme Clusters는 언어학적으로(linguistic) 의미와 형태가 같으면, Canonically Equivalent하다."

 

 Swift Language Guide에 나와있듯이, firstString과 secondString은 다른 Unicode Scalar들로 이루어져 있더라도 언어학적으로 의미와 형태가 같아서 비교한 결과가 True인 것이다.

 

 

 

2. NSString에서의 String 처리

: NSString은 조금 동작이 다르다. 확인을 위해 다음과 같은 코드를 작성했다.

 

1
2
3
4
5
6
7
8
let typecastedFirstString = firstString as NSString
print("1) count: \(typecastedFirstString.length)") // => 5
         
let typecastedSecondString = secondString as NSString
print("2) count: \(typecastedSecondString.length)") // => 6
        
let isSameTypecastedStrings = typecastedFirstString == typecastedSecondString 
// => false
 
cs

 

 Swift Strig에서는 firstString과 secondString의 count는 같았는데, NSString으로 타입 캐스팅한 typecastedFirstString과 typecastedSecondString의 length는 왜 다른 것일까? NSString을 설명하는 Apple 문서에 이유가 설명되어 있었다(링크).

 

 "An NSString object encodes a Unicode-compliant text string, represented as a sequence of UTF-16 code units. All lengths, character indexes, and ranges are expressed in terms of 16-bit platform-endian values, with index values starting at 0."

 

 음... 그러니까 NSString은 UTF-16로 Text를 인코딩한다. NSString의 length와 index, range도 16bit로 인코딩한 값에 따라 계산이 된다.

 

 NSString을 비교하는 'isEqual(to aString: String) -> Bool' 메서드에 대한 설명에서도, 두 String의 Unicode가 동일한지를 비교한다고 설명되어 있다(링크).

 

 

 

3. 마무리 및 참고자료

: 이번 글에서는 String을 비교할 때 주의할 점과, Swift String과 NSString이 어떻게 다른지를 설명했다. 글 중간중간에 삽입한 링크들을 정리하는 것을 끝으로, 이번 글을 마무리하겠다.

 

- Swift 문서의 String Compare

https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html#ID298

 

- NSString

https://developer.apple.com/documentation/foundation/nsstring

 

- NSString의 isEqual(to aString: String) -> Bool 메서드

https://developer.apple.com/documentation/foundation/nsstring/1407803-isequal

:
Posted by syjdev