You write an in-out parameter by placing the inout keyword right before a parameter’s type. An in-out parameter has a value that is passed in to the function, is modified by the function, and is passed back out of the function to replace the original value.

https://docs.swift.org/swift-book/LanguageGuide/Functions.html

In-Out Parameters

In-out parameters are passed as follows:

  1. When the function is called, the value of the argument is copied.

  2. In the body of the function, the copy is modified.

  3. When the function returns, the copy’s value is assigned to the original argument.

This behavior is known as copy-in copy-out or call by value result. For example, when a computed property or a property with observers is passed as an in-out parameter, its getter is called as part of the function call and its setter is called as part of the function return.

As an optimization, when the argument is a value stored at a physical address in memory, the same memory location is used both inside and outside the function body. The optimized behavior is known as call by reference; it satisfies all of the requirements of the copy-in copy-out model while removing the overhead of copying. Write your code using the model given by copy-in copy-out, without depending on the call-by-reference optimization, so that it behaves correctly with or without the optimization.

Within a function, don’t access a value that was passed as an in-out argument, even if the original value is available in the current scope. Accessing the original is a simultaneous access of the value, which violates Swift’s memory exclusivity guarantee. For the same reason, you can’t pass the same value to multiple in-out parameters.

For more information about memory safety and memory exclusivity, see Memory Safety.

A closure or nested function that captures an in-out parameter must be nonescaping. If you need to capture an in-out parameter without mutating it or to observe changes made by other code, use a capture list to explicitly capture the parameter immutably.

  1. func someFunction(a: inout Int) -> () -> Int {
  2. return { [a] in return a + 1 }
  3. }

If you need to capture and mutate an in-out parameter, use an explicit local copy, such as in multithreaded code that ensures all mutation has finished before the function returns.

  1. func multithreadedFunction(queue: DispatchQueue, x: inout Int) {
  2. // Make a local copy and manually copy it back.
  3. var localX = x
  4. defer { x = localX }
  5. // Operate on localX asynchronously, then wait before returning.
  6. queue.async { someMutatingOperation(&localX) }
  7. queue.sync {}
  8. }

For more discussion and examples of in-out parameters, see In-Out Parameters.

In-Out Parameters

Function parameters are constants by default. Trying to change the value of a function parameter from within the body of that function results in a compile-time error. This means that you can’t change the value of a parameter by mistake. If you want a function to modify a parameter’s value, and you want those changes to persist after the function call has ended, define that parameter as an in-out parameter instead.

You write an in-out parameter by placing the inout keyword right before a parameter’s type. An in-out parameter has a value that is passed in to the function, is modified by the function, and is passed back out of the function to replace the original value. For a detailed discussion of the behavior of in-out parameters and associated compiler optimizations, see In-Out Parameters.

You can only pass a variable as the argument for an in-out parameter. You cannot pass a constant or a literal value as the argument, because constants and literals cannot be modified. You place an ampersand (&) directly before a variable’s name when you pass it as an argument to an in-out parameter, to indicate that it can be modified by the function.

NOTE

In-out parameters cannot have default values, and variadic parameters cannot be marked as inout.

Here’s an example of a function called swapTwoInts(_:_:), which has two in-out integer parameters called aand b:

  1. func swapTwoInts(_ a: inout Int, _ b: inout Int) {
  2. let temporaryA = a
  3. a = b
  4. b = temporaryA
  5. }

The swapTwoInts(_:_:) function simply swaps the value of b into a, and the value of a into b. The function performs this swap by storing the value of a in a temporary constant called temporaryA, assigning the value of b to a, and then assigning temporaryA to b.

You can call the swapTwoInts(_:_:) function with two variables of type Int to swap their values. Note that the names of someInt and anotherInt are prefixed with an ampersand when they are passed to the swapTwoInts(_:_:) function:

  1. var someInt = 3
  2. var anotherInt = 107
  3. swapTwoInts(&someInt, &anotherInt)
  4. print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
  5. // Prints "someInt is now 107, and anotherInt is now 3"

The example above shows that the original values of someInt and anotherInt are modified by the swapTwoInts(_:_:) function, even though they were originally defined outside of the function.

NOTE

