์์ํ๋ฉฐ
swift ๊ณต๋ถ๋ฅผ ์์ํ์ง 3์ผ์ฐจ... ์์ฆ ๊ณต๋ถ๊ฐ ๋ธํ๋ค. ๋ด ์์คํ ์น๊ตฌ๊ฐ ํ๋๋๋ผ๋ก ๊ฐ์ง ์ผ์ฃผ์ผ์ด ์ง๋ฌ๋ค. ์ด์ ๋๋ ์ ์ ์ ์ฐจ๋ฆฌ๊ณ ๋ด ๋ฏธ๋๋ฅผ ์ํด, ์น๊ตฌ์ ์ฝ์ํ ๋๋ก ์ฑ๊ณต์ ์ธ 2022๋ ์ ์ํด ๊ณต๋ถ์ ์จ ์ ์ ์ ๋งค์งํด์ผ๊ฒ ๋ค. ์น๊ตฌ์ผ ํ๋์์๋ ๊ผญ ํ๋ณตํ๊ธธ. ์ฐ๋ฆฌ ์ด์ ์ํ๋ ๊ฒ์ ํ๊ณ ์ด์. ๊ทธ๋ฐ ์๋ฏธ๋ก ์ค์ํํธ ๊ณต์๋ฌธ์ 3ํ์ฐจ ์ ๋ฆฌ go
Swift ๊ณต์ Documents (3) strings and characters
Strings and Characters (๋ฌธ์์ด๊ณผ ๋ฌธ์)
String(๋ฌธ์์ด) ์ "Hello, World" ์ ๊ฐ์ ์ผ๋ จ์ character(๋ฌธ์)๋ค์ด ๋ฌถ์ฌ์ง ๊ฒ์ด๋ค. Swift์์ ๋ฌธ์์ ๋ฌธ์์ด์ ์ฝ๋์์ ํ ์คํธ ์ ๋์ฝ๋ ํธํ๋ฐฉ๋ฒ์ผ๋ก ์ ๊ณตํ๋ฉฐ, ๋ฌธ์์ด ๋ฐ ๋ฌธ์์ ์์ฑ ๋ฌธ๋ฒ์ C์ธ์ด์ ๋น์ทํ๋ค. ๋ฌธ์์ด ์ฐ๊ฒฐ์ + ์ฐ์ฐ์๋ก ๊ตฌํํ ์ ์๊ณ , ๋ค๋ฅธ ๋ณ์ ๋ฐ ์์์ฒ๋ผ ์ ์ธํ๊ณ ์ฌ์ฉํ๋ฉด ๋๋ค.
String Literals (๋ฌธ์์ด ๋ฆฌํฐ๋ด)
๊ฐ๋ฐ์๋ ์ฝ๋ ๋ด์ ๋ฏธ๋ฆฌ ์ ์ ๋ String ๊ฐ์ผ๋ก ๋ฌธ์์ด์ ์์ฑํ ์ ์๋ค. ๋ฌธ์์ด์ " " ์์ ์จ์ฃผ๋ฉด ๋๋ค.
let someString = "Some string literal value"
์ ์ฝ๋์ฒ๋ผ ์์๋ฅผ ์ ์ธํ๋ฉด, someString์ Swift๋ ๋ฌธ์์ด ๋ฆฌํฐ๋ด ๊ฐ์ผ๋ก ์ด๊ธฐํ ๋๋ค.
Multiline String Literals (์ฌ๋ฌ ์ค ๋ฌธ์์ด ๋ฆฌํฐ๋ด)
๋ง์ฝ ๋ฌธ์์ด์ ์ฌ๋ฌ ์ค์ ์ฐ๊ณ ์ถ๋ค๋ฉด """ ๋ฅผ ํ์ฉํด๋ผ.
let quotation = """
The White Rabbit put on his spectacles. "Where shall I begin,
please your Majesty?" he asked.
"Begin at the beginning," the King said gravely, "and go on
till you come to the end; then stop."
"""
โฒ ์์ฒ๋ผ ๋ฉํฐ ๋ผ์ธ ๋ฌธ์์ด ๋ฆฌํฐ๋ด์ ์์ํ๋ """์ ๋ง์ง๋ง์ """ ์ฌ์ด์ ๋ชจ๋ ์ค์ ํฌํจํ๋ค.
๋ฉํฐ๋ผ์ธ ๋ฌธ์์ด ๋ฆฌํฐ๋ด ๋ด๋ถ์ ์ค๋ฐ๊ฟ์ด ํฌํจ๋ ๊ฒฝ์ฐ, ํด๋น ์ค ๋ฐ๊ฟ์ ๋ฌธ์์ด์ ๊ฐ์๋ ์ ์ฉ๋๋ค. ์์ค์ฝ๋๋ฅผ ์ฝ๊ธฐ ์ฝ๊ฒ ํ๊ธฐ ์ํด ์ค๋ฐ๊ฟ์ ์ฌ์ฉํ๊ณ , ์ค์ ๋ก๋ ์ค๋ฐ๊ฟ์ ์ฌ์ฉํ์ง ์์ผ๋ ค๋ฉด ๋ฌธ์ ๋ค์ ๋ฐฑ์ฌ๋์ (\)๋ฅผ ์์ฑํ๋ฉด ๋๋ค. โผ
let softWrappedQuotation = """
The White Rabbit put on his spectacles. "Where shall I begin, \
please your Majesty?" he asked.
"Begin at the beginning," the King said gravely, "and go on \
till you come to the end; then stop."
"""
์ฌ๋ฌ ์ค์ ์ฌ์ฉํ ๋๋ ์๋์ฒ๋ผ ์ฒซ์ค๊ณผ ๋ง์ง๋ง ์ค์ ๋น์๋๊ณ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. (๊ทธ๋ฅ ํต์์ ์ธ ์์?์ธ๋ฏ?)
let lineBreaks = """
This string starts with a line break.
It also ends with a line break.
"""
๋ฉํฐ๋ผ์ธ ๋ฌธ์์ด ๋ฆฌํฐ๋ด์์ ์์ ๊ณต๋ฐฑ์ ์ฒซ์ค์ด ์์ํ ๋์ ๊ณต๋ฐฑ๋งํผ์ ๋ฌด์๋์ง๋ง, ๊ทธ ์ดํ์ ์ค์์๋ ์ฒซ์ค ๊ณต๋ฐฑ๋งํผ์ ๋ฌด์๋๊ณ , ์์ ๋์์ง ๋ค๋ฅธ ๊ณต๋ฐฑ์ ๋ฌด์๋์ง ์๋๋ค. ์๋์ ์ฌ์ง์ ๋ณด๋ฉด ๋ฌด์จ ๋ง์ธ์ง ์ดํด๊ฐ ๋ ๊ฒ์ด๋ค.
Special Characters in String Literals (๋ฌธ์์ด ๋ฆฌํฐ๋ด ๋ด์ ํน์ ๋ฌธ์)
๋ฌธ์์ด ๋ฆฌํฐ๋ด์ ์๋์ ๊ฐ์ ํน์๋ฌธ์๋ฅผ ํฌํจํ ์ ์๋ค.
- \0 : null character
- \\ : back slash ๋ฐฑ์ฌ๋์ฌ๋ ์ด๋ ๊ฒ ํํํ ์ ์๋ค.
- \t : ํญ ํค ํ ๋ฒ ๋๋ฅธ ๊ฒ
- \n : ์ค๋ฐ๊ฟ
- \r : carriage return์ผ๋ก ์ปค์์ ์์น๋ฅผ ์ค์ ๋งจ ์ฒ์์ผ๋ก ๋ณด๋ด ์ค
- \" : ๋ฌธ์์ด์์ ํฐ ๋ฐ์ดํ
- \' : ๋ฌธ์์ด์์ ์์ ๋ฐ์ดํ
- \u(n) : ๋ฌธ์์ด์์ ์ ๋์ฝ๋๋ฅผ ์ค๊ณ ์ถ์ ๋ (n์๋ 1-8์๋ฆฌ์ 16์ง์๋ฅผ ์จ์ฃผ๋ฉด ๋จ)
let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"
// "Imagination is more important than knowledge" - Einstein
let dollarSign = "\u{24}" // $, Unicode scalar U+0024
let blackHeart = "\u{2665}" // ♥, Unicode scalar U+2665
let sparklingHeart = "\u{1F496}" // ๐, Unicode scalar U+1F496
๋ง์ฝ ๋ฉํฐ ๋ผ์ธ ๋ฌธ์์ด ๋ฆฌํฐ๋ด ๋ด๋ถ์์ ๋ฐ์ดํ๋ฅผ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด ๊ทธ๋ฅ ์จ๋ ๋๋ค.(", "") ํ์ง๋ง ๋ฉํฐ๋ผ์ธ ๋ฌธ์์ด ๋ฆฌํฐ๋ด์ (""")๋ฅผ ์ฌ์ฉํ๋ฏ๋ก, ๋ง์ฝ ๋ฌธ์์ด ๋ด๋ถ์ """ ๋ฅผ ํฌํจํ๊ณ ์ถ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ฐฑ์ฌ๋์ฌ์ ํจ๊ป ์ฌ์ฉํ๋ฉด ๋๋ค.
let threeDoubleQuotationMarks = """
Escaping the first quotation mark \"""
Escaping all three quotation marks \"\"\"
"""
Extended String Delimiters (ํ์ฅ ๋ฌธ์์ด ๊ตฌ๋ถ ๊ธฐํธ)
์๊น์ ๊ฐ์ด ํน์๋ฌธ์๋ฅผ ์ฐ๋ ๊ฒ์ด ๊ท์ฐฎ๊ฑฐ๋ \n ๊ณผ ๊ฐ์ ๋ฌธ์๋ฅผ ์ฐ๊ณ ์ถ๋ค๋ฉด # ์์ ๋ฌธ์์ด์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค. ๊ทธ๋ฌ๋ฉด ๊ทธ๋ฅ ๊ทธ ๋ฌธ์์ด ๊ทธ๋๋ก๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ๊ทผ๋ฐ ๋ง์ฝ #๋ฅผ ์ฐ๊ณ ๊ทธ ์์ \n๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ์ฐ๊ณ ์ถ๋ค๋ฉด #๊ฐ์์ ๊ฐ์ ์์ #๋ฅผ \n์ ์จ์ฃผ๋ฉด ๋๋๋ฐ ์๋ ์์๋ฅผ ํตํด ์ดํดํด๋ณด์.
let threeMoreDoubleQuotationMarks = #"""
Here are three more double quotes: """
"""#
Initializing an Empty String (๋น ๋ฌธ์์ด ์ด๊ธฐํ)
๊ธด ๋ฌธ์์ด์ ์์ฑํ๊ธฐ ์ํ ์์์ ์ผ๋ก ๋น ๋ฌธ์์ด ๊ฐ์ ๋ง๋๋ ค๋ฉด ๋ณ์์ ๋น ๋ฌธ์์ด ๋ฆฌํฐ๋ด์ ํ ๋นํ๊ฑฐ๋ Initializing ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ์ ๋ฌธ์์ด ์ธ์คํด์ค๋ฅผ ์ด๊ธฐํ ํ ์ ์๋ค.
์ฆ, ๋น ๋ฌธ์์ด์ ๋ง๋๋๋ฐ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋๋ฐ ์๋์ ๊ฐ์ด ์ธ ์ ์๋ค.
var emptyString = "" // empty string literal
var anotherEmptyString = String() // initializer syntax
// these two strings are both empty, and are equivalent to each other
๋ํ ์ด๋ ๊ฒ ์ ์ํ๋ฉด , String ๊ฐ์ isEmpty ๋ผ๋ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๋๋ฐ, ์ด๊ฒ์ if๋ฌธ์ ํ์ฉํ์ฌ ํ์ธํด๋ณผ ์ ์๋ค. (์๋)
if emptyString.isEmpty {
print("Nothing to see here")
}
// Prints "Nothing to see here"
String Mutability (๋ฌธ์์ด ๋ณํ์ฑ)
๊ฐ๋ฐ์๊ฐ String '๋ณ์'๋ก ์ ์ธํ์๋ค๋ฉด ๋ฌธ์์ด์ ๋ณํํ ์ ์๊ณ , ์์๋ก ์ ์ธํ์๋ค๋ฉด ๋ณํ ํ ์ ์๋ค.
var variableString = "Horse"
variableString += " and carriage"
// variableString is now "Horse and carriage"
let constantString = "Highlander"
constantString += " and another Highlander"
// this reports a compile-time error - a constant string cannot be modified
Strings Are Value Types
swift์ String ํ์ ์ Value , ์ฆ ๊ฐ ํ์ ์ด๋ค. ๊ฐ๋ฐ์๊ฐ ์๋ก์ด string๊ฐ์ ๋ง๋ค์ด ๋ด๋ฉด ๊ทธ ๊ฐ์ด ํจ์๋ ๋งค์๋์์ ์ฌ์ฉ๋ ๋ ๋ณต์ฌ๋์ด ์ฌ์ฉ๋๋ค. ์ฆ ๊ธฐ์กด์ ๋ค๋ฅธ ๊ฐ๋ค๊ณผ๋ ๋ค๋ฅด๊ฒ ์์ ์๋ก์ด ๊ฐ์ด ์์ฑ๋๋ค๊ณ ์๊ฐํ์. ๋ฌผ๋ก ๋ณต์ฌ๋ฅผ ํ๊ธฐ ๋๋ฌธ์ ๋ด์ฉ์ ๊ฐ๋ค.
Working with Characters
String์์ charcacter๋ ํ ๊ธ์์ฉ์ ์๋ฏธํ๋ค. ๋ฐ๋ผ์ ์๋ for-in ๊ตฌ๋ฌธ์ ํ์ฉํ์ฌ ํ ๊ธ์์ฉ ์ถ์ถํ ์ ์๋ค.
for character in "Dog!๐ถ" {
print(character)
}
// D
// o
// g
// !
// ๐ถ
๋ง์ฝ ํ char๋ง ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด ์๋์ ๊ฐ์ด ์ ์ธํ ์ ์๋ค.
let exclamationMark: Character = "!"
print(exclamationMark)
// !
์๋์ ๊ฐ์ด String ๊ฐ์ character์ ๋ฐฐ์ด๋ก๋ ๋ง๋ค ์ ์๋ค.
let catCharacters: [Character] = ["C", "a", "t", "!", "๐ฑ"]
let catString = String(catCharacters)
print(catString)
// Prints "Cat!๐ฑ"
Concatenating Strings and Characters (๋ฌธ์์ฐ๊ฒฐ๊ณผ ๋ฌธ์)
string์ ๋ํ๊ธฐ ์ฐ์ฐ์ (+)๋ฅผ ํ์ฉํ์ฌ ์๋ก์ด ๋ฌธ์์ด์ ๋ง๋ค ์ ์๋ค. (concat)
let string1 = "hello"
let string2 = " there"
var welcome = string1 + string2
// welcome now equals "hello there"
๋ํ๊ธฐ ์ฐ์ฐ์ ๋ฟ๋ง ์๋๋ผ += ์ฐ์ฐ์๋ ์ฌ์ฉํ ์ ์๋ค.
var instruction = "look over"
instruction += string2
// instruction now equals "look over there"
Character๊ฐ์ String์ ์ถ๊ฐํ๊ณ ์ถ์ ๋ String ํ์ ๊ฐ์ append() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์. (Character๋ ํ ๊ธ์๋ง ์กด์ฌํ๋ '๋ฌธ์'์ด๋ฏ๋ก, character๋ณ์์๋ appendํ ์ ์๋ค๋ ๊ฒ์ ๋น์ฐํ๋ค!)
let exclamationMark: Character = "!"
welcome.append(exclamationMark)
// welcome now equals "hello there!"
๋ง์ฝ ๋ฉํฐ ๋ผ์ธ ๋ฌธ์์ด ๋ฆฌํฐ๋ด์ ์ฌ์ฉํ ๋์๋ ๋ง์ง๋ง ์ค์์ ๊ฐํ์ด ์ผ์ด๋์ง ์๊ธฐ ๋๋ฌธ์ ์๋์ ๊ฐ์ด ํด์ค์ผ ์ํ๋ ๋ฌธ์์ด์ ํฉ์น ์ ์์ ๊ฒ์ด๋ค.
let badStart = """
one
two
"""
let end = """
three
"""
print(badStart + end)
// Prints two lines:
// one
// twothree
let goodStart = """
one
two
"""
print(goodStart + end)
// Prints three lines:
// one
// two
// three
String Interpolation (๋ฌธ์์ด ๋ณด๊ฐ)
๋ฌธ์์ด ๋ณด๊ฐ์ String์ ์์, ๋ณ์ , ๋ฆฌํฐ๋ด, ์ฐ์ฐ ๋ฑ์ ๊ฐ์ ๋ฃ๋ ๊ฒ์ ๋งํ๋ค. ๋ฌธ์์ด ๋ณด๊ฐ์ ์ฌ์ฉํ ๋์๋ \()๋ฅผ ๋ฌธ์์ด์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค. ์๋ ์์๋ฅผ ๋ด๋ผ.
let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
// message is "3 times 2.5 is 7.5"
์ด๋ฌํ ๋ฌธ์์ด ๋ณด๊ฐ๋ ์์์ ๋ฐฐ์ด ๊ฒ๊ณผ ๊ฐ์ด #์ ์ฐ๋ฉด ๋ฌดํจํ ๋๋ค. #๋ฅผ ๋ฌธ์ ์์ ๋ถ์ด๋ฉด ์ฌ์ฉํ ์๋ ์๊ธด ํ๋ค.
print(#"Write an interpolated string in Swift using \(multiplier)."#)
// Prints "Write an interpolated string in Swift using \(multiplier)."
print(#"6 times 7 is \#(6 * 7)."#)
// Prints "6 times 7 is 42."
Unicode (์ ๋์ฝ๋)
์ ๋์ฝ๋๋ ํ ์คํธ๋ฅผ ์ธ์ฝ๋ฉ, ํํํ๊ธฐ ์ํ ๊ตญ์ ํ์ค์ด๋ค. ์ด๋ ํ ๋ฌธ์์ ์ธ์ด๋ ํ์คํ๋ ํ์์ผ๋ก ํํํ ์ ์์ผ๋ฉฐ ์ธ๋ถ ์์ค๋ ์น์์๋ ์ฝ๊ณ ์ธ ์ ์๋ค. Swift์ String, Characterํ์ ๋ ์ ๋์ฝ๋ ํ์์ ์ฌ์ฉํ๋ค.
Unicode Scalar Values
swift์ native Stringํ์ ์ ์ ๋์ฝ๋ ์ค์นผ๋ผ ๊ฐ์ผ๋ก ๊ตฌ์ฑ๋๋ค. ์ ๋์ฝ๋ ์ค์นผ๋ผ ๊ฐ์ ๊ณ ์ ํ 21๋นํธ ์์ด๋ค. ๋ชจ๋ 21๋นํธ ์ ๋์ฝ๋ ์ค์นผ๋ผ ๊ฐ์ด ๋ฌธ์์ ํ ๋น๋๋ ๊ฒ์ ์๋๊ณ ํฅํ ์ถ๊ฐ๊ฐ ๋๊ฑฐ๋ UTF-16์ธ์ฝ๋ฉ์ ์ฌ์ฉ๋๋๋ก ์์ฝ๋์ด ์๋ค. ๊ฐ๋จํ๊ฒ ์๋ฅผ ๋ค์ด ๋ณด๋ฉด, U+0061dms ("a") ๋ํ๋ด๋ฉฐ, U+1F425๋ ("๐ฅ")๋ฅผ ๋ํ๋ธ๋ค.
Extended Grapheme Clusters
Swift์ Characterํ์ ์ ํ๋์ graphemeํด๋ฌ์คํฐ๋ฅผ ๋ํ๋ธ๋ค. ํ์ฅ๋ Grapheme Cluster๋ ์ ๋์ฝ๋ ์ค์นผ๋ผ ์ํ์ค๋ก ์ฌ๋์ด ์ฝ์ ์ ์๋ ๋ฌธ์๋ฅผ ์์ฑํ๋ค. (์๋ ์ฝ๋์ ๋ํด์ ์ ๋์ฝ๋๊ฐ ์ด๋ป๊ฒ ํ์ฑ๋๊ณ ์ด๋ป๊ฒ ๋ณํ๋๋์ง? ์์ธํ๊ฒ ์ค๋ช ๋์ด ์๋๋ฐ ์์ธํ ์ค๋ช ์ ์๋ตํ๊ณ ์ฝ๋๋ง ์ฒจ๋ถํด ๋์)
let eAcute: Character = "\u{E9}" // é
let combinedEAcute: Character = "\u{65}\u{301}" // e followed by ฬ
// eAcute is é, combinedEAcute is eฬ
ํ๊ธ์ ์ด๋ป๊ฒ ํํ๋ ๊น?
"ํ"์ด๋ผ๋ ๊ธ์๋ก ์๋ฅผ ๋ค๋ฉด "ํ"์ด๋ผ๊ณ ํํํ ์๋ ์๊ณ "ใ
" + "ใ
" + "ใด" ์ผ๋ก๋ ํํํ ์ ์๋ค. (๊ณต์๋ฌธ์์ ์ด๋ ๊ฒ ํ๊ธ์ด ์ค๋ช
๋์ด ์์ผ๋๊น ๋ญ๊ฐ ๋ฟ๋ฏํ๊ณ ์ ๊ธฐํ๋ค ํํํ)
let precomposed: Character = "\u{D55C}" // ํ
let decomposed: Character = "\u{1112}\u{1161}\u{11AB}" // แ, แ
ก, แซ
// precomposed is ํ, decomposed is แแ
กแซ
์ฆ, Extended Grapheme Clusters๋ฅผ ์ฌ์ฉํ๋ฉด ๋จ์ผ ์ค์นผ๋ผ์ ๋ค๋ฅธ ์ค์นผ๋ผ ๊ฐ์ ๋ฌถ์ด์ ๋ณด์ฌ์ค ์ ์๋ค.
Counting Characters (๋ฌธ์์ด ๊ธธ์ด count)
String์ Count๋ผ๋ ํ๋กํผํฐ๋ฅผ ํ์ฉํ์ฌ ํด๋น String์ด ํฌํจํ๋ ๋ฌธ์์ ์(string์ ๊ธธ์ด) ๋ฅผ ๋ํ๋ผ ์ ์๋ค.
let unusualMenagerie = "Koala ๐จ, Snail ๐, Penguin ๐ง, Dromedary ๐ช"
print("unusualMenagerie has \(unusualMenagerie.count) characters")
// Prints "unusualMenagerie has 40 characters"
์๊น ๋ณธ Extended grapheme clusters์์ é๋ ๋๊ฐ์ ์ค์นผ๋ผ๋ก ์ด๋ฃจ์ด ์ก๋ค๊ณ ํ๋๋ฐ ์ด๋ฐ ๋ฌธ์๊ฐ ํฌํจ๋ String์ count ํ๋กํผํฐ์ ๊ฐ์ ์ผ๋ง์ผ๊น?
var word = "cafe"
print("the number of characters in \(word) is \(word.count)")
// Prints "the number of characters in cafe is 4"
word += "\u{301}" // COMBINING ACUTE ACCENT, U+0301
print("the number of characters in \(word) is \(word.count)")
// Prints "the number of characters in cafeฬ is 4"
์ ๋์ฝ๋๋ก ์ฐ์ฌ์ง string๋ ์๊ธฐ ์ฝ๊ฒ ์ถ๋ ฅ๋ ๋ฌธ์์ ๊ธธ์ด๋ฅผ ์ถ๋ ฅํด์ค๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์์ ๋ณผ ์ ์๋ฏ์ด ๋ฌธ์๋ค์ด ๋ค๋ฅธ ์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฐ์ง ์๋ ์๋ค๋ ๊ฒ์ด๋ค. ์ฆ, count ํ๋กํผํฐ์ ์ํด ๋ฐํ๋๋ ๋ฌธ์์๋ NSString์ length ํ๋กํผํฐ์๋ ๋์ผํ์ง ์์ ์ ์๋ค๋ ๊ฒ์ด๋ค. NSString ์ lengthํ๋กํผํฐ๋ UTF-16 ํํ ๋ด 16๋นํธ ์ฝ๋ ๋จ์ ์๋ก ๋ฌธ์์ ์๋ฅผ ์ผ๋ค.
Accessing and Modifying a String (๋ฌธ์์ด ์ ๊ทผ ๋ฐ ์์ )
String์ ๋ฉ์๋์ ํ๋กํผํฐ๋ฅผ ํ์ฉํ์ฌ ๋ฌธ์์ด์ ์ ๊ทผํ๊ณ ์์ ํ ์ ์๋ค.
String Indices (๋ฌธ์์ด ์ธ๋ฑ์ค)
stringํ์ ์ indexํ์ ์ด๋ค. String.index ํ๋กํผํฐ๋ฅผ ํ์ฉํ์ฌ ํด๋น ์์น์ ์๋ character์ ์ ๊ทผํ ์ ์๋ค. ๊ทธ๋ฐ๋ฐ ์์์ ๋ฐฐ์ ๋ฏ์ด, ๊ฐ๊ฐ์ ๋ฌธ์๊ฐ ๋ค๋ฅธ ์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฐ์ง ์ ์๊ธฐ ๋๋ฌธ์ swift๋ฌธ์์ด์ ์ ์ ๊ฐ์ผ๋ก Index๋ฅผ ์์ฑํ ์ ์๋ค.
์ฐ์ startIndex๋ string์ ์ฒซ character์ ์ ๊ทผํ๋ ์์น์ด๋ฉฐ, endIndex๋ ๋ง์ง๋ง character์ ์ ๊ทผํ๋ ์์น์ด๋ค. ๋ง์ฝ ๋น String์ด๋ผ๋ฉด startIndex์ endIndex์ ๊ฐ์ ๊ฐ๋ค.
String์ index(before:), index(after:)์ ์ฌ์ฉํด์ ์ธ๋ฑ์ค์ ์ ๊ทผํ ์ ์๊ณ , index(_:offsetBy:)๋ฉ์๋๋ฅผ ์ด์ฉํด์ ์ฌ๋ฌ ๋ฌธ์๋ฅผ ํ ๋ฒ์ ๋ฐ์ด๋์ ์ ๋ ์๋ค.
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
๋ง์ฝ String ๋ฒ์์์ ๋ฒ์ด๋ ์ธ๋ฑ์ค์ ์ ๊ทผํ๋ ค๊ณ ํ๋ฉด ์๋ฌ๋ฅผ ๋ฐ์์ํจ๋ค.
greeting[greeting.endIndex] // Error
greeting.index(after: greeting.endIndex) // Error
indices ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋ฌธ์์ด์ ๋ชจ๋ index์ ์ ๊ทผ ํ ์ ์๋ค.
for index in greeting.indices {
print("\(greeting[index]) ", terminator: "")
}
// Prints "G u t e n T a g ! "
Inserting and Removing (๋ฌธ์์ด ์ฝ์ ๋ฐ ์ญ์ ) : string.insert(), sring.remove()
String์ ํน์ ์ธ๋ฑ์ค์ Character๋ฅผ ์ฝ์ ํ๊ฑฐ๋ ์ญ์ ํ ์ ์๋ค. ํน์ ์ธ๋ฑ์ค์ ํ๋์ ๋ฌธ์๋ง ๋ฃ์ ๋๋ insert(_:at:)๋ฉ์๋๋ฅผ ์ฌ์ฉํ๊ณ , ํน์ ์ธ๋ฑ์ค์ '๋ฌธ์์ด'์ ๋ฃ์ผ๋ ค๋ฉด insert(contentsOf:at:)์ ์ฌ์ฉํ๋ค.
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!"
remove(์ญ์ )๋ ๋ง์ฐฌ๊ฐ์ง๋ก ํ๊ธ์๋ง ์ญ์ ํ ๊ฒฝ์ฐ remove(:at:)์ ์ฌ์ฉํ๋ฉด ๋๊ณ , ๋ฌธ์์ด์ด๋ ํน์ ํ ๋ฒ์๋ฅผ ์ญ์ ํ๊ณ ์ถ์ ๋๋ removeSubragne(_:) ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
welcome.remove(at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there"
// hello there!์์ !๊ฐ ์ญ์ ๋จ (๋ง์ง๋ง ์ธ๋ฑ์ค before)
let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
welcome.removeSubrange(range)
// welcome now equals "hello"
// ๋ณดํต ๋งจ ๋ค์ ์ธ๋ฑ์ค๊ฐ -1 ์ด๋๊น, -6๋ถํฐ (๊ณต๋ฐฑ) endindex before๊น์ง ์ญ์ ํ๋ฉด๋๋ค. (๋๊น์ง)
// swift์์๋ ๋ง์ง๋ง์ endindex before ๋ก ์ธ์ํ๋๋ณด๋ค.
SubStrings (๋ถ๋ถ ๋ฌธ์์ด)
String์์ prefix(_:)์ ๊ฐ์ ๋ฉ์๋๋ก substring์ ๊ฐ์ง๊ณ ์ค๋ฉด ๊ฒฐ๊ณผ๋ Substring ์ธ์คํด์ค๊ฐ ๋๋ค. swift์์ substring๊ณผ ๊ฐ์ string์ ๊ฑฐ์ ๋น์ทํ๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์๋ ๊ทธ๋ฅ ๋์ผํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
ํ์ง๋ง substring์ 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๊ณผ substring์ ์ฐจ์ด๋ฅผ ๋ฐ๊ฒฌํ ์ ์๋ค. substring์ ๊ธฐ์กด์ string์ด ์ฌ์ฉํ๊ณ ์๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฌ์ฉํ๊ฑฐ๋ ๋ค๋ฅธ substring์ด ์ฌ์ฉํ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ์ด๋ ๊ธฐ์กด์ string์ด๋ substring์ ์์ ํ์ง ์์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ๋ฅผ ํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ญ๋น๋ฅผ ํ์ง ์์ ์ ์๋ค. ํ์ง๋ง substring์ ๊ธฐ์กด์ string์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฌ์ฉํ๋๋ฐ ์ด๋ฌํ ๋ฐฉ์ ๋๋ฌธ์ substring์ ์ฌ์ฉํ๋ ๋์์๋ ๊ธฐ์กด์ string์ ๋ฉ๋ชจ๋ฆฌ์ ๋ณด๊ดํด์ผ ํ๋ค. ์ฆ, substring์ ์ค๋ ์ง์ํ๊ธฐ์๋ ์ ํฉํ์ง ์๋ค.
Comparing Strings (๋ฌธ์์ด ๋น๊ต)
swift๋ ํ ์คํธ ๊ฐ์ ๋น๊ตํ ์ ์๋ ์ธ ๊ฐ์ง ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค : ๋ฌธ์์ด๊ณผ ๋ฌธ์ ๋์ผ์ฑ ํ๋จ, ์ ๋์ฌ ๋์ผ์ฑ ํ๋จ, ์ ๋ฏธ์ฌ ๋์ผ์ฑ ํ๋จ.
String and Character Equality (๋ฌธ์ ๋ฐ ๋ฌธ์์ด ๋์ผ์ฑ) : ==, !==
๋ฌธ์์ด ๋ฐ ๋ฌธ์ ๋์ผ์ฑ์ ๋น๊ต ์ฐ์ฐ์์ ๋์ผํ๊ฒ ๋์ผ ์ฐ์ฐ์ (==) ๊ฐ์ง์์ ์ฐ์ฐ์ (!=)๋ฅผ ํ์ฉํ๋ค.
let quotation = "We're a lot alike, you and I."
let sameQuotation = "We're a lot alike, you and I."
if quotation == sameQuotation {
print("These two strings are considered equal")
}
// Prints "These two strings are considered equal"
extended grapheme clusters๊ฐ ๋์ผํ ๊ฒฝ์ฐ ๋ ๋ฌธ์์ด๋ ๋์ผํ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ๋ค. ์๊น ๋ณธé์ ๊ฐ์ด ๋ ๊ฐ์ ์ค์นผ๋ผ๋ก ์ด๋ฃจ์ด ์ง ๋ฌธ์์ธ ๊ฒฝ์ฐ์๋ e์ ๋์ผํ ๋ฌธ์๋ก ๊ฐ์ฃผํ๋ค.
// "Voulez-vous un café?" using LATIN SMALL LETTER E WITH ACUTE
let eAcuteQuestion = "Voulez-vous un caf\u{E9}?"
// "Voulez-vous un cafeฬ?" 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"
๋ฐ๋๋ก ์์ด์์ ์ฌ์ฉ๋๋ ๋ผํด์ด ๋๋ฌธ์ A (U+0041, or "A") ๋ ๋ฌ์์์์ ์ฌ์ฉ๋๋ ํค๋ฆด๋ฌธ์ A (U+0410, or "ะ")์๋ ๊ฐ์ง ์๋ค.
let latinCapitalLetterA: Character = "\u{41}"
let cyrillicCapitalLetterA: Character = "\u{0410}"
if latinCapitalLetterA != cyrillicCapitalLetterA {
print("These two characters aren't equivalent.")
}
// Prints "These two characters aren't equivalent."
Prefix and Suffix Equality (์ ๋์ฌ ๋ฐ ์ ๋ฏธ์ฌ ๋์ผ์ฑ) : hasPrefix(), hasSuffix()
๋ฌธ์์ด์ ํน์ ๋ฌธ์์ด ์ ๋์ฌ ๋๋ ์ ๋ฏธ์ฌ๊ฐ ์๋์ง ํ์ธ ํ๋ ค๋ฉด ๋ฌธ์์ด์ hasPrefix(_:) ๋ฐ hasSuffix(_:)๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. ๋ ๋ฉ์๋๋ ๋ชจ๋ ๋ฌธ์์ด ์ ํ์ ๋จ์ผ ์ธ์๋ฅผ ์ฌ์ฉํ๊ณ ๋ถ์ธ ๊ฐ์ ๋ฐํํ๋ค.
let romeoAndJuliet = [
"Act 1 Scene 1: Verona, A public place",
"Act 1 Scene 2: Capulet's mansion",
"Act 1 Scene 3: A room in Capulet's mansion",
"Act 1 Scene 4: A street outside Capulet's mansion",
"Act 1 Scene 5: The Great Hall in Capulet's mansion",
"Act 2 Scene 1: Outside Capulet's mansion",
"Act 2 Scene 2: Capulet's orchard",
"Act 2 Scene 3: Outside Friar Lawrence's cell",
"Act 2 Scene 4: A street in Verona",
"Act 2 Scene 5: Capulet's mansion",
"Act 2 Scene 6: Friar Lawrence's cell"
]
var act1SceneCount = 0
for scene in romeoAndJuliet {
if scene.hasPrefix("Act 1 ") {
act1SceneCount += 1
}
}
print("There are \(act1SceneCount) scenes in Act 1")
// Prints "There are 5 scenes in Act 1"
var act1SceneCount = 0
for scene in romeoAndJuliet {
if scene.hasPrefix("Act 1 ") {
act1SceneCount += 1
}
}
print("There are \(act1SceneCount) scenes in Act 1")
// Prints "There are 5 scenes in Act 1"
Unicode Representations of Strings
์ ๋์ฝ๋ ๋ฌธ์์ด์ด ํ ์คํธ ํ์ผ์ด๋ ๋ค๋ฅธ ์ ์ฅ์์ ์ ์ฅ๋ ๋ ๋ฌธ์์ด์ ์ ๋์ฝ๋ ์ค์นผ๋ผ ๊ฐ์ ์ฌ๋ฌ ๊ฐ์ง Unicode-defined encoding forms์ ์ํด ์ธ์ฝ๋ฉ ๋๋ค. ์ฌ๊ธฐ์ UTF-8(8๋นํธ๋ก ์ธ์ฝ๋ฉ), UTF-16(16๋นํธ๋ก ์ธ์ฝ๋ฉ), UTF-32(32๋นํธ๋ก ์ธ์ฝ๋ฉ)๊ฐ ์๋ค.
Swift๋ ๋ฌธ์์ด์ ์ ๋์ฝ๋ ํํ์ ํ๋ ๋ฐฉ๋ฒ์ผ๋ก ์ฌ๋ฌ ๊ฐ์ง๋ฅผ ์ ๊ณตํ๋ค. ์ธ ๊ฐ์ง์ ์ ๋์ฝ๋ ํํ ๋ฐฉ์์ผ๋ก String ๊ฐ์ ์ ๊ทผํ ์ ์๋ค.(UTF-8, UTF-16, UTF-32) ๊ทธ๋ผ ์ธ ๊ฐ์ง ์ ๋์ฝ๋ ํํ ๋ฐฉ์์ ์ฐจ์ด๋ฅผ ์ดํด๋ณด์.
let dogString = "Dogโผ๐ถ"
UTF-8 Representation (8๋นํธ)
์ด๋ฌํ ์ฝ๋์ ์ธ ๊ฐ์ง ์ ๋์ฝ๋ ํํ ๋ฐฉ์์ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
for codeUnit in dogString.utf8 {
print("\(codeUnit) ", terminator: "")
}
print("")
// Prints "68 111 103 226 128 188 240 159 144 182 "
์ธ ์๋ฆฌ ์ญ์ง์๋ก ๋ฌธ์๋ฅผ ํํํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ์ด๊ฒ ๋ฐ๋ก UTF-8 ํํ์ด๋ค.
UTF-16 Representation (16๋นํธ) : string.UTF16View()
๊ฐ๋ฐ์๋ string.UTF16View ๋ก UTF-16 ํํ๋ฐฉ์์ ์ ๊ทผํ ์ ์๊ณ , ๋ถํธ๊ฐ ์๋ 16๋นํธ๋ก ํํํ๊ฒ ๋๋ค.
for codeUnit in dogString.utf16 {
print("\(codeUnit) ", terminator: "")
}
print("")
// Prints "68 111 103 8252 55357 56374 "
Unicode Scalar Representation
์ ๋์ฝ๋๋ฅผ 10์ง์๋ก ๋ฐ๊ฟ ์ ์๋ค. ์ฌ์ค ์ ๋์ฝ๋๊ฐ 16์ง์ ์ด๋ ๊ทธ๋ฅ 16์ง์๋ฅผ 10์ง์๋ก ๋ณํํ๋ค๊ณ ๋ณผ ์ ์๋ค.
for scalar in dogString.unicodeScalars {
print("\(scalar.value) ", terminator: "")
}
print("")
// Prints "68 111 103 8252 128054 "
์ฒ์ ์ธ ๊ฐ์ ๊ฐ์ D, o, g ๋ฌธ์๋ฅผ ๋ํ๋ธ๋ค. ๋ค๋ฒ์งธ codeUnit ๊ฐ (8252)๋ 16์ง์ ๊ฐ 203C์ ๊ฐ์ ์ญ์ง๋ฒ์ด๋ฉฐ, ์ด๋ U+203C๋ฅผ ๋ํ๋ธ๋ค.
๊ฐ ๊ฐ๋ค์ unicodeScalar ๊ฐ์ ์ฌ์ฉํ์ฌ ๋ฌธ์์ด ๋ณด๊ฐ๊ณผ ๊ฐ์ด ์ ๋ฌธ์์ด ๊ฐ์ ๊ตฌ์ฑํ ์ ๋ ์๋ค. (์๋)
for scalar in dogString.unicodeScalars {
print("\(scalar) ")
}
// D
// o
// g
// โผ
// ๐ถ
๋ง๋ฌด๋ฆฌํ๋ฉฐ
๋.. ๊ธธ๋ค.. 1์ ์ด๋ด๋ก๋ ๊ผญ ์ด ๋ชจ๋ ๋ฌธ๋ฒ ์ฌํญ์ ์ตํ๊ณ ์ฝ๋ฉํ ์คํธ๋ฅผ swift๋ก ๋ณผ ์ ์๊ฒ ๋ ธ๋ ฅํ์!