๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

study iOS๐ŸŽ/์ฃผ์ ‘ Swift - swift ํ…Œ๋งˆ

[Too Swift] ์‹œ์ฆŒ1 2ํ™” How Swift deals with Strings ์Šค์œ„ํ”„ํŠธ๊ฐ€ ์ŠคํŠธ๋ง์„ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ• : ๋„ˆ๋ฌด ์ค‘์š”ํ•œ ์ž๋ฃŒํ˜• !!

1. [ A String as a collection of a Grapheme cluster or clusters ] : ์Šค์œ„ํ”„ํŠธ์—๊ฒŒ ์ŠคํŠธ๋ง์€ ๊ทธ๋ž˜ํ•Œ ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ปฌ๋ ‰์…˜์ด๋‹ค. 

 

unicode์˜ ์บ๋ฆญํ„ฐ ์…‹์„ ๊ธฐ๋ฐ˜์œผ๋กœํ•œ ์Šค์œ„ํ”„ํŠธ์˜ ์ŠคํŠธ๋ง์€, codePoints๋“ค์ด ๋“ค์–ด์™”์„ ๋•Œ, ๊ทธ๊ฒƒ์ด ํ•˜๋‚˜์˜ ์กฐํ•ฉ์ด ๋  ์ˆ˜ ์žˆ์œผ๋ฉด, ๊ทธ๊ฒƒ์„ Grapheme cluster๋ผ๊ณ  ๋ณด๊ณ , ๊ทธ๊ฒƒ์„ ํ•˜๋‚˜์˜ "char"๋ผ๊ณ  ๋ด…๋‹ˆ๋‹ค.

 

let cafeNormal = "café"
let cafeCombined = "cafe\u{0301}" 

// \u0000001100000001 => hexacoded unicode code point

 

 

 

์˜ˆ๋ฅผ ๋“ค์–ด, ์œ„์—์„œ ์ฒซ ๋ฒˆ์งธ ์ƒ์ˆ˜์˜ ๋‘ ๋ฒˆ์งธ ์ƒ์ˆ˜ ์œ ๋‹ˆ์ฝ”๋“œ ์ƒ ์ฝ”๋“œ ํฌ์ธํŠธ ๊ฐฏ์ˆ˜๋Š” 4๊ฐœ์™€ 5๊ฐœ๋กœ ์ƒ์ดํ•˜๋‚˜, ์Šค์œ„ํ”„ํŠธ๋Š” ์˜์–ด ์•ŒํŒŒ๋ฒณ e์™€ ๋ฐœ์Œ๊ธฐํ˜ธ๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ๋ฌถ์–ด ํ•˜๋‚˜์˜ ์บ๋ฆญํ„ฐ๋กœ ๋ด…๋‹ˆ๋‹ค.

// ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์—
cafeNormal.unicodeScalars.count // 4
cafeCombining.unicodeScalars.count // 5

cafeNormal.count // 4
cafeCombining.count // 4

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œํฌ์ธํŠธ๋Š” ์„œ๋กœ ๋‹ฌ๋ผ๋„, char์— ๋Œ€ํ•œ ์นด์šดํŠธ๋Š” ์„œ๋กœ ๊ฐ™๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 

 

2. [ Indexed String ] ์ŠคํŠธ๋ง ์ž๋ฃŒํ˜•์„ ์ธ๋ฑ์‹ฑํ•˜๊ธฐ -> ์ŠคํŠธ๋ง[3] ์ด๊ฑฐ ์•ˆ๋จ ...

  ์œ„์—์„œ ๋ดค๋“ฏ์ด, ๋‘ ๊ฐœ์˜ ์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ๋ฌถ์—ฌ์„œ ํ•˜๋‚˜์˜ ์บ๋ฆญํ„ฐ๊ฐ€ ๋˜๊ธฐ๋„ ํ•˜๋Š” ๊ฒƒ์„ ๋ณด์‹œ์—ˆ๋‹ค ์‹œํ”ผ, ์ŠคํŠธ๋ง ๋ฐ์ดํ„ฐ ํƒ€์žŽ์— ๋Œ€ํ•œ ์ธ๋ฑ์‹ฑ์€

