inout 参数的用法(In-Out Parameters)

详细介绍下inout 参数的用法等,主要是对查看的官方文档的翻译及自己对相关知识点的理解的记录,怕以后忘记了😜
原文链接

以前在有些东西不清楚的时候也看过一些官方的文档,但是看过之后不久就忘记了,有想法想一点点的将以前看过的及以后看的官方文档都翻译过来记录一下,希望手不懒,能够实行下去🙏


In-Out Parameters 01

方法的参数默认是不可变(constants)类型(刚刚学习swift的时候还真的没注意这个)。在方法的内部视图去改变参数的值是会导致编译错误的(确实会报错,大家可以自己试一下)。

func changeStr(a: String, b: String) -> String {
        a = "asd"
        return a
    }

如果想要在方法的内部去改变参数的值,并且想要在方法执行结束后仍然保持这个改变,那么可以用一个 in-out 参数替代原来的参数。
声明一个in-out参数的方法是放一个 inout 关键字在参数类型的前面。in-out参数会持有那个传递到方法内部的参数,当这个参数在方法内部被改变后,会将这个值传递出去替换原来的值。
你只能传递一个变量作为in-out参数(如果是let型则会报错)。你不能传递一个不可变(constant)的或者字面值作为参数,因为不可变量或者字面值是不能被更改的。当你将一个变量的名字作为in-out参数传递的时候,应该在这个变量名字前面加上&符号,以此用来表示这个变量的值可以被这个方法改变。

注意:in-out参数不能有默认值,同时可变参数也不能标记为in-out.

来看下面的例子,一个叫swapTwoInts(::)方法,他有两个in-out int型的参数 a 和 b:

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
  let tempA = a
  a = b
  b = tempA
}

swapTwoInts(::)方法只是简单的交换值,将b值分配给a,将a原来的值分配给b。这个方法的交换过程是将a的值存储在一个叫tempA的常量中,然后将b的值分配给a,在将tempA的值分配给b。
现在你可以通过调用swapTwoInts(::)方法,去改变两个作为参数的变量的。注意下面如果你想将someInt和anotherInt作为参数去,调用swapTwoInts(::)方法的时候,在参数的前面是有&前缀的

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
//现在 someInt = 107   anotherInt = 3

上面的例子展示了即使在swapTwoInts(::)方法外面定义的两个变量someInt 和 anotherInt,也能通过该方法去改变他们原有的值。

注意:in-out 参数和方法的返回值是不一样的。上面例子中的方法没有定义任何的返回值或者返回类型,但是依然可以改变方法外面的变量的值。in-out参数是方法对方法体外部产生影响的一种方式。

In-Out Parameters 02

In-out参数按照下面的过程被传递:

  • 1 当方法被调用的时候,参数的值被拷贝
  • 2 在方法体内部,被改变的是拷贝的值
  • 3 当方法结束后,拷贝的值重新分配给原来的参数
    这种行为就像考入,考出一样或者称为结果值调用。举个例子,当一个计算属性或者一个具有属性观察器的属性作为一个in-out参数被传递时,当方法被调用的时候,它的getter方法会被调用,当方法返回的时候,它的setter方法会被调用。
    作为一种优化手段,当参数值被存储在内存物理地址中时,在方法内部和外部会用同一个内存位置。这种优化手段叫做引用调用。它满足了拷入拷出模式的所有要求,且消除了复制带来的开销。在代码中,要规范使用拷入拷出模式,不要依赖于引用调用。

不要使用传递给in-out参数的值,即使原始值在当前作用域中依然可用。当函数返回时,你对原始值所做的更改会被拷贝的值所覆盖。不要依赖于引用调用的优化机制来试图避免这种覆盖。

你不能将同一个值传递给不同的in-out参数,因为不好确定将哪一个拷贝值回写,因策原来的最终值㛑不好确定。

var x = 10
func f(a: inout Int, b: inout Int) {
    a += 1
    b += 1
}
f(a: &x, b: &x)  //提示错误:Inout arguments are not allowed to alias each other

闭包或者嵌套函数中捕获的in-out参数一定是非逃逸的(nonescaping)。如果你需要捕获in-out参数而不去改变他的值,请使用捕获列表来显示的捕获参数

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

如果需要捕获和突变输入参数,请使用显式本地拷贝副本,例如多线程代码,以确保在函数返回之前已完成所有突变。

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

defer语句:特点是,当当前作用域代码执行结束后,要退出当前作用域时去执行defer块内的代码,同时如果有多个defer分代码块同时被定义,他将按照defer代码块定义的顺序反向执行
defer原文

希望我的文章对你有帮助,努力,坚持,与君共勉。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,631评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,657评论 18 139
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,233评论 0 4
  • Hello Word 在屏幕上打印“Hello, world”,可以用一行代码实现: 你不需要为了输入输出或者字符...
    restkuan阅读 3,176评论 0 6
  • “幸福如人饮水,冷暖自知”,这是我对幸福的认知的最初理解。 我一直觉得关于幸福这个词的定义应该是主观的、开放的,而...
    小乐心阅读 766评论 6 8