通过引用访问变量

时间:2014-09-09 15:04:42

标签: variables reference swift

我试图找出在Swift中引用简单类型的基本方法。

在C中,没有问题:

int a = 42;
int* refA = &a;
*refA = 43;
// At this point, a is 43

在Swift中,我似乎无法做到这一点。

var a:Int = 42

println ( a )

//    var aRef:Int = &a       // Nope.
//    var aRef:Int& = &a      // Nah.
//    inout var:Int aRef = &a // Nyet
//    var inout:Int aRef = &a // Non
//    var aRef:Int* = &a      // What are you, stupid, or stubborn?
//
//    aRef = 43               // If any of the above worked, I could do this.

println ( a )         // How can I get this to print "43"?

我无法在文档中找到任何说我能做到的事情。我知道作为函数参数修饰符的inout,但我希望能够在函数之外执行此操作。

我有一些基本的原因,我想这样做。声明所有类的引入会带来一些开销(主要是计划和编写,而不是执行时间)。

3 个答案:

答案 0 :(得分:3)

值不能通过Swift中的引用传递(inout参数除外),这是使其成为"没有C"的Objective-C的事情之一。您可能需要重新考虑您的方法,并考虑到语言的可能性和限制。

答案 1 :(得分:1)

一般来说,尝试使用语言A就好像它是基于特征的语言B一样,这是一种让自己陷入圆形方孔问题的好方法。相反,退一步 - 你用语言B中的特征X解决了什么问题?语言A可能有不同的(甚至可能更优雅的)方法来解决这些问题。

无法为任意值创建指针(或C ++样式引用)可能是Swift类型/内存安全性的一部分。添加该间接级别会使编译器更难以对代码进行合理的推论(特别是内存地址的所有权),从而为未定义的行为打开各种可能性(读取:错误,安全漏洞)。

Swift旨在eat bugs。通过为值与引用使用精心设计的语义,为特定用途增加inout,Swift可以更仔细地控制内存所有权并帮助您编写更可靠的代码。没有任何表现力的损失,真的 - 表达性只是采取不同的形式。 :)

如果你真的想把一个圆形挂钩插入一个方孔,你可以通过一个包含引用中任何值的通用实现来减少你的“计划和编写”开销。这样的事情,也许是:

class Handle<T> {
    var val: T
    init(_ val: T) {
        self.val = val
    }
}

请注意,有了这个,您仍然需要提前计划 - 因为您无法创建指针/对已存在的任意事物的引用,当您希望能够处理时,您必须通过句柄创建一些内容它稍后就像一个参考类型。

使用一些自定义运算符定义,您甚至可以使它看起来有点像C / C ++。 (如果你这样做,可以在Terrible Swift Ideas上发帖。)

答案 2 :(得分:1)

为了记录,您所期望的行为并非难以实现:

  1> func inc (inout x: Int) { x = x + 1 }
  2> var val:Int = 10
val: Int = 10
  3> inc(&val)
  4> val
$R0: Int = 11

你失去的是内置二进制操作的“性能”;但是你通过使用功能抽象获得的东西可以衡量任何非内置问题。

func incrementor (by: Int) (inout _ x: Int) { x = x + by }   #Bug in Swift prevents this '_'
var incBy10 = incrementor (10)
incBy10(&val)