Swift:闭包如何捕获值类型的变量?

jon*_*531 6 struct closures value-type swift

看看下面的代码片段

struct Person{
  var name: String
  let surname: String
  var closure: (()->())?
   init(name: String, surname: String){
      self.name = name
      self.surname = surname
    
   }
}

var person = Person(name: "John",  surname: "Lennon")
let cl = {
   print(person.name)
}

person.name = "Bill"
cl()
print(person.name)
Run Code Online (Sandbox Code Playgroud)

上面代码片段的输出是

Bill
Bill
Run Code Online (Sandbox Code Playgroud)

有人可以解释这是如何发生的吗?我认为,由于闭包是引用类型并且Person是值类型,因此当创建闭包时,它会获得自己的副本Person(因为值类型是在传递时复制的),因此修改外部Person不应影响Person闭包捕获的内容,但它似乎这样不行。我是 swift 和 value 类型的新手,所以请不要太严格地判断我的问题。
谢谢
PS 我知道我们可以使用捕获列表显式捕获值变量,在这种情况下修改外部变量不会影响捕获的变量。问题与此无关。问题在于我认为即使没有显式捕获它也应该具有相同的方式

Dáv*_*tor 8

仅当您将变量显式传递给闭包时,您期望的行为才会起作用,如下所示:

var person = Person(name: "John",  surname: "Lennon")
let cl: (Person) -> () = { person in
    print(person.name)
}
cl(person)
person.name = "Bill"
cl(person)
Run Code Online (Sandbox Code Playgroud)

当您在闭包中隐式捕获变量时,该变量始终通过引用传递。如果要按值捕获变量,则需要显式传入它们。