Domina cómo y cuándo usar propiedades computadas de solo lectura en Swift. Verás por qué un valor derivado no debe modificarse directamente, cómo declarar el getter implícito y un ejemplo práctico: el volumen de un cuboide. Además, se aclara su uso tanto en structs como en classes y se propone un ejercicio aplicado.
¿Qué es una computed property de solo lectura en Swift?
Una variable es de solo lectura cuando no tiene setter y solo tiene getter. Es decir, su valor se calcula a partir de otros datos y no se puede asignar desde fuera. Esto evita inconsistencias: si alguien cambiara el volumen, no habría forma clara de saber cómo ajustar anchura, altura o profundidad.
Valor derivado: se calcula con otros campos internos.
Sin setter: no admite asignaciones externas.
Coherencia de datos: impide cambios ambiguos.
¿Cómo se declara un getter implícito en Swift?
Swift permite omitir la palabra clave get en una computed property de solo lectura. El cuerpo entre llaves define la expresión calculada.
Sintaxis concisa: var propiedad: Tipo { expresión }.
Claro y seguro: comunica que no hay setter.
¿Qué pasa si intentas modificar una read-only property?
Si intentas asignar un nuevo valor, Swift marca error: no se puede asignar una propiedad de solo lectura. El valor solo se consulta, no se modifica.
¿Cómo calcular el volumen de un cuboide con una computed property?
Se define un cuboide con anchura, altura y profundidad. El volumen es el producto de esas tres magnitudes. Aquí, lo correcto es exponerlo como propiedad computada de solo lectura.
structCuboid{var width:Double=0.0var height:Double=0.0var depth:Double=0.0// Computed property de solo lecturavar volume:Double{ width * height * depth
}}let cuboid =Cuboid(width:4, height:5, depth:2)let v = cuboid.volume // 40// cuboid.volume = 57 // Error: propiedad de solo lectura.
width, height, depth: propiedades almacenadas que se pueden editar.
volume: propiedad computada sin setter, solo obtiene el valor.
Intento de asignación: produce error por ser de solo lectura.
¿Por qué el volumen no aparece como editable?
Al inspeccionar la instancia ves las propiedades almacenadas (anchura, altura, profundidad). El volumen solo se expone para consulta, no como campo asignable. Esto refuerza la idea de valor derivado.
¿Se usan en structs y en classes en Swift?
Sí. Aunque el ejemplo se mostró con struct, las propiedades computadas, las propiedades almacenadas y las propiedades perezosas también aplican a las classes. No te limites mentalmente a las estructuras: el patrón sirve en ambos tipos.
API clara: evita exponer asignaciones incoherentes.
¿Cómo practicar con un saludo dinámico?
Se sugiere crear una estructura con género, idioma y nombre. La computed property construye el saludo según esos datos, por ejemplo, diciendo "Hola", "Hello" o "Bonjour" y añadiendo el nombre.
structSaludo{var genero:String// "femenino" o "masculino"var idioma:String// "es", "en", "fr"var nombre:Stringvar saludo:String{let base:Stringswitch idioma {case"es": base ="Hola"case"en": base ="Hello"case"fr": base ="Bonjour"default: base ="Hola"}return"\(base), \(nombre)"}}
Combina datos: idioma y nombre generan el mensaje.
Evita setter: el saludo se deriva del estado.
Extensible: puedes ajustar reglas por género cuando lo necesites.
¿Tienes otra idea de computed property útil en tu código? Comparte tu propuesta y cómo la implementarías.
struct Person{varfirstName:StringvarlastName:Stringvarname:String{ firstName +" "+ lastName
}}var persona =Person(firstName:"Luis",lastName:"Rangel")print(persona.name)
Yo hice esto.
Hice una estructura de una persona. Tiene como propiedades: nombre, idioma que habla, genero, saludo, y una presentación
struct Person{varname:Stringvargender:Gendervarlanguage:Stringvargreeting:String{switch language {case"french":return"bonjour"case"spanish":return"hola"case"english":return"hello"default:return"I'm sorry, y can't greeting you"}}varpresentation:String{var title =""if gender ==Gender.man{ title ="Mr. "}else{title ="Mrs. "}return title + name +" says "+ greeting
}}varBradley=Person(name:"Bradley",gender:Gender.man,language:"french")
struct Greeting{var lenguage =String()var gender =String()var name =String()varmenssage:String{return initialGreeting + name
}varinitialGreeting:String{switch lenguage{case"spanish":let aux ="Hola "if gender =="Female"{return aux +"Señora "}return aux +"Señor "case"english":let aux ="Hello "if gender =="Female"{return aux +"Lady "}return aux +"Gentleman "case"French":let aux ="Bonjour"if gender =="Female"{return aux +"Madame "}return aux +"Monsieur "default:return"Hi "}}}let greeting =Greeting(lenguage:"english",gender:"male",name:"Omar")greeting.menssage
enumGender{case masculino, femenino
}enumLanguage{case spanish, english
}struct Saludo{varname:Stringvargender:Gendervarlanguage:Languagevarsaludar:String{if self.language==Language.spanish{if self.gender==Gender.masculino{return("Hey \(self.name) Tas Fuerte we")}else{return("Hola \(self.name) Te ves bien")}}if self.language==Language.english{if self.gender==Gender.masculino{return("Hey \(self.name) You looks Strong man")}else{return("Hello \(self.name) You looks cute")}}else{return("No language defined")}}}let saludo =Saludo(name:"Carlos",gender:Gender.femenino,language:Language.english)saludo.saludar
Las Computed Properties de sólo lectura en Swift son propiedades que calculan su valor a partir de otras propiedades, pero no permiten ser modificadas directamente. Esto es útil para garantizar la integridad de los datos.
El ejemplo que hice fue una bascula.
Calcula el precio total de la compra de un vegetal dependiendo de las libras que lleves del mismo.
Por otra parte, también permite calcular cuantas libras del vegetal puedes llevar por cierta cantidad de dinero.
struct Persona{varname:StringvarlastName:StringvaryearOfBirth:Int}struct edad{varpersona:Personavaredad:Int{return2022- persona.yearOfBirth}}letAndy=edad(persona:Persona(name:"andy",lastName:"Paz",yearOfBirth:2000))letLuis=edad(persona:Persona(name:"Luis",lastName:"Paz",yearOfBirth:2002))letDavid=edad(persona:Persona(name:"David",lastName:"Flowrez",yearOfBirth:2015))print("Hola \(Andy.persona.name) \(Andy.persona.lastName) tu edad actual es: \(Andy.edad)")print("Hola \(Luis.persona.name) \(Luis.persona.lastName) tu edad actual es: \(Luis.edad)")print("Hola \(David.persona.name) \(David.persona.lastName) tu edad actual es: \(David.edad)")
enumGender{case masculino
case femenino
case na
}enumLenguague{caseENcaseES}enumLocalizedStrings{staticletwelcomeMessage:[Lenguague:[Gender:String]]=[.ES:[.masculino:"Bienvenido",.femenino:"Bienvenida",.na:"Hola",],.EN:[.masculino:"Welcome",.femenino:"Welcome",.na:"Welcome",]]}struct Saludo{varname:Stringvarlenguague:Lenguaguevargender:Gendervarsaludar:String{ get{let prefijo =LocalizedStrings.welcomeMessage[lenguague]?[gender]??"Hola"return"\(prefijo) \(name)"}}}print(Saludo(name:"kevin",lenguague:.EN,gender:.masculino).saludar)
Acá mi ejercicio
//Ejercicio persona que saludaenumLanguage{case japanese
case inglés
case español
}enumGender{case masculino
case femenino
}struct Person{varname:String}classGreetings{privatevarlanguaje:Languageprivatevargender:Genderprivatevarperson:Personprivatevargreeting:String{ get {switch self.languaje{case.japanese:if(isFemale(gender:self.gender)){return"Konichiwa \(self.person.name) san"}else{return"Konichiwa \(self.person.name) kun"}case.inglés:if(isFemale(gender:self.gender)){return"Hello lady \(self.person.name)"}else{return"Hello Sr. \(self.person.name)"}case.español:if(isFemale(gender:self.gender)){return"Hola señorita \(self.person.name)"}else{return"Hola joven \(self.person.name)"}}}}publicinit(languaje:Language,gender:Gender,person:Person){ self.languaje= languaje
self.gender= gender
self.person= person
}public func greetingPerson()->String{return self.greeting}private func isFemale(gender:Gender)->Bool{switch gender {case.femenino:returntruedefault:returnfalse}}}var madai =Greetings(languaje:.español,gender:.femenino,person:Person(name:"Claudia Madai"))print(madai.greetingPerson())