代码之家  ›  专栏  ›  技术社区  ›  Nilanshu Jaiswal

函数在Swift中是值类型还是引用类型?为什么?

  •  2
  • Nilanshu Jaiswal  · 技术社区  · 7 年前

    考虑这个功能:

    func addTwoInts(_ a: Int, _ b: Int) -> Int {
        return a + b
    }
    

    这里我将这个函数赋值给另一个变量

    var mathFunction: (Int, Int) -> Int = addTwoInts
    

    addTwoInts 是值类型还是引用类型?为什么?

    2 回复  |  直到 7 年前
        1
  •  13
  •   Hamish    7 年前

    我认为函数类型最适合 the definition of a reference type :

    引用类型在指定给变量或常量或传递给函数时不会被复制。使用对同一现有实例的引用而不是副本。

    然而,我不认为这是一个特别有用的区别,在我看来,将函数作为值类型(如 technically speaking they consist of a pointer and a reference

    更有用的区别是函数具有 引用语义 ,这意味着可以观察实例之间的某种共享状态。这与引用类型不同,值类型可能具有引用语义,而引用类型可能具有值语义。

    例如,这里有一个具有引用语义的值类型:

    var foo = 0
    struct S {
      var bar: Int {
        get { return foo }
        nonmutating set { foo = newValue }
      }
    }
    
    let s = S()
    let s1 = s
    s.bar += 1
    print(s.bar)  // 1
    print(s1.bar) // 1
    

    二者都 s 和 s1

    final class C {
      let foo = 0
    }
    
    let c = C()
    let c1 = c
    print(c.foo)  // 0
    print(c1.foo) // 0
    

    虽然两者都有 c 和 c1

    那么,为什么函数有引用语义呢?因为它们可以包含捕获的变量,这是可以观察到的共享可变状态。

    例如:

    func makeFn() -> () -> Int {
      var foo = 0
      return {
        foo += 1
        return foo
      }
    }
    
    let fn = makeFn()
    let fn1 = fn
    print(fn())  // 1
    print(fn1()) // 2
    
        2
  •  20
  •   CPR    7 年前

    闭包和函数是引用类型。这在Swift语言文件中有说明: Closures

        3
  •  3
  •   zeytin    5 年前

    闭包和函数是引用类型

    苹果说:每当你给一个常量或变量赋值一个函数或闭包, 实际上,您正在将该常量或变量设置为对函数或闭包的引用。

    让我们试试看这个例子:

    首先,我将创建一个函数,该函数以整数作为参数,返回一个名为 makeIncrementer

    func makeIncrementer(forIncrement amount: Int) -> () -> Int {
        var runningTotal = 0
        func incrementer() -> Int {
            runningTotal += amount
            return runningTotal
        }
        
        return incrementer
    }
    

    现在incrementByTen将引用这个函数的结果,换句话说,引用一个闭包

    let incrementByTen = makeIncrementer(forIncrement: 10)
    
    incrementByTen()
    // returns a value of 10
    

    结果是10还是20? 是的,你说到点子上了:)会的。因为 闭包和函数是引用类型 正如我一开始说的。

    incrementByTen()
    // returns a value of 20
    incrementByTen()
    // returns a value of 30 with same approach as i explained.