์๋ ํ์ธ์, ๊ฐ์์ ๋๋ค. ์ค๋์ ์๋ธ์คํฌ๋ฆฝํธ์ ๋ํด์ ๊ณต๋ถํด๋ณด์์ต๋๋ค. ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด, string์์ ์ธ๋ฑ์ค๋ก ์ ๊ทผํ๋ ๋ฐฉ์์ ๋ํด์๋ ๋์ค๋๋ฐ์, ์ด ๋ถ๋ถ์ ๋ํด์๋ ํ์ด์ฌ์์๋ ์์ฐ์ค๋ฝ๊ฒ ๋๋๋ฐ, ์ ์๋ผ!!! ํ๋ฉด์ ์ฑ์ง๋๋ ๊ธฐ์ต์ด ์๋ค์ ํํ... ์๋ธ์คํฌ๋ฆฝํธ๋ฅผ ํ์ฉํ๋ฉด ๋ฌธ์์ด์์๋ [index]๋ฅผ ํ์ฉํ์ฌ ์ ๊ทผํ ์ ์๋ค๋ ์ฌ์ค! ๊ทธ๋ผ ์ด์ ์ดํด๋ณด๋๋ก ํ์ฃ .
Swift Documents chap.12 Subscripts ๋ฐ๋ก๊ฐ๊ธฐ
Subscripts๋?
ํด๋์ค, ๊ตฌ์กฐ์ฒด, ๊ทธ๋ฆฌ๊ณ ์ด๊ฑฐํ์์ ์ํ์ค์ ๋ฉค๋ฒ ์์์ ์ ๊ทผํ๊ธฐ ์ํ ๋ฐ๋ก๊ฐ๊ธฐ ์ฒจ์๋ก, ๋จ์ผ ํ์ ์ ์ฌ๋ฌ ์๋ธ ์คํฌ๋ฆฝํธ๋ฅผ ์ ์ํ ์ ์๋ค. ์๋ธ์คํฌ๋ฆฝํธ๋ฅผ ์ด์ฉํ๋ฉด ์ถ๊ฐ์ ์ธ ๋ฉ์๋ ์์ด ํน์ ๊ฐ์ ํ ๋นํ๊ฑฐ๋ ๊ฐ์ ธ์ฌ ์ ์๋ค.
์ฐ๋ฆฌ๋ ํ์์ ์๋ธ์คํฌ๋ฆฝํธ๋ฅผ ์์ฃผ ์ฌ์ฉํด์๋ค. ๋ฐฐ์ด์ ์ ๊ทผํ๊ธฐ ์ํด์๋ someArray[index]๋ก, ๋์ ๋๋ฆฌ์ ์ ๊ทผํ๊ธฐ ์ํด์๋ someDictionary[index]๋ก [] ๋ฅผ ํ์ฉํ์ฌ ์ ๊ทผํ ์ ์์๋ค. ์ด [] ๊ฐ ๋ฐ๋ก ์๋ธ์คํฌ๋ฆฝํธ์ด๋ค.
๋ฐฐ์ด index์ ์ ๊ทผํ๋ []์ ์ ์๋ฅผ ๋ฐ๋ผ๊ฐ๋ณด๋ฉด, ์๋์ ๊ฐ๋ค.
@inlinable public subscript(index: Int) -> Element
[]๋ ์ด๋ ๊ฒ ์ ์๋์ด ์๋๋ฐ, ๋ฐฐ์ด์ ์๋ธ์คํฌ๋ฆฝํธ๋ parameter๋ก Intํ์ index๋ก ๋ฐ๊ณ , ํด๋น index์ ํด๋นํ๋ Element๋ฅผ ๋ฐํํ๋ ํํ์์ ์ ์ ์๋ค.
์๋ธ์คํฌ๋ฆฝํธ๋ ์ด์ฒ๋ผ ์ํ์ค์ ๋ฉค๋ฒ ์์์ ์ ๊ทผํ ๋ ์ฌ์ฉ๋๋ค.
Subscript Syntax (์๋ธ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ)
์๋ธ ์คํฌ๋ฆฝํธ ์ ์ธ ๋ฌธ๋ฒ์ ์ธ์คํด์ค ๋ฉ์๋์ ์ฐ์ฐ ํ๋กํผํฐ๋ฅผ ์ ์ธํ๋ ๊ฒ๊ณผ ๋น์ทํ๋ค. ์ธ์คํด์ค ๋ฉ์๋์ ๋ค๋ฅธ ์ ์, ์๋ธ์คํฌ๋ฆฝํธ๋ ์ฝ๊ณ -์ฐ๊ธฐ ํน์ ์ฝ๊ธฐ ์ ์ฉ๋ง ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ด๋ค. ์ ์๋ ์ฐ์ฐ ํ๋กํผํฐ ๋ฐฉ์๊ณผ ๊ฐ์ด setter, getter ๋ฐฉ์์ ๋ฐ๋ฅธ๋ค.
subscript(index: Int) -> Int {
get {
// ์ ์ ํ ๋ฐํ ๊ฐ
}
set(newValue) {
// ์ ์ ํ set ์ก์
}
}
์๋ธ์คํฌ๋ฆฝํธ์ set์ ๋ํ ์ธ์ ๊ฐ์ ๋ฐ๋ก ์ง์ ํ์ง ์์ผ๋ฉด, ๊ธฐ๋ณธ ๊ฐ์ผ๋ก newValue๋ฅผ ์ฌ์ฉํ๋ค. ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ ์ธํ๋ ค๋ฉด, get, set์ ์ง์ฐ๊ณ ๋ฐ๋ก ์ง์ ํ์ง ์๊ณ ์์ฑํ๊ฒ ๋๋ฉด get์ผ๋ก ๋์ํ๊ฒ ๋์ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ ์ธ๋๋ค.
์๋ ์ฝ๋๋ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ ์ธ๋ ์๋ธ์คํฌ๋ฆฝํธ ์ฝ๋์ด๋ค.
/*---------์ฝ๊ธฐ ์ ์ฉ ๊ธฐ๋ณธ ํํ--------*/
subscript(index: Int) -> Int {
// ์ ์ ํ ๋ฐํ ๊ฐ
}
struct TimesTable {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \\(threeTimesTable[6])")
// "six times three is 18" ์ถ๋ ฅ
โท ์ฝ๋ ์ค๋ช
- TimeTable ๊ตฌ์กฐ์ฒด์ multiplier๋ฅผ 3์ผ๋ก ์ค์ ํ๊ณ threeTimesTable[6]์์ 6๋ฒ์งธ ๊ฐ, ์ฌ๊ธฐ์๋ 3์ 6์ ๊ณฑํ๊ฐ์ ์ถ๋ ฅํจ.
Subscript Usage (์๋ธ์คํธ๋ฆฝํธ ์ฌ์ฉํ๊ธฐ)
์๋ธ์คํฌ๋ฆฝํธ ์ฌ์ฉ ์์๋ฅผ ์ดํด๋ณด์.
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2
numberOfLegs ๊ฐ์ ํ์ ์ถ๋ก ์ ์ํด [String: Int]ํ์ ๊ฐ๋๋ค. numberOfLegs[”bird”] = 2 ๋ ์ฌ์ ํ ๋ณ์ numberOfLegs ์ key๋ก bird๋ฅผ , ๊ทธ ๊ฐ์ 2๋ฅผ ๋ฃ์ผ๋ ค๋ ์๋ธ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ์ด๋ค.
โท note
- ๋์ ๋๋ฆฌ์ ๋ฐํ๊ฐ์ optional์ด๋ค. ์ฌ์ ์ ํน์ ํค ๊ฐ์ด ์๋ ๊ฒฝ์ฐ๊ฐ ์์ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์๋ธ์คํฌ๋ฆฝํธ ์ฌ์ฉํ๊ธฐ (1)
let name = "jisoo"
name[0] //ERROR
name[0]์ ํ๋ฉด ์ ์ผ ์์์๋ ์ํ๋ฒณ “j”๊ฐ ๋ฐํ๋๋ฉด ์ข๊ฒ ์ง๋ง, ์ด๋ ์๋ฌ์ด๋ค. ํด๋น ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ ์ ์๋ค๋ ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ค. ์ฐ๋ฆฌ๋ ์ด์ ๊ฐ์ ์ ๊ทผํ๊ธฐ ์ํ ์๋ธ์คํฌ๋ฆฝํธ๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์ผ๋, ์ด๋ ๊ฒ ์ธ๋ฑ์ค๋ก ์ํ๋ฒณ์ ์ ๊ทผํ๋ ์๋ธ์คํฌ๋ฆฝํธ๋ฅผ ๊ฐ๋จํ๊ฒ ๋ง๋ค์ด๋ณด์.
extension String {
subscript(idx: Int) -> String? {
guard(0..<count).conrtains(idx) else {
return nil
}
let target = index(startIndex, offsetBy: idx)
return String(self[target])
}
}
์ด๋ ๊ฒ String์ ํ์ฅํ์ฌ ์๋ธ์คํฌ๋ฆฝํธ๋ฅผ ์ง์ ๊ตฌํํด์ฃผ๋ฉด ์๋์ฒ๋ผ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐฉ์์ผ๋ก String์ ์ ๊ทผํ ์ ์๋ค.
let name = "jisoo"
name[0] //optional("j")
name[100] //nil
์๋ธ์คํฌ๋ฆฝํธ ์ฌ์ฉํ๊ธฐ (2)
struct Stack {
var stack: [Int] = [0,1,2,3,4,5]
subscript(index: Int) -> Int {
get {
return stack[index]
}
set {
stack[index] = newValue
}
}
}
/*---------- []๋ฅผ ํตํด getter, setter์ ์ ๊ทผํ๊ธฐ ------------*/
var stack: Stack = .init()
stack[0] // ์๋ธ์คํฌ๋ฆฝํธ getter์ ์ ๊ทผ
stack[1] = 2 // ์๋ธ์คํฌ๋ฆฝํธ setter ์ ์ ๊ทผ
Subscript Options
์๋ธ์คํฌ๋ฆฝํธ๋ ์ ๋ ฅ ์ธ์์ ์ซ์์ ์ ํ์ด ์๊ณ , ์ ๋ ฅ ์ธ์์ ํ์ ๊ณผ ๋ฐํํ์ ์ ์ ํ๋ ์๋ค. ๋ค๋ง in-out ํ๋ผ๋ฏธํฐ๋ ๊ธฐ๋ณธ ํ๋ผ๋ฏธํฐ ๊ฐ์ ์ ๊ณตํ ์๋ ์๋ค. ์๋ธ์คํฌ๋ฆฝํธ๋ ์ค๋ฒ๋ก๋ฉ๋ ํ์ฉํ๋ค. ๊ทธ๋์ ์ธ์ํ, ๋ฐํํ์ ๋ฐ๋ผ ์ํ๋ ์ ๋งํผ์ ์๋ธ์คํฌ๋ฆฝํธ๋ฅผ ์ ์ธํ ์ ์๋ค. ๋ค์์ ์๋ธ์คํฌ๋ฆฝํธ๋ฅผ ์ด์ฉํ์ฌ ๋ค์ฐจ์ ํ๋ ฌ์ ์ ์ธํ๊ณ ์ ๊ทผํ๋ ์์์ด๋ค.
struct Matrix {
let rows: Int, columns: Int
var grid: [Double]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
grid = Array(repeating: 0.0, count: rows * columns)
}
func indexIsValid(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
subscript(row: Int, column: Int) -> Double {
get {
assert(indexIsValid(row: row, column: column), "Index out of range")
return grid[(row * columns) + column]
}
set {
assert(indexIsValid(row: row, column: column), "Index out of range")
grid[(row * columns) + column] = newValue
}
}
}
์ ์ฝ๋์์ subscript(row: Int, column: Int) -> Double ์ฝ๋์ ๊ฐ์ด row, column 2๊ฐ์ ์ธ์๋ฅผ ๋ฐ๊ณ , Double์ ๋ฐํํ๋ ์๋ธ์คํฌ๋ฆฝํธ๋ฅผ ์ ์ธํ๋ค. get, set ๊ฐ๊ฐ์ indexIsValid๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ์ ์ํ ์ธ๋ฑ์ค๊ฐ ์๋ ๊ฒฝ์ฐ ํ๋ก๊ทธ๋จ์ด ๋ฐ๋ก ์ข ๋ฃ๋๋๋ก assert๋ฅผ ํธ์ถํ๋ค. ์ ์ธํ ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ์ ์ด์ฉํด var matrix = Matrix(rows: 2, columns: 2) 2 by 2 ํ๋ ฌ์ ์ ์ธํ๋ค.
grid ๋ฐฐ์ด์ ์๋ธ์คํฌ๋ฆฝํธ์ ์ํด ์์ ๊ฐ์ด row์ column์ ๊ฐ๋ ํ๋ ฌ๋ ๋์ํ๋ค. ํ๋ ฌ์ ์๋ธ์คํฌ๋ฆฝํธ๋ฅผ ์ด์ฉํด ํน์ row, column์ ๊ฐ์ ๋ฃ์ ์ ์๋ค.
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2
๊ฐ์ ๋ฃ์ ๊ฒฐ๊ณผ ํ๋ ฌ์ ์๋์ ๊ฐ๋ค.
ํ๋ ฌ์ ์ ์ถ๋ ฅ์ row๋ column์ ๋ฒ์๊ฐ ์ ์ ํ์ง ์๋์ ์ฝ๋๋ก ํ์ธํ ์ ์๋ค.
func indexIsValid(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
๋ง์ฝ ์ ์ ํ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ฉด assert๊ฐ ์คํ๋๋ค.
let someValue = matrix[2, 2]
// [2, 2]๊ฐ ์ฌ์ฉํ ์ ์๋ ํ๋ ฌ์ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ฏ๋ก assert๊ฐ ์คํ๋ฉ๋๋ค.