Swift 函数是按值还是按引用分配/传递?

Posted

技术标签:

【中文标题】Swift 函数是按值还是按引用分配/传递?【英文标题】:Are Swift functions assigned/passed by value or by reference? 【发布时间】:2015-11-28 06:21:42 【问题描述】:

当 Swift 中的函数被赋值给变量或作为嵌套函数从更高级别的函数返回时,它是通过值传递还是通过引用传递?当我写:

func foo() -> Bool

    return false


var funcVar = foo

funcVar 是否收到对foo() 的引用,或者是foo() 的副本创建并以“funcVar”名称存储在内存中?以下代码的相同问题:

func otherfoo() -> (Int) -> ()

    func bar(num :Int) 
    return bar


var funcVar = otherfoo()

第二个例子特别让我感到困惑,因为如果我调用funcVar(3),在函数通过引用分配/返回的情况下,我不应该能够访问bar,因为bar同时在另一个函数中funcVar 的范围,但它仍然有效(来自 C++ 背景,我只是对它编译感到惊讶)。 有人可以帮我解释一下这件事吗?

【问题讨论】:

【参考方案1】:

来自Apple documentation:

在上面的例子中,incrementBySeven 和 incrementByTen 是常量,但是这些常量引用的闭包仍然能够增加它们捕获的 runningTotal 变量。这是因为函数和闭包都是引用类型。

每当您将函数或闭包分配给常量或变量时,您实际上是将该常量或变量设置为对该函数或闭包的引用。

【讨论】:

抱歉,我没有想到要查看文档的 Closures 页面 - 我只阅读了 Functions 页面。无论如何,这解决了它:显然,在这种情况下,引用完全忽略了原始范围。谢谢!【参考方案2】:

首先,Swift 中的 everything 是按值赋值的,如果参数没有ref 而你没有,则 Swift 中的 everything 是按值传递不要使用& 传递它。 (如果参数有ref,而你使用&传递它,它就是通过引用传递。)无论类型如何,都是如此。

不清楚你在问什么。您可能会问函数是值类型(如结构)还是引用类型(如对对象的引用),这是一个不同的问题。答案是,因为 Swift 中的函数是不可变的(没有可以更改的函数的可变“内容”),所以在语义上无法区分它是值类型还是引用类型。无论哪种方式都没有区别。

第二个例子让我特别困惑,因为如果我打电话给 funcVar(3) 我不应该能够在 case 函数中访问 bar 通过引用分配/返回,因为 bar 在另一个内部 funcVar 范围内的函数

我不明白你在说什么。函数是一等公民。所以一旦你有了一个函数值,你就可以使用它,你可以传递它,你可以返回它,就像其他任何东西一样,并且任何获得这个函数的人都可以像使用任何其他函数一样使用它。函数值是被复制的值类型还是对引用计数对象的引用都没有区别。

【讨论】:

【参考方案3】:

函数是 swift 中的引用类型。通过代码示例进一步说明这一点。

func countAdder(_ word: String)-> () -> ()
var count = 0
func currentCount()
    count += 1
    print(count)

return currentCount

let countedWord = countAdder("Hello")
let countedWordTwo = countAdder("World")
countedWord() // count is 1
countedWordTwo() // count is  1
//Lets try this

let countedWord = countAdder("Hello")
let countedWordTwo = countedWord
countedWord() // count is  1
countedWordTwo() // now count is 2

我希望它足够清楚地解释这个概念。

【讨论】:

以上是关于Swift 函数是按值还是按引用分配/传递?的主要内容,如果未能解决你的问题,请参考以下文章

JS是按值传递还是按引用传递

JavaScript 是按引用传递还是按值传递? [复制]

.bind(this) 是按引用传递还是按值传递?

js传参是按值传递还是按引用传递?

JS基础类型和对象,分别是按值传递还是按引用传递?

java中的参数传递是按引用传递还是按值传递