【问题标题】:Syntactic Sugar Struct Reference in Swift?Swift 中的语法糖结构参考?
【发布时间】:2015-06-21 15:16:19
【问题描述】:

在c++ 中,可以引入一个别名引用,如下所示:

StructType & alias = lengthyExpresionThatEvaluatesToStuctType;
alias.anAttribute = value; // modify "anAttribute" on the original struct

在 Swift 中操作(值类型)结构是否有类似的语法糖?

更新 1: 例如:假设结构包含在类型 [String:StructType] 的字典中,并且我喜欢修改结构 myDict["hello" 中的几个属性]。我可以制作该条目的临时副本。修改副本,然后将临时结构体复制回字典,如下:

var temp = myDict["hello"]!
temp.anAttribute = 1
temp.anotherAttribute = "hej"
myDict["hello"] = temp

但是,如果我的函数有多个退出点,我将不得不在每个退出点之前编写 myDict["hello"] = temp,因此如果我可以为 myDict["hello"] 引入别名(参考)会更方便,如下所示:

var &  alias = myDict["hello"]! // how to do this in swift ???
alias.anAttribute = 1
alias.anotherAttribute = "hej"

更新 2: 在否决或关闭投票之前:请查看 Building Better Apps with Value Types in swift(来自 WWWDC15)! 值类型是Swift的一个重要特性!您可能知道,Swift 借鉴了 C++ 的几个特性,而 值类型 可能是 C++ 最重要的特性(当将 C++ 与Java 等语言)。对于值类型,C++ 有一些语法糖,我的问题是:Swift 是否隐藏了类似的糖用它的语言?我相信Swift 最终会...如果您不理解这个问题,请不要投票!

我刚刚阅读了 Deitel 关于 Swift 的书。虽然我不是专家(还),但我并不完全是新奇的。我正在尝试尽可能高效地使用 Swift!

【问题讨论】:

  • 您能否详细解释一下 C++ 代码的含义?那里的& 是什么?你到底想做什么?
  • @nhgrif:他正在修改lengthyExpresionThatEvaluatesToStuctType [原文如此],在以后的行中将其称为alias,引用类型的工作方式。
  • 是否有必要让两个不同的变量在同一个范围内引用同一个结构?这个问题确实需要更具体地说明在什么情况下究竟要完成什么。我知道提问者可能不是 Swift 专家,但重要的是学习如何以 Swift 方式做事,而不是简单地尝试使用 Swift 语法以 C++ 方式做事。因此,请通过可能的具体示例清楚地了解要完成的工作。
  • @nhgrif,好的,我已经更新了我的问题。

标签: swift


【解决方案1】:

一般而言,Swift 不允许对值类型使用引用语义,除非用作声明为 inout 的函数参数。您可以将对结构的引用传递给在 inout 版本上工作的函数(我相信,需要引用,这是作为复制写入实现的,而不是作为内存引用)。您还可以捕获嵌套函数中的变量以获得类似的语义。在这两种情况下,您都可以从 mutating 函数中提前返回,同时仍然保证适当的分配。这是我在 Xcode 6.3.2 和 Xcode 7-beta1 中运行的示例 Playground:

//: Playground - noun: a place where people can play

import Foundation

var str = "Hello, playground"

struct Foo {
    var value: Int
}

var d = ["nine": Foo(value: 9), "ten": Foo(value: 10)]

func doStuff(key: String) {

    let myNewValue = Int(arc4random())

    func doMutation(inout temp: Foo) {
        temp.value = myNewValue
    }

    if d[key] != nil {
        doMutation(&d[key]!)
    }
}

doStuff("nine")
d // d["nine"] has changed... unless you're really lucky

// alternate approach without using inout
func doStuff2(key: String) {

    if var temp = d[key] {

        func updateValues() {
            temp.value = Int(arc4random())
        }

        updateValues()
        d[key] = temp
    }
}

doStuff2("ten")
d // d["ten"] has changed

您不必将 doMutation 函数嵌套在您的外部函数中,我这样做只是为了演示您可以从周围的函数中捕获像 myNewValue 这样的值,这可能会使实现更容易。但是,updateValues 必须嵌套,因为它捕获了 temp。

尽管这可行,但根据您的示例代码,我认为在这里使用一个类(如果您关心性能,可能是一个最终类)确实是更惯用的命令式 Swift。


如果您真的愿意,您可以使用标准库函数withUnsafeMutablePointer 获取原始指针。您也可以将值放入只有一个成员的内部类中。还有一些功能性的方法可以缓解提前返回问题。

【讨论】:

  • 谢谢,(+1),在将其标记为“答案”之前,我必须考虑一下!
  • 当然。这是一个值得研究和思考的有趣问题。我想我应该先说“不,没有这样的语法糖”。但是很难证明是否定的:)
猜你喜欢
  • 2018-06-21
  • 1970-01-01
  • 2014-08-10
  • 2020-02-17
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多