Swift函数是通过值传递还是引用传递?

6

当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++背景,我只是惊讶它编译通过)。 请问有人能为我解释一下这个问题吗?

3个回答

8
根据Apple文档所述:
在上面的示例中,incrementBySeven和incrementByTen是常量,但这些常量引用的闭包仍然可以增加它们已捕获的runningTotal变量。这是因为函数和闭包都是引用类型。
每当您将一个函数或闭包分配给常量或变量时,实际上是将该常量或变量设置为对该函数或闭包的引用。

抱歉,我没有想到查看文档中的闭包页面 - 我只读了函数页面。无论如何,这解决了问题:显然,在这种情况下,引用完全忽略了原始作用域。谢谢! - MustangXY

1

函数在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

我希望这足够清晰,可以解释这个概念。


0
首先,Swift 中的所有内容都是按值分配的,如果参数没有 ref 并且您不使用 & 传递它,则 Swift 中的所有内容都是按值传递的。 (如果参数具有 ref 并且您使用 & 传递它,则它是按引用传递的。)这对于任何类型都是正确的。
您的问题不太清楚。您可能会问函数是值类型(如结构体)还是引用类型(如对象引用),这是一个不同的问题。答案是,因为 Swift 中的函数是不可变的(没有可变的函数“内容”可以更改),所以无论它是值类型还是引用类型,在语义上都是无法区分的。两种方式都没有区别。
“第二个例子特别让我困惑,因为如果我调用 funcVar(3),则在函数被分配/返回引用的情况下,我不应该能够访问 bar,因为 bar 在与 funcVar 相同的作用域内的另一个函数中。”

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接