【问题标题】:How to I use optional vars with mutable collections?如何将可选变量与可变集合一起使用?
【发布时间】:2014-06-22 09:08:01
【问题描述】:

当集合被分配给可选变量时,我似乎无法让它们变得可变。在下面的示例代码中, NonOptional 按预期工作。 var 将保持集合上的可变状态。没有本地变量,我可以直接使用变量字段。但是我不确定如何让 var 具有不可变的集合,我应该假设“let”而不是“var”可以解决问题吗?

尽管如此,查看 Optional 类,需要一个本地 var 来为集合提供一个可变状态(即使 XCode 在我不使用本地 var 时建议 append() )。这真的是我应该编写代码通过添加局部变量来更新集合的方式吗?有没有不使用本地变量的更简洁的方法?我很想知道一个集合的分配是一个简单的别名还是它做了一个副本,无论是浅的还是深的?

   class NonOptional {
        var exclamation: String[] // using var should set that collection as mutable...

        init() {
            self.exclamation = []
        }

        func write() {
            self.exclamation.append("exclamation")
        }

        func delete() {
            if self.exclamation.count > 0 {
                self.exclamation.removeAtIndex(0)
            }
        }
    }

    class Optional {
        var question: String[]? // using var should set that collection as mutable...

        init() {
            self.question = []
        }

        func write() {
            var local = self.question! // copy or pass by ref?
            local.append("question")    // why can't I just do self.foo!.append("foo") ?
        }

        func delete() {
            if self.question!.count > 0 {
                var local = self.question!
                local.removeAtIndex(0)
            }
        }
    }

【问题讨论】:

标签: swift


【解决方案1】:

这个问题是在 Swift 1 仍处于测试阶段时提出的,此后发生了很大变化(尽管我不完全确定 Swift 1 中是否不存在这个特定功能)。

对于后代来说,在 Swift 3 中改变一个可选数组是没有问题的。你可以这样做:

var strings: [String]? = ["a", "b"]
strings?[0] = "A"
// strings is now Optional(["A", "b"])
strings?.append("c")
// strings is now Optional(["A", "b", "c"])
strings?.remove(at: 1)
// strings is now Optional(["A", "c"])

【讨论】:

    【解决方案2】:
    var question: String[]? // using var should set that collection as mutable...
    

    这是错误的。那里的var 表示可选引用是“可变的”,即它可以是nil 或设置为实际数组。 Swift 然后默认使数组不可变。

    许多关于数组和可变性的小细节目前有点不稳定,我希望在未来几周内会有修复、更改和明确定义。

    【讨论】:

    • 很高兴听到。我知道这不是一个发表意见的好地方,所以让我提出一个建议,即使我为此受到抨击:我已经看到自己经常用 Swift 解决这样的问题。也许该语言过于努力地向后兼容,不确定。为了保存像 mut/mutating 这样的关键字,这种语法不容易编写甚至阅读。当你可以明确地告诉 vars 是否是可变的时,我更喜欢 Rust 或 OCaml 中的东西。今天不可变数组实际上是可变的减去大小变化,所以我认为一个新的关键字可以解决问题的清晰度和正确性
    • 只要不改变不可变数组的大小,就可以改变不可变数组的问题显然至少会在未来的版本中得到解决。我们将获得真正的不可变数组。
    • 在此期间,您建议我做什么?坚持使用类似桥的语法的 NSMutable 数组,或者使用上面的 var 技巧,本质上将数组重新定义为函数范围内的可变数组?只是想弄清楚什么是处理语言设计中似乎存在很大缺陷的最佳方法。我有点闷闷不乐地看到这只会在以后解决。毕竟,内存管理感觉应该更牢固地锚定在语言蓝图中
    • 我不知道你的具体情况,但我会使用默认的空数组,这样我就没有可选的类型。然后我只有一个很好的可变数组,它默认为空数组。否则,我会从上面使用您的技巧。顺便说一句,你可以直接在原地初始化属性var myArray = String[]()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-19
    • 2011-03-11
    • 2012-01-07
    • 1970-01-01
    • 2012-02-12
    相关资源
    最近更新 更多