์•„๋ฌด๋ฆฌ ์ปฌ๋ ‰์…˜์ด์–ด๋„ [2], [1]๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ๋  ์ˆ˜ ์žˆ์–ด, ๋ฉ”๋ชจ๋ฆฌ ์–ด๋“œ๋ ˆ์Šค ๋‘ ๊ฐœ๊ฐ€ ๋ฌถ์—ฌ ํ•˜๋‚˜์˜ ์บ๋ฆญํ„ฐ๋ฅผ ๋‚˜ํƒ€๋‚ผ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ์ ์–ด๋„ ์Šค์œ„ํ”„ํŠธ์—์„œ๋Š” ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ, ์šฐ๋ฆฌ๋Š” ๋ฐฐ์›Œ์•ผํ•  ๋ฟ์ž…๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ ์ŠคํŠธ๋ง ์ž๋ฃŒํ˜•์€ ์ธ๋ฑ์‹ฑ์„ ์–ด๋–ป๊ฒŒ ํ• ๊นŒ์š”?

 

๋นŒ๋“œ์—… 1๋‹จ๊ณ„. ์‹œ์ž‘ ์บ๋ฆญํ„ฐ์˜ ์ธ๋ฑ์Šค, ๋ ์บ๋ฆญํ„ฐ์˜ ์ธ๋ฑ์Šค

// 1). ์šฐ์„  ์บ๋ฆญํ„ฐ ์ปฌ๋ ‰์…˜์ธ ์ŠคํŠธ๋ง์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ์˜ ์ธ๋ฑ์Šค๋ฅผ ๊ตฌํ•ด๋ด…์‹œ๋‹ค.

let firstIndex = cafeCombining.startIndex // ์ฒซ ์บ๋ฆญํ„ฐ์˜ ์ธ๋ฑ์Šค

// 2). ์ด๋ ‡๊ฒŒ ์Šค์œ„ํ”„ํŠธ๊ฐ€ ๊ตฌํ•ด๋†“์€ ์ธ๋ฑ์Šค๋ฅผ ์ธ๋ฑ์‹ฑ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

cafeCombining[firstIndex] // String์˜ ์ฒซ ๋ฒˆ์งธ "์บ๋ฆญํ„ฐ" ์ž…๋‹ˆ๋‹ค.

// 3). ๊ทธ๋ ‡๋‹ค๋ฉด ๋งˆ์ง€๋ง‰ ์บ๋ฆญํ„ฐ์˜ ์ธ๋ฑ์Šค๋Š”? ๊ทธ๊ฒƒ๋„ ์Šค์œ„ํ”„ํŠธ๊ฐ€ ์ฃผ๋Š” ๊ฑธ๋กœ๋งŒ ํ•ด์š” !!

// *** warning : cafeCombining.endIndex๋Š” "1 char past the end of the string์ด๋ผ๊ณ  ํ•˜๋‹ˆ,
// .index(before: cafeCombining.endIndex) ์—”๋“œ ์ธ๋ฑ์Šค๊ฐ€ ๋ฆฌํ„ดํ•œ ์บ๋ฆญํ„ฐ์˜ ์ธ๋ฑ์Šค์˜ ํ•œ ์บ๋ฆญํ„ฐ ์ด์ „์˜
// ์ธ๋ฑ์Šค๋ฅผ ํ•ด์•ผ ์‹ค์งˆ์ ์œผ๋กœ ์ŠคํŠธ๋ง์˜ ๋งˆ์ง€๋ง‰ ์บ๋ฆญํ„ฐ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•˜๋„ค์š”."

let lastIndex = cafeCombining.index(before: cafeCombining.endIndex) // -> é

// 4). ๊ทธ๋Ÿผ ๋˜ ์ด๊ฑธ ์ด์šฉํ•ด์„œ ๋งˆ์ง€๋ง‰ ์บ๋ฆญํ„ฐ๋ฅผ ๊ตฌํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
cafeCombining[lastIndex]

์ƒ๊ฐ๋ณด๋‹ค ์“ธ ๊ฒŒ ๋งŽ์ฃ ?????????? ํ ...

 