In-out parameters are not the same as returning a value from a function. The swapTwoInts example above does not define a return type or return a value, but it still modifies the values of someInt and anotherInt. In-out parameters are an alternative way for a function to have an effect outside of the scope of its function body.

In-Out Parameters inout keyword的更多相关文章

  1. testng参数化及用例排序

    http://blog.sina.com.cn/s/blog_6966650401012ra0.html 一.一个简单的测试谷歌搜索 import org.testng.annotations.Tes ...

  2. 请求Url返回数据较大,使结果分页获取

    首先创建了一个单元测试,如下项目视图: 分页结果映射类PageResult的编写: using System; using System.Collections.Generic; using Syst ...

  3. MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.7 Adding a wms layer

    MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.7 Adding a wms layer 前言 Add OGC WMS Layers( ...

  4. skopt超参数优化实例

    import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import load_boston from skl ...

  5. WebDriver+TestNG的一个典型例子

    想让测试更加灵活,1. 可以配置使用任意支持的浏览器进行测试:2. 配置所有Google的URL:3. 配置搜索的关键字.修改后的代码: public class GoogleTest { WebDr ...

  6. swift的值类型和引用类型

    前言 最近在学设计模式中,发现 Swift 中的 struct,class 以及 enum 在一般的使用中能够做到互相替换,因此探究其背后的逻辑就十分有必要.而这一问题又引出了 Swift 中的值类型 ...

  7. MapServer教程2

    第二章 Tutorial 教程 MapServer Tutorial MapServer教程 Tutorial background 教程背景 Section 1: Static Maps and t ...

  8. Odoo Documentation : Environment

    Environment The Environment stores various contextual data(上下文数据 ) used by the ORM: the database cur ...

  9. Elixir's keyword lists as option parameters

    备注: 文章转自:https://www.djm.org.uk/posts/writing-extensible-elixir-with-behaviours-adapters-pluggable-b ...

随机推荐

  1. @dalao help!!!

  2. eclipse IED 创建springboot项目教程

    学习使我沉淀变成淀粉.-- 沃兹基硕德[美] 首先给你的 eclipse 安装插件 Help> Eclipse Marketplace uploading-image-736738.png 所搜 ...

  3. JavaScript基础的记录

    一.JavaScript的六种基本类型: 基本数据类型: String.Number.Boolean.Null.Undefined 引用数据类型: Object 二.强制类型转换: 主要指将其他的数据 ...

  4. lucene_09_solrj的使用

    什么是solrj solrj 是访问Solr 服务的java客户端,提供索引(增删改)和搜索(查)的请求方法,Solrj 通常在嵌入在业务系统中,通过Solrj的API接口操作Solr服务,如下图: ...

  5. Android 自己定义TextView 实现文本间距

    转载请标明出处: http://blog.csdn.net/u011974987/article/details/50845269: Android系统中TextView默认显示中文时会比較紧凑.不是 ...

  6. Android自己定义控件之轮播图控件

    背景 近期要做一个轮播图的效果.网上看了几篇文章.基本上都能找到实现,效果还挺不错,可是在写的时候感觉每次都要单独去又一次在Activity里写一堆代码.于是自己封装了一下.这里仅仅是做了下封装成一个 ...

  7. 学习 java netty (一) -- java nio

    前言:近期在研究java netty这个网络框架,第一篇先介绍java的nio. java nio在jdk1.4引入,事实上也算比較早的了.主要引入非堵塞io和io多路复用.内部基于reactor模式 ...

  8. Android常用的一些make命令【转】

    本文转载自:http://blog.csdn.net/liuxd3000/article/details/39181377 1.make -jX  X表示数字,这个命令将编译Android系统并生成镜 ...

  9. C Tricks(十七)—— 对角线元素的屏蔽、二维数组(矩阵)的遍历

    1. 对角线元素的屏蔽 使用 if + continue 实现对对角线元素的屏蔽 for u in range(n): for v in range(n): if u == v: continue . ...

  10. ClassLoader.getResourceAsStream(name);获取配置文件的方法

    ClassLoader.getResourceAsStream(name);路径问题 InputStream in = getClass().getResourceAsStream('/'+" ...