Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Variables 通过引用访问变量_Variables_Reference_Swift - Fatal编程技术网

Variables 通过引用访问变量

Variables 通过引用访问变量,variables,reference,swift,Variables,Reference,Swift,我试图找出在Swift中引用简单类型的基本方法 在C中,这不是问题: int a = 42; int* refA = &a; *refA = 43; // At this point, a is 43 在斯威夫特,似乎我不能这样做 var a:Int = 42 println ( a ) // var aRef:Int = &a // Nope. // var aRef:Int& = &a // Nah. // ino

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

在C中,这不是问题:

int a = 42;
int* refA = &a;
*refA = 43;
// At this point, a is 43
在斯威夫特,似乎我不能这样做

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是一个函数参数修饰符,但我希望能够在函数之外实现这一点


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

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

一般来说,在功能对功能的基础上,尝试将语言A当作语言B来使用,是一种很好的方法,可以让您陷入圆滑的问题中。相反,退一步——在语言B中使用功能X解决了哪些问题?语言A可能有不同(甚至可能更优雅)的方法来解决这些问题

不能创建指向任意值的指针(或C++风格的引用)可能是Swift类型/内存安全的一部分。添加这种间接级别使编译器更难对代码进行合理的推断(特别是内存地址的所有权),从而为未定义的行为(读:bug、安全漏洞)打开了各种可能性

Swift的设计宗旨是:。通过对值和引用使用精心设计的语义,再加上针对特定用途的
inout
,Swift可以更仔细地控制内存所有权,并帮助您编写更可靠的代码。在没有任何表现力损失的情况下,真的——这种表现力只是采用不同的形式而已

如果你真的想把一个圆钉放进一个方孔里,你可以用一个通用的实现来减少你的“计划和编写”开销,这个实现将任何值封装在一个引用中。也许是这样的:

class Handle<T> {
    var val: T
    init(_ val: T) {
        self.val = val
    }
}
类句柄{
var val:T
初始值(val:T){
self.val=val
}
}
注意,有了这个,您仍然需要提前计划——因为您无法创建指向已经存在的任意对象的指针/引用,所以当您希望以后能够将其视为引用类型时,您必须通过句柄创建一些对象


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

请注意,你想要的行为并不是很难实现:

  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)

嗯,您可以通过引用传递函数(inout&适用于值类型),但看起来您无法在野外引用值类型。添加了inout参数异常以供将来参考。我想补充一点,使用inout参数可能只能在使用Objective-C方法时使用。在Swift中有更优雅的方式。
inout
可能是最好的节约使用方式,但在C/ObjC可互操作代码之外,它仍然非常有用。浏览Swift标准库,您会发现使用它可以做一些方便的事情,比如对任何集合进行排序的泛型函数。@rickster有趣,将对此进行研究!您是否有在Swift标准库中使用i/o参数的特定示例?
sort
swap
是很好的基本示例。特别是,
swap
的有趣之处在于,由于
inout
的工作方式,它将交换您传递给它的任何内容,包括那些局部变量、类的属性,甚至数组中的索引或切片。通过在Xcode中打开标准库界面(cmd单击库符号,如
String
)并搜索
inout
,可以找到更多信息。当然,您完全正确。当我学习新的语言时,我总是经历这个阶段(你认为斯威夫特很难吗?试试看——这对我来说很难)。我会明白的,但我总是有一些新语言的“一次性”项目,在我找到自己的步伐之前。我已经,我现在正在做一个更复杂的工作,涉及远程PTP-IP和实时视频。是的,这是我试图避免的开销。然而,如前所述,我仍然在“C”世界中思考。我需要再多用一点Swift,让我的思维变得敏捷。幸运的是,我有很多PHP经验。PHP是一种相当混乱的语言,但它有许多您可以在Swift中找到的陷阱。现在,担心这种开销水平可能是过度的——除非您已经有了一个正在优化的正常工作的应用程序。即使如此,优化也不太可能是在单个函数调用与内置(假设偶数发生)的级别,而是在架构(例如并行性、通信路径)或算法(例如搜索、排序)级别。如果您正在从PHP移动,请注意Swift闭包和Currun。实际上,我正在从Objc和C++迁移。我用许多不同的语言工作,我很好奇。你有“Swift中的Bug阻止了这个'"',我不知道这是什么意思。我不太熟悉Swift通配符,经常看到它们,所以我想我还有很多作业要做。我把你的代码片段放到了一个操场上,经过几次调整(删除通配符和注释,并添加一个值var),它使Xcode 6 GMc上的解析器崩溃。我提出了一份雷达报告。Xcode 6 GMc似乎有点不稳定。我经常遇到解析器和代码格式化程序间歇性崩溃。这是第一个100%可重复的。