๋นŒ๋“œ์—… 2๋‹จ๊ณ„. => .index( .startIndex, offsetBy: ~๋ฒˆ์งธ ๊ธ€์ž(Int) ) ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ

// ์ฒซ ๋ฒˆ์งธ ์บ๋ฆญํ„ฐ์˜ ์ธ๋ฑ์Šค๋กœ ๋ถ€ํ„ฐ => 3 ์บ๋ฆญํ„ฐ ๋–จ์–ด์ง„ ์บ๋ฆญํ„ฐ์˜ ์ธ๋ฑ์Šค
let fourthIndex = cafeCombining.index(cafeCombining.startIndex, offsetBy: 3)

// ์œ„์—์„œ .index(์ฒซ ์บ๋ฆญ ์ธ๋ฑ์Šค, ์˜คํ”„์…‹: ์บ๋ฆญํ„ฐ ์ˆ˜)๋กœ ํž˜๊ฒน๊ฒŒ ๊ตฌํ•œ ์ธ๋ฑ์Šค๋ฅผ [ ] <- ์„œ๋ธŒ์Šคํฌ๋ฆฝํŠธ์— ๋„ฃ์–ด์„œ
// ๋งˆ์นจ๋‚ด, ๋„ค ๋ฒˆ์งธ ์บ๋ฆญํ„ฐ๋ฅผ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.
let fourthChar = cafeCombining[fourthIndex] // -> é

 

์Šค์œ„ํ”„ํŠธ๋„ ํ• ๋ง์ด ์žˆ๋‹ค๋„ค์š”. "  ๋‚˜๋„ ํ•  ๋ง์€ ์žˆ์–ด, ์ด๋ ‡๊ฒŒ ๊ณ ์ƒํ•˜๋Š” ์ด์œ ๋Š” ๋ฐ”๋กœ ...  "

์ด๋ชจ์ง€ ๋”ฐ๋ด‰๋„ ์ปฌ๋Ÿฌ๋ฅผ ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆ ํ•ด์„œ => ํ•˜๋‚˜์˜ ๋ฌธ์ž๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ž ๋ Œ๋”๋ง์˜ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•๊ณผ ๋‹ค์–‘์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

 

์• ํ”Œ์Šค๋Ÿฝ๊ฒŒ๋„, ๊ทธ๋ž˜ํ•Œ ์กฐํ•ฉ์„ ์ฐพ์•„ ํ•œ ์บ๋ฆญํ„ฐ๋กœ ๋ฌถ์–ด์„œ ๋žœ๋”๋งํ•˜๋Š” ๊ฒƒ์€ ํ•œ ์บ๋ฆญํ„ฐ์˜ ๋‹ค์–‘์„ฑ๊ณผ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ๊ฐ€๋Šฅ์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ •๋ง, ์• ํ”Œ์ด ๋งŒ๋“  ์–ธ์–ด๋‹ต๋„ค์š” ...

 

3. [ String equality ] ์ŠคํŠธ๋ง์˜ ๋™๋“ฑ์„ฑ ๋น„๊ต

๊ทธ๋ ‡๋‹ค๋ฉด, ์Šค์œ„ํ”„ํŠธ ๋งŒ์˜ ์ŠคํŠธ๋ง์˜ ๋™๋“ฑ์„ฑ์„ ๋น„๊ตํ•˜๋Š” ๋ฐฉ์‹์€ ๋ฌด์—‡์ผ๊นŒ์š”?

 

์ฝ”๋“œ ํฌ์ธํŠธ๊ฐ€ ์™ผ์ชฝ์€ 1๊ฐœ์˜ ๋…๋ฆฝ๋œ ํฌ์ธํŠธ, ์˜ค๋ฅธ์ชฝ์€ 2๊ฐœ์˜ ํฌ์ธํŠธ => ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ๋ณผ๊นŒ์š”?

์•„๋‹™๋‹ˆ๋‹ค. ์Šค์œ„ํ”„ํŠธ์˜ ์ŠคํŠธ๋ง ๋™๋“ฑ์„ฑ ๋น„๊ต์˜ ์›์น™์€,

canonicalization์ž…๋‹ˆ๋‹ค. ์ ˆ๋Œ€ ๊ธฐ์ค€์œผ๋กœ ํ‰๊ฐ€? ์™€ ๋น„์Šทํ•œ ์˜๋ฏธ๋กœ ๋ณผ ์ˆ˜ ์žˆ์„์ง€ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ,

 

    1). ๊ฒฐ๊ตญ ๋…๋ฆฝ๋œ ์ฝ”๋“œํฌ์ธํŠธ๋ฅผ ์ชผ๊ฐœ์„œ ๋ถ„ํ•ด๋œ ๊ทธ๋ž˜ํ•Œ ์กฐํ•ฉ์œผ๋กœ ๋งตํ•‘ํ•˜๋˜์ง€,

    2). ๊ทธ๋ž˜ํ•Œ ์กฐํ•ฉ์„, ์กฐํ•ฉํ•˜์—ฌ ํ•˜๋‚˜์˜ ๋…๋ฆฝ๋œ ์ฝ”๋“œํฌ์ธํŠธ๋กœ ๋งตํ•‘ํ•˜๋˜์ง€,

 

  ๊ฒฐ๊ตญ์—” "ํ†ต์ผ๋œ" ๊ธฐ์ค€์œผ๋กœ ๋‘ ๊ฐœ์˜ ์ŠคํŠธ๋ง์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด, ์ฝ”๋“œ ํฌ์ธํŠธ ์กฐํ•ฉ์ด ์•„๋ฌด๋ฆฌ ๋‹ค์–‘ํ•  ์ˆ˜ ์žˆ์–ด๋„,

๊ฒฐ๊ตญ ์šฐ๋ฆฌ๊ฐ€ ๋ณผ ๋•Œ ๊ฐ™์€ ์บ๋ฆญํ„ฐ๋“ค์ด ๊ฐ™์€ ์ˆœ์„œ๋กœ ์žˆ๋‹ค๋ฉด( ์ด๊ฒŒ ๋” ์‹ค์šฉ์ ์ด์ฃ . ) ๊ฐ™์€ ์ŠคํŠธ๋ง์€ ๊ฒฐ๊ตญ ๊ฐ™์€ ์ŠคํŠธ๋ง์œผ๋กœ ํ‰๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. 

 

cafeCombining == cafeNormal -> true 

 

์ด๋ ‡๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด์ฃ . ์ด๊ฒŒ ์Šค์œ„ํ”„ํŠธ์˜ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. 

 

 

4. String as bi-directional collections ์–‘๋ฐฉํ–ฅ์„ฑ ์ปฌ๋ ‰์…˜์œผ๋กœ์„œ์˜ ์Šค์œ„ํ”„ํŠธ ์ŠคํŠธ๋ง

let name = "Matt"
let backwardsName = name.reversed( )

//
let secondCharIndex = backwardsName.index(backwardsName.startIndex, offsetBy: 1)
let secondChar = backwardsName[secondCharIndex]

//
let backwardNameString = String(backwardsName)

String => .reversed( )๋ฅผ ์ ์šฉํ•˜๋Š” ๊ฒƒ์€, char์˜ collection์ธ String์—, ๋งˆ์น˜ ๊ทธ๊ฒƒ์„ ๊ฑฐ๊พธ๋กœํ•œ ์ŠคํŠธ๋ง์œผ๋กœ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š”, a thin wrapper๋ฅผ ์”Œ์› ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ์ถ”๊ฐ€์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์“ฐ์ง€ ์•Š์œผ๋ฉด์„œ ๊ทธ๋ ‡๊ฒŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค !! ๊ทธ๋Ÿฌ๋ฉด 2๋ฒˆ์งธ ๋ธ”๋ก์—์„œ ๋ณด์‹ค ์ˆ˜ ์žˆ๋‹ค์‹œํ”ผ, ๊ฑฐ๊พธ๋กœ๋œ ์ŠคํŠธ๋ง์ธ ๊ฒƒ์ฒ˜๋Ÿผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ธ๋ฑ์‹ฑ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋žฉํ•‘๋œ ์ŠคํŠธ๋ง์„ ์ŠคํŠธ๋ง ๋ฐ์ดํ„ฐ ํƒ€์žŽ์œผ๋กœ ๋งŒ๋“ค์–ด๋ฒ„๋ฆฌ๋ ค๋ฉด => String( ) : ์ŠคํŠธ๋ง ํƒ€์žŽ ์ปจ๋ฒ„์ ผ์„ ์‚ฌ์šฉํ•˜๋ฉด๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ๋งŒ์•ฝ ๊ฑฐ๊พธ๋กœ๋œ ํ˜•ํƒœ์˜ ๋์—์„œ ์ฒซ ๊ธ€์ž์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ด์šฉํ•˜๋ ค๋ฉด, ๊ตณ์ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋‚ญ๋น„ํ•˜๋ฉด์„œ, ํƒ€์žŽ ์ปจ๋ฒ„์ ผ์„ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

 

 

5. Raw Strings ์ƒ์ŠคํŠธ๋ง

์Šค์œ„ํ”„ํŠธ์—์„œ ์ŠคํŠธ๋ง์€

 

    1. " " " " ๊ฐ€ ๋‚˜์˜ค๋ฉด, ๋’ท " "๋Š” ๋ญ๋ƒ๊ณ  ๋ฌผ์–ด๋ด…๋‹ˆ๋‹ค. ํ•œ ์ŠคํŠธ๋ง์€ " " ๋‹ˆ๊นŒ.

    2. \(  ) ๊ฐ€ ๋‚˜์˜ค๋ฉด ๋ณ€์ˆ˜๊ฐ€ ๋“ค์–ด๊ฐ€์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด์ƒํ•œ ๊ฒƒ์„ ๋„ฃ์œผ๋ฉด, ๋ญ๋ƒ๊ณ  ๋”ฐ์ง‘๋‹ˆ๋‹ค.

    3. \๊ฐ€ ๋‚˜์˜ค๋ฉด ์ด์Šค์ผ€์ดํ•‘ ๋ฌธ์ž๋กœ ์“ฐ์ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

๊ทผ๋ฐ ๋งŒ์•ฝ, ์ด๋Ÿฐ ๋ฃฐ์„ ํ”ผํ•˜๊ธฐ ๋‚œ์ฒ˜ํ•˜๋‹ค๋ฉด, ๊ทธ๋ƒฅ ๋ณด์ด๋Š” ๊ทธ๋Œ€๋กœ์˜ ์ŠคํŠธ๋ง์œผ๋กœ ๋งŒ๋“ค์–ด์คฌ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค๋ฉด,

 

#" ~ "# ์˜ ์‹ ํƒ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด, ์ŠคํŠธ๋ง์„ ๊ทธ๋ƒฅ ์ฃผ๋Š” ๊ทธ๋Œ€๋กœ, ๋ณด์ด๋Š” ๊ทธ๋Œ€๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๊ฒŒ๋ฉ๋‹ˆ๋‹ค. ํ”„๋ฆฐํŠธ๋„ ๊ทธ๋ž˜๋„ ๋‚˜์˜ค์ฃ .

+ ) ์Šค์œ„ํ”„ํŠธ ํŒ€์€, ์‚ฌ๋žŒ๋“ค์ด ์ƒ์ŠคํŠธ๋ง์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋งŒ์•ฝ, ๊ทธ์™€์ค‘์— interpolation์„ ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด,

์˜ˆ์™ธ๋ฅผ ๋‚จ๊ฒจ๋†“์•˜์Šต๋‹ˆ๋‹ค. 

\#( schoolName )   ์€ ๊ทธ๋ž˜๋„ ์—ฌ์ „ํžˆ, ์ธํ„ฐํด๋ ˆ์ด์…˜์œผ๋กœ ํ•ด์„๋ฉ๋‹ˆ๋‹ค.

 

ํœ˜๋ฌธ์ด๋ผ๋Š” ์ŠคํŠธ๋ง ๋ณ€์ˆ˜๊ฐ€  \ # ( )  ์— ๋„ฃ์œผ๋‹ˆ, ๊ฐ’์ด ์ŠคํŠธ๋ง์— ํ‘œ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

Substring ์„œ๋ธŒ ์ŠคํŠธ๋ง (type)

* ๋ถ€๋ชจ ์ŠคํŠธ๋ง ๋ฐ์ดํ„ฐ๋กœ๋ถ€ํ„ฐ, ์ผ์ • ๋ฒ”์œ„ ๋งŒํผ ์Šฌ๋ผ์ด์‹ฑํ•  ๋•Œ, ๊ทธ ๊ฒฐ๊ณผ๋กœ ์ƒ๊ธฐ๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ( ๋น„์Šทํ•œ ๊ธฐ๋Šฅ์ด์ง€๋งŒ, ๋ณ„๋„์˜ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ) ์ž๋™์œผ๋กœ ๋ณต์‚ฌ๋˜์–ด, ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋กœ ๋žจ์— ์ €์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. 

* ๋žจ์—์„œ ์ƒˆ๋กœ์šด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์•„๋‚„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๋‹ค์ˆ˜์˜ ์ ์šฉ๊ฐ€๋Šฅํ•œ ๋ฉ”์†Œ๋“œ๋Š” ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

* ๊ตณ์ด String( )์„ ํ†ตํ•ด ๊ฐ’์„ ์นดํ”ผํ•ด ์ƒˆ๋กœ์šด ์ŠคํŠธ๋ง์„ ๋งŒ๋“ค ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.

* ๋งŒ์•ฝ ์„œ๋ธŒ ์ŠคํŠธ๋ง์„ ์ด์šฉํ•ด, ํ•จ์ˆ˜ ๊ฐ’์„ ๋ฆฌํ„ดํ•˜๊ฑฐ๋‚˜, ์ŠคํŠธ๋ง์„ ๋ฐ›๋Š” ํ•จ์ˆ˜์— ์ธ์ž๋กœ ์ „๋‹ฌํ•  ์‹œ์—๋Š”, String( )์œผ๋กœ ํƒ€์žŽ ๋ณ€ํ™˜์„ ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

let fullName = "Han seokhee"
let spaceIndex = fullName.firstIndex(of: " ")! // String.Index? ์˜ต์…”๋„ ๋ฆฌํ„ด์ด๋ผ ์ด๋ ‡๊ฒŒ // Han seokhee
var firstName = fullName[ fullName.startIndex ..< spaceIndex ] // Han

// -> "Han" ( String.subsequence type )
// ๋ถ€๋ชจ ์ŠคํŠธ๋ง์ธ ํ’€ ๋„ค์ž„์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ๊ธฐ์ƒํ•˜์—ฌ ์–ด๋“œ๋ ˆ์‹ฑ๋งŒ ์ž˜ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—,
// ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์•„๋‚๋‹ˆ๋‹ค.

// < Range >
// ์„œ๋ธŒ์ŠคํŠธ๋ง : [ ์ธ๋ฑ์Šค ๋ ˆ์ธ์ง€ ]

// ๋ ˆ์ธ์ง€ ์ข…๋ฅ˜
// close-ended :  spaceIndex ..< secondSpaceIndex
// open-ended  :  spaceIndex ... : spaceIndex ~๋ถ€ํ„ฐ ๋๊ฐ€์ง€
//                fullNamep[ ..< spaceIndex ] : ์ฒ˜์Œ๋ถ€ํ„ฐ ~๊นŒ์ง€

// ์ŠคํŽ˜์ด์Šค ์ธ๋ฑ์Šค ๋‹ค์Œ ์ธ๋ฑ์Šค๋ถ€ํ„ฐ
// * ์ปฌ๋ ‰์…˜์˜ ๋๊นŒ์ง€
fullName[ fullName.index(after: spaceIndex)... ] // seokhee
fullName[ ...fullName.index(before: spaceIndex) ] // Han

String ์œผ๋กœ ๋ฐ”๊พธ์–ด์„œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด? casualํ•˜๊ฒŒ String( String.subsequence๊ฐ’ ) ์„ ์ด์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

String(firstName) // -> type : String
// copied -> new memory usage

์—ฐ์Šตํ•ด๋ณด์„ธ์š” !!

// Substring
let fullName3 = "sucky Han"
let target1Index = fullName3.firstIndex(of: " ")!
let target2Index = fullName3.index(after: target1Index)
let subString1 = fullName3[ ..<target2Index ]
let firstIndex = subString1.firstIndex(of: "s")!