Swift: Structs that refer to eac

2019-04-17  本文已影响0人  KAKA_move

Value type 'xxx' cannot have a stored property that references itself“
这段代码编译器通过不了,原因是结构体的空间在编译期间要求是确定的,解决办法之一是提供中间层

struct DetailedPin {
     var pin: Pin?
}

struct Pin {
    var detailedPin: DetailedPin?  
}

中间层:

/// Provides indirection for a given instance.
/// For value types, value semantics are preserved.
struct Indirect<T> {

  // Class wrapper to provide the actual indirection.
  private final class Wrapper {

    var value: T

    init(_ value: T) {
      self.value = value
    }
  }

  private var wrapper: Wrapper

  init(_ value: T) {
    wrapper = Wrapper(value)
  }

  var value: T {
    get {
      return wrapper.value
    }
    set {
      // Upon mutation of value, if the wrapper class instance is unique,
      // mutate the underlying value directly.
      // Otherwise, create a new instance.
      if isKnownUniquelyReferenced(&wrapper) {
        wrapper.value = newValue
      } else {
        wrapper = Wrapper(newValue)
      }
    }
  }
}

使用:在结构体的至少一端的属性用中间层包装。

struct DetailedPin {
  private var _pin = Indirect<Pin?>(nil)

  // Convenience computed property to avoid having to say ".value" everywhere.
  var pin: Pin? {
    get { return _pin.value }
    set { _pin.value = newValue }
  }
}

struct Pin {
  var detailedPin: DetailedPin?
  var foo: String
}

var d = DetailedPin()
var p = Pin(detailedPin: d, foo: "foo")
d.pin = p

// testing that value semantics are preserved...
var d1 = d
d1.pin?.foo = "bar"

print(d.pin?.foo as Any) // Optional("foo")
print(d1.pin?.foo as Any) // Optional("bar")
上一篇下一篇

猜你喜欢

热点阅读