Swift中的ios – didSet对突变功能有一个奇怪的敲击效应

前端之家收集整理的这篇文章主要介绍了Swift中的ios – didSet对突变功能有一个奇怪的敲击效应前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我刚刚了解到,mutation只是一个curried func,第一个参数为inout,所以下面的代码将工作并将firstName更改为“John”
  1. struct Person {
  2. var firstName = "Matt"
  3.  
  4. mutating func changeName(fn: String) {
  5. firstName = fn
  6. }
  7. }
  8. var p = Person()
  9. let changer = Person.changeName
  10. changer(&p)("John")
  11. p.firstName

但是奇怪的事情发生在我添加属性观察者p如下,你可以看到firstName还是“马特”,为什么?

一个有趣的注意事项是,观察者在召集公民之前被召唤:
  1. struct Person {
  2. var firstName = "Matt"
  3.  
  4. mutating func changeName(fn: String) {
  5. firstName = fn
  6. }
  7. }
  8.  
  9. var p: Person = Person() {
  10. didSet {
  11. print("p was set")
  12. }
  13. }
  14.  
  15. print("1: \(p.firstName)")
  16. let changer = Person.changeName
  17. print("2: \(p.firstName)")
  18. let setter = changer(&p)
  19. print("3: \(p.firstName)")
  20. setter("John")
  21. print("4: \(p.firstName)")
  22. p.changeName("John")
  23. print("5: \(p.firstName)")

打印:

  1. 1: Matt
  2. 2: Matt
  3. p was set
  4. 3: Matt
  5. 4: Matt
  6. p was set
  7. 5: John

所以似乎在inout结构体中获取setter方法会执行实际的突变。这通过inout参数如何在语义上工作来解释:当参数传递给函数时,它的值被复制到函数可以突变的地方。当函数返回时,该值将被复制回原始位置,触发setter观察者一次,该值是否改变。

当我们改变方式让预先填充的咖喱设定者:

  1. let setter = p.changeName

…编译器对象:

  1. error: partial application of 'mutating' method is not allowed

看来,编译器了解到关闭inout值是一个坏主意,因为它基本上是对值类型进行引用。

闭包可以随时更改struct的值,即使编译器假定它是不变的。为了防止这种不幸的情况,编译器只是禁止关闭inout。

您发现一个愚弄编译器并围绕诊断工作的情况。这似乎是一个错误,应该提交。

简短版本:

  1. struct Foo {
  2. mutating func foo() {}
  3. }
  4.  
  5. var f = Foo()
  6. let m = Foo.foo
  7. let s = m(&f)

最后两行之一应该发出一个错误,类似于让x = f.foo。

猜你在找的Swift相关文章