Skip to content

Instantly share code, notes, and snippets.

@nikitamounier
Created May 9, 2021 12:16
Show Gist options
  • Save nikitamounier/e325b88f40d10960b85ebc76db5be5ee to your computer and use it in GitHub Desktop.
Save nikitamounier/e325b88f40d10960b85ebc76db5be5ee to your computer and use it in GitHub Desktop.
/// Property wrapper to introduce indirection into your property.
///
/// Indirection is very useful to introduce recursion into `structs`, which don't usually support it. This is very similar to using the `indirect` modifier on enum cases.
///
/// struct Person: Identifiable {
/// let id = UUID()
///
/// @Indirect var father: Person?
/// @Indirect var mother: Person?
/// }
@propertyWrapper
enum Indirect<Value> {
indirect case value(Value)
var wrappedValue: Value {
get {
guard case .value(let value) = self else { fatalError("Can't reach indirect value") }
return value
}
set {
self = .value(newValue)
}
}
init(wrappedValue: Value) {
self = .value(wrappedValue)
}
}
import Foundation
struct Person: Identifiable {
let id = UUID()
@Indirect var mother: Person?
@Indirect var father: Person?
}
let person1: Person = .init(mother: Person(mother: Person(mother: nil, father: nil), father: nil), father: Person(mother: nil, father: Person(mother: Person(mother: nil, father: nil), father: nil)))
dump(person1)
// person1
// mother
// mother
// nil
// nil
// nil
// father
// nil
// father
// mother
// nil
// nil
// nil
person1.father = nil // Cannot assign to property: 'person1' is a 'let' constant -> advantage of using structs over classes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment