app*_*ing 42 ampersand swift inout
我知道&符号有点操作,但有时候我会在变量名称前面看到它.是什么把一个&
在前面的变量做?
Ica*_*aro 58
它可以inout
使变量成为输入输出参数.In-out实际上意味着通过引用而不是通过值传递值.它不仅要求通过引用接受值,还要通过引用传递它,所以将它传递给& - foo(&myVar)
而不仅仅是foo(myVar)
如你所见,你可以在Swift中使用它来处理错误,你必须创建一个错误引用,并使用&
该函数将其传递给函数,如果发生错误则将填充错误值,或者将变量恢复为之前的状态
我们为什么用它?有时函数已经返回其他值,只返回另一个(如错误)会让人感到困惑,所以我们将它作为inout传递.其他时候我们希望函数填充值,因此我们不必迭代许多返回值,因为函数已经为我们做了 - 以及其他可能的用途.
我希望能帮到你!
Leo*_*Leo 11
这意味着它是一个输入输出变量.您可以直接使用该变量执行某些操作.它是通过地址传递的,而不是副本.
例如:
var temp = 10
func add(inout a: Int){
a++
}
add(inout:&temp)
temp // 11
Run Code Online (Sandbox Code Playgroud)
如果&
在函数中放入变量之前,则表示此变量是inout变量.
@Icaro已经描述了它的含义,我将举一个例子来说明inout变量和变量之间的区别:
func majec(inout xValue:Int, var yValue:Int) {
xValue = 100
yValue = 200
}
var xValue = 33
var yValue = 33
majec(&xValue, yValue: yValue)
xValue //100
yValue //33
Run Code Online (Sandbox Code Playgroud)
Swift 语言中还有一个&符号的功能尚未提及。以下面的例子为例:
protocol Foo {}
protocol Bar {}
func myMethod(myVar: Foo & Bar) {
// Do something
}
Run Code Online (Sandbox Code Playgroud)
这里的&符号语法声明同时myVar
符合 Foo 和 Bar 协议。
作为另一个用例,请考虑以下事项:
func myMethod() -> UIViewController & UITableViewDataSource {
// Do something
}
Run Code Online (Sandbox Code Playgroud)
这里我们说该方法返回一个符合特定协议(UITableViewDataSource)的类实例(UIViewController)。这在 Swift 5.1 的Opaque Types 中显得有些过时,但您可能会不时在 Swift 5.1 之前的代码中看到这种语法。
正如其他答案中所述,您可以使用前缀&
将值传递给inout
方法或函数调用的参数,如《Swift 编程语言》中的Functions > Function Argument Labels and Parameter Names > In-OutParameters下所述。但事情还不止于此。
在实践中,您可以将 Swiftinout
参数和向它们传递值视为类似于 C 或 C++ 按地址传递或按引用传递。事实上,编译器会将参数的许多使用优化inout
为大致相同的机制(特别是当您调用处理指针的导入 C 或 ObjC API 时)。然而,这些只是语义层面上的优化 \xe2\x80\x94,inout
实际上并没有传递地址,这可以释放编译器,使这种语言构造更加灵活和强大。
例如,这里的结构使用通用策略来验证对其属性之一的访问:
\n\nstruct Point {\n private var _x: Int\n var x: Int {\n get {\n print("get x: \\(_x)")\n return _x\n }\n set {\n print("set x: \\(newValue)")\n _x = newValue\n }\n }\n // ... same for y ...\n init(x: Int, y: Int) { self._x = x; self._y = y }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n(在“真实”代码中, for 的 getter 和 setterx
可以执行诸如强制执行最小值/最大值之类的操作。或者x
可以执行其他计算属性技巧,例如在后台与 SQL 数据库对话。这里我们只对调用进行检测并获取/设置底层私有财产。)
x
现在,当我们传递一个参数时会发生什么inout
?
func plusOne(num: inout Int) {\n num += 1\n}\n\nvar pt = Point(x: 0, y: 1)\nplusOne(num: &pt.x)\n// prints:\n// get x: 0\n// set x: 1\n
Run Code Online (Sandbox Code Playgroud)\n\n因此,即使x
是计算属性,使用参数“通过引用”传递它的效果与您期望的(如果是存储属性或局部变量)inout
相同。x
这意味着您可以“通过引用”传递您在 C/C++/ObjC 中甚至无法考虑的各种内容。例如,考虑标准库swap
函数,它接受任意两个...“事物”并切换它们的值:
var a = 1, b = 2\nswap(&a, &b)\nprint(a, b) // -> 2 1\n\nvar dict = [ "Malcolm": "Captain", "Kaylee": "Mechanic" ]\nswap(&dict["Malcolm"], &dict["Kaylee"])\nprint(dict) // -> ["Kaylee": "Captain", "Malcolm": "Mechanic"], fanfic ahoy\n\nlet window1 = NSWindow()\nlet window2 = NSWindow()\nwindow1.title = "window 1"\nwindow2.title = "window 2"\nvar windows = [window1, window2]\nswap(&windows[0], &windows[1])\nprint(windows.map { $0.title }) // -> ["window 2", "window 1"]\n
Run Code Online (Sandbox Code Playgroud)\n\n这种inout
工作方式还可以让您做一些有趣的事情,例如+=
在嵌套调用链上使用运算符:
window.frame.origin.x += 10\n
Run Code Online (Sandbox Code Playgroud)\n\nCGRect
...这比仅仅分解一个具有不同坐标的新的要简单得多x
。
这种更细致的行为版本inout
,称为“按值结果调用”,以及它可以优化为 C 风格的“按地址传递”行为的方法,在《Swift 编程语言》中的声明 > 函数 > 输入输出参数中进行了介绍。 。
归档时间: |
|
查看次数: |
11914 次 |
最近记录: |