23

我是初学者,对Swift操作员没有高级知识。

我有以下课程

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

我想实现运算符subscript []以便从list.

我需要这样的东西:

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

我也希望能够写出这样的东西:

data[1][2]

是否有可能考虑到元素1fromContainer是一个array

感谢您的帮助。

4

6 回答 6

39

看起来这里有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]吗?

如果我们使用你的例子,你不能。因为data[1]返回类型的东西Any。而且你不能下标Any

但是,如果您添加演员表,则成为可能

var container = Container()
container[0] = ["Enterprise", "Defiant", "Voyager"]
(container[0] as! [String])[2] // > "Voyager"
于 2015-08-11T19:44:55.103 回答
6

一种解决方法是利用多个参数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]
于 2016-06-22T12:24:15.890 回答
2

Swift 5.2:在 UserDefaults 值中下标 - 有用的管理器

具有泛型类型的静态函数

class Defaults {

   static subscript<T>(key: DefaultsKey) -> T? {
      get {
        return UserDefaults.standard.value(forKey: key.rawValue) as? T
      }
      set {
        UserDefaults.standard.set(newValue, forKey: key.rawValue)
      }
    }
}

enum DefaultsKey: String {
    case firstKey = "JSGHDjasgchvsas"
}

节省价值

Defaults[.firstKey] = 34

获取价值

let value: Int = Defaults[.firstKey]

快乐编码!

于 2020-04-18T15:44:52.603 回答
1

听起来您正在寻找下标。您可以为自己的类型创建下标,如下例所示:

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

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

上面的例子只适用于 double [ ],因为我知道我们将返回一个Array. 这里以Array包含字符串为例,但您当然可以换成自己的类型

var container = Container()

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

print(container[0][0]) // "Stack"
print(container[1][1]) // "Bar"
于 2015-08-11T19:56:01.183 回答
1
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/

于 2015-08-11T19:43:27.487 回答
1
class Container {
    private var list = [Any]()
    subscript(_ index: Int) -> Int? {
       get {
            guard index < list.count else { return nil }
            return list[index]
      }
       set(newValue){
          guard let unwrappedElement = newValue else { return }
          list.insert(unwrappedElement, at: index)
       }
    }
}

在这里,我们使用具有可选类型的下标来处理超出范围的索引。

于 2020-11-29T18:15:28.163 回答