我试图找出在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,但我希望能够在函数之外执行此操作。
我有一些基本的原因,我想这样做。声明所有类的引入会带来一些开销(主要是计划和编写,而不是执行时间)。
答案 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)