Subscripts trong Swift
1. Giới thiệu
Subscripts cho phép truy cập elements bằng cú pháp [index].
2. Subscript cơ bản
struct Matrix {
let rows: Int
let columns: Int
var grid: [Double]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
grid = Array(repeating: 0.0, count: rows * columns)
}
subscript(row: Int, col: Int) -> Double {
get {
grid[row * columns + col]
}
set {
grid[row * columns + col] = newValue
}
}
}
var matrix = Matrix(rows: 3, columns: 3)
matrix[0, 0] = 1.0
matrix[1, 1] = 2.0
matrix[2, 2] = 3.0
print(matrix[1, 1]) // 2.03. Read-Only Subscript
struct TimesTable {
let multiplier: Int
subscript(index: Int) -> Int {
multiplier * index
}
}
let threeTimesTable = TimesTable(multiplier: 3)
print(threeTimesTable[6]) // 18
print(threeTimesTable[9]) // 274. String Extension
extension String {
subscript(index: Int) -> Character? {
guard index >= 0, index < count else { return nil }
return self[self.index(startIndex, offsetBy: index)]
}
subscript(range: Range<Int>) -> Substring? {
guard range.lowerBound >= 0, range.upperBound <= count else {
return nil
}
let start = index(startIndex, offsetBy: range.lowerBound)
let end = index(startIndex, offsetBy: range.upperBound)
return self[start..<end]
}
}
let str = "Hello"
print(str[0]) // Optional("H")
print(str[4]) // Optional("o")
print(str[1..<4]) // Optional("ell")5. Multiple Parameters
struct Spreadsheet {
private var cells: [[String]]
init(rows: Int, cols: Int) {
cells = Array(repeating: Array(repeating: "", count: cols), count: rows)
}
// Subscript với row, col
subscript(row: Int, col: Int) -> String {
get { cells[row][col] }
set { cells[row][col] = newValue }
}
// Subscript với tên cell như A1, B2
subscript(cell: String) -> String {
get {
let col = Int(cell.first!.asciiValue! - 65) // A=0, B=1
let row = Int(String(cell.dropFirst()))! - 1
return cells[row][col]
}
set {
let col = Int(cell.first!.asciiValue! - 65)
let row = Int(String(cell.dropFirst()))! - 1
cells[row][col] = newValue
}
}
}
var sheet = Spreadsheet(rows: 10, cols: 5)
sheet[0, 0] = "Name"
sheet["B1"] = "Age"
print(sheet["A1"]) // Name6. Subscript trong Class
class DataStore {
private var storage: [String: Any] = [:]
subscript(key: String) -> Any? {
get { storage[key] }
set { storage[key] = newValue }
}
// Generic subscript
subscript<T>(key: String, default defaultValue: T) -> T {
storage[key] as? T ?? defaultValue
}
}
let store = DataStore()
store["name"] = "John"
store["age"] = 30
print(store["name"]) // Optional("John")
print(store["city", default: "Unknown"]) // Unknown7. Static Subscripts
enum Settings {
static var values: [String: String] = [:]
static subscript(key: String) -> String? {
get { values[key] }
set { values[key] = newValue }
}
}
Settings["theme"] = "dark"
Settings["language"] = "en"
print(Settings["theme"]) // Optional("dark")8. Subscript Overloading
struct MultiArray {
private var data: [Int] = Array(1...100)
// Subscript bằng index
subscript(index: Int) -> Int {
data[index]
}
// Subscript bằng range
subscript(range: Range<Int>) -> [Int] {
Array(data[range])
}
// Subscript bằng nhiều indices
subscript(indices: Int...) -> [Int] {
indices.map { data[$0] }
}
}
let arr = MultiArray()
print(arr[5]) // 6
print(arr[0..<5]) // [1, 2, 3, 4, 5]
print(arr[0, 5, 10]) // [1, 6, 11]9. Ví dụ thực tế: JSON-like Access
struct JSONValue {
private var storage: Any
init(_ value: Any) {
self.storage = value
}
subscript(key: String) -> JSONValue? {
guard let dict = storage as? [String: Any],
let value = dict[key] else {
return nil
}
return JSONValue(value)
}
subscript(index: Int) -> JSONValue? {
guard let array = storage as? [Any],
index < array.count else {
return nil
}
return JSONValue(array[index])
}
var stringValue: String? { storage as? String }
var intValue: Int? { storage as? Int }
}
let json = JSONValue([
"name": "John",
"age": 30,
"friends": ["Alice", "Bob"]
])
print(json["name"]?.stringValue) // Optional("John")
print(json["age"]?.intValue) // Optional(30)
print(json["friends"]?[0]?.stringValue) // Optional("Alice")📝 Tóm tắt
- Subscript cho phép truy cập bằng
[] - Có thể có
getvàset - Có thể nhận nhiều parameters
- Có thể overload với các types khác nhau
static subscriptcho type-level access- Hữu ích cho collections, matrices, JSON
Last updated on
Swift