¿Es posible implementar una relatioship bidireccional entre dos estructuras usando solo properties constantes?

Mi caso de uso se basa en el siguiente model:

struct Person { let name: String let houses: [House] } struct House { let owner: Person } 

Ahora, idealmente, me gustaría mantener una relación bidireccional que requiera que cada casa tenga exactamente un propietario donde un propietario también debería conocer todas sus casas.

Usando las estructuras de datos anteriores, ¿es posible crear instancias de House y Person tal manera que exista una relación entre los dos y que los objects se señalen esencialmente entre sí?

Supongo que la fraseología de esto ya es algo engañosa, porque debido a la semántica de valor de las struct , en realidad no apuntan a ninguna parte, sino que solo contienen copys de valores. Parece que debería ser obvio que no es posible crear estos dos objects con una relación bidireccional, ¡pero todavía quería estar seguro y hacer estas preguntas aquí!

Una solución obvia también sería hacer que las houses y las variables de owner usen var lugar de let cuando las declaran, entonces la relación podría mantenerse en el inicializador de cada struct :

 struct Person { let name: String var houses: [House] init(name: String, houses: [House]) { self.name = name self.houses = houses self.houses = houses.map { (house: House) in var newHouse = house newHouse.owner = self return newHouse } } } struct House { var owner: Person init(owner: Person) { self.owner = owner var newHouses = self.owner.houses newHouses.append(self) self.owner = Person(name: owner.name, houses: newHouses) } } 

Sin embargo, ¿qué pasa si quiero mantener constantes las houses y el owner ? Como dije, parece obvio que no es posible, pero me pregunto si hay alguna forma elegante (quizás funcional) para lograr esto. Estaba pensando en lentes , que pueden usarse como captadores y creadores cuando se trata de models inmutables.

Lo que está describiendo suena más como un ORM que una function de idioma, y ​​tampoco suena apropiado para manejar types de valor como estructuras. ¿Cómo espera que el idioma sepa que el owner es la propiedad de relación inversa de las houses y necesita mantenerse en consecuencia? Esto es algo que debe implementarse con el código no es posible solo con el lenguaje Swift.

Parece que está tratando de mantener algún tipo de gráfico de object model, que es un problema que se resolvió muchas veces. Debería echar un vistazo a Realm DB y Core Data, los cuales ofrecen relaciones bidireccionales administradas. Sin embargo, encontrará que ninguno de estos se implementa con estructuras. El problema con el uso de los types de valor es que son de copy en escritura. Tan pronto como mutes una estructura en el gráfico de object, deberías reasignar todos sus elementos relacionados a la nueva copy mutada, que a su vez están mutados y tendrían que actualizar todas sus estructuras relacionadas. La semántica de reference (classs) hace que el mantenimiento de un gráfico de objects sea mucho más fácil ya que las mutaciones no producen nuevas instancias.

Lo que quieres no es posible usando estructuras. Su solución actual (con var ) no funciona como cree que lo hace: todos los valores son copys independientes. Considere el siguiente ejemplo:

 let p = Person(name: "Nick", houses: []) let h = House(owner: p) h.owner.houses p.houses 

Debido a que cada copy es independiente, esto significa que p no es lo mismo que h.owner .

Si necesita una relación bidireccional, debe usar objects con pointers weak (para romper el ciclo de reference). Alternativamente, podría pensar para ver si necesita la relación bidireccional.