Свифт оператора `индекс` []

Я начинаю с Swift, не имеющего предварительных знаний с операторами.

У меня есть следующий класс

class Container {
   var list: [Any] = [];
}

Я хочу реализовать оператор subscript [] для доступа к данным из list.

Мне нужно что-то вроде этого:

var data: Container = Container()
var value = data[5]
// also    
data[5] = 5

Также я хочу написать что-то вроде этого:

data[1][2]

Возможно ли, учитывая, что элемент 1 из Container является array?

Thanx для справки.

Ответы

Ответ 1

Похоже, здесь есть 2 вопроса.

1. Как включить subscripting в свой собственный класс?

Чтобы включить subscripting в вашем классе Container, вам нужно реализовать вычисленное свойство subscript, подобное этому.

class Container {
    private var list : [Any] = [] // I made this private

    subscript(index:Int) -> Any {
        get {
            return list[index]
        }
        set(newElm) {
            list.insert(newElm, atIndex: index)
        }
    }
}

Теперь вы можете использовать его таким образом.

var container = Container()
container[0] = "Star Trek"
container[1] = "Star Trek TNG"
container[2] = "Star Trek DS9"
container[3] = "Star Trek VOY"

container[1] // "Star Trek TNG"

2. Могу ли я получить доступ к одному элементу Container, который поддерживает подписи, записывая что-то вроде data[1][2]?

Если мы используем ваш пример no, вы не можете. Потому что data[1] возвращает что-то типа Any. И вы не можете индексировать Any.

Но если вы добавите бросок, это станет возможным

var container = Container()
container[0] = ["Enterprise", "Defiant", "Voyager"]
(container[0] as! [String])[2] // > "Voyager"

Ответ 2

Обходным путем является использование нескольких параметров в subscript

Итак, вместо data[1][2] вы можете сказать data[1, 2]. Это будет удобно в некоторых случаях

struct Container {
  subscript(a: Int, b: Int) -> String {
    print(a)
    print(b)
    return "possible"
  }
}

let data = Container()
data[1, 2]

Ответ 3

class Container
{
    var list: [AnyObject] = ["hello" , "world"];
    subscript ( i : Int) -> AnyObject{
        get{
            return list[i]
        }
        set{
            list[i] = newValue
        }
    }
}

var c : Container = Container()
println(c[1])

c[1] = "lol"

println(c[1])

Дополнительные сведения об операторе: http://nshipster.com/swift-operators/

Ответ 4

Похоже, вы ищете индексы. Вы можете создавать индексы для своего собственного типа, например, в следующем примере:

class Container {
    var list = [["Hello", "World"], ["Foo", "Bar"]]

    subscript(index: Int) -> [String] {
        get {
            return list[index]
        }
        set {
            list.insert(newValue, atIndex: index)
        }
    }
}

Приведенный выше пример работает с двойным [ ] только потому, что я знаю, что мы вернем Array. Здесь Array содержит строки в качестве примера, но вы можете, конечно, поменять свой собственный тип

var container = Container()

container[0][0] = "Stack"
container[0][1] = "Overflow"

print(container[0][0]) // "Stack"
print(container[1][1]) // "Bar"