En la sesión de Introducción a Swift WWDC, description
se demuestra una propiedad de solo lectura :
class Vehicle {
var numberOfWheels = 0
var description: String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description)
¿Hay alguna implicación en elegir el enfoque anterior en lugar de usar un método en su lugar?
class Vehicle {
var numberOfWheels = 0
func description() -> String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description())
Me parece que las razones más obvias por las que elegiría una propiedad calculada de solo lectura son:
- Semántica : en este ejemplo, tiene sentido
description
que sea una propiedad de la clase, en lugar de una acción que realiza. - Brevedad / Claridad : evita la necesidad de utilizar paréntesis vacíos al obtener el valor.
Claramente, el ejemplo anterior es demasiado simple, pero ¿hay otras buenas razones para elegir uno sobre el otro? Por ejemplo, ¿existen algunas características de las funciones o propiedades que guiarían su decisión de cuál usar?
NB A primera vista, esta parece una pregunta de OOP bastante común, pero estoy ansioso por conocer las características específicas de Swift que guiarían las mejores prácticas al usar este lenguaje.
methods
properties
semantics
swift
Stuart
fuente
fuente
get {}
? ¡No lo sabía, gracias!Respuestas:
Me parece que es principalmente una cuestión de estilo: prefiero usar propiedades solo para eso: propiedades; es decir, valores simples que puede obtener y / o establecer. Utilizo funciones (o métodos) cuando se realiza el trabajo real. Tal vez algo tenga que ser calculado o leído desde el disco o desde una base de datos: en este caso uso una función, incluso cuando solo se devuelve un valor simple. De esa manera puedo ver fácilmente si una llamada es barata (propiedades) o posiblemente costosa (funciones).
Probablemente obtendremos más claridad cuando Apple publique algunas convenciones de codificación Swift.
fuente
Bueno, puede aplicar los consejos de Kotlin https://kotlinlang.org/docs/reference/coding-conventions.html#functions-vs-properties .
fuente
Si bien la cuestión de las propiedades calculadas frente a los métodos en general es difícil y subjetiva, actualmente existe un argumento importante en el caso de Swift para preferir los métodos a las propiedades. Puede usar métodos en Swift como funciones puras, lo que no es cierto para las propiedades (a partir de Swift 2.0 beta). Esto hace que los métodos sean mucho más poderosos y útiles, ya que pueden participar en la composición funcional.
fuente
Dado que el tiempo de ejecución es el mismo, esta pregunta también se aplica a Objective-C. Yo diría que con las propiedades que obtienes
readwrite
didSet
para notificaciones de cambiosEn cuanto a algo específico de Swift, el único ejemplo que tengo es que se puede utilizar
@lazy
para una propiedad.fuente
Hay una diferencia: si usa una propiedad, eventualmente puede anularla y hacerla leer / escribir en una subclase.
fuente
willSet
ydidSet
a la clase base , sin saber nada de futuras clases derivadas, puede detectar cambios en la propiedad invalidada. Pero no se puede hacer nada parecido con las funciones, creo.En el caso de solo lectura, una propiedad calculada no debe considerarse semánticamente equivalente a un método, incluso cuando se comportan de manera idéntica, porque eliminar la
func
declaración desdibuja la distinción entre cantidades que comprenden el estado de una instancia y cantidades que son meras funciones de la estado. Ahorra escribir()
en el sitio de la llamada, pero corre el riesgo de perder claridad en su código.Como ejemplo trivial, considere el siguiente tipo de vector:
Al declarar la longitud como método, queda claro que es una función del estado, que depende solo de
x
yy
.Por otro lado, si tuvieras que expresar
length
como una propiedad calculadaa continuación, cuando Dot-tab-completo en su IDE en una instancia de
VectorWithLengthAsProperty
, se vería como six
,y
,length
eran propiedades en pie de igualdad, que es conceptualmente incorrecto.fuente
Hay situaciones en las que preferiría la propiedad calculada sobre las funciones normales. Por ejemplo: devolver el nombre completo de una persona. Ya sabes el nombre y el apellido. Entonces, realmente la
fullName
propiedad es una propiedad, no una función. En este caso, se trata de una propiedad calculada (debido a que no puede establecer el nombre completo, simplemente puede extraerlo usando el nombre y el apellido)fuente
Desde la perspectiva del desempeño, no parece haber diferencia. Como puede ver en el resultado del benchmark.
esencia
main.swift
fragmento de código:Salida:
prop: 0.0380070209503174 func: 0.0350250005722046 prop: 0.371925950050354 func: 0.363085985183716 prop: 3.4023300409317 func: 3.38373708724976 prop: 33.5842199325562 func: 34.8433820009232 Program ended with exit code: 0
En la tabla:
fuente
Date()
no es adecuado para evaluaciones comparativas, ya que utiliza el reloj de la computadora, que está sujeto a actualizaciones automáticas por parte del sistema operativo.mach_absolute_time
obtendría resultados más fiables.Hablando semánticamente, las propiedades calculadas deben estar estrechamente acopladas con el estado intrínseco del objeto; si otras propiedades no cambian, la consulta de la propiedad calculada en diferentes momentos debería dar el mismo resultado (comparable a través de == o ===) - similar para llamar a una función pura en ese objeto.
Los métodos, por otro lado, salen de la caja con la suposición de que es posible que no siempre obtengamos los mismos resultados, porque Swift no tiene una forma de marcar funciones como puras. Además, los métodos en OOP se consideran acciones, lo que significa que ejecutarlos puede provocar efectos secundarios. Si el método no tiene efectos secundarios, se puede convertir de forma segura en una propiedad calculada.
Tenga en cuenta que las dos declaraciones anteriores son puramente desde una perspectiva semántica, ya que bien podría suceder que las propiedades calculadas tengan efectos secundarios que no esperamos y que los métodos sean puros.
fuente
Históricamente, la descripción es una propiedad de NSObject y muchos esperarían que continúe igual en Swift. Agregar paréntesis después solo agregará confusión.
EDITAR: Después de una furiosa votación negativa, tengo que aclarar algo: si se accede a él a través de la sintaxis de puntos, se puede considerar una propiedad. No importa lo que haya debajo del capó. No puede acceder a los métodos habituales con sintaxis de puntos.
Además, llamar a esta propiedad no requería parens adicionales, como en el caso de Swift, lo que puede generar confusión.
fuente
description
es un método requerido en elNSObject
protocolo, por lo que en el objetivo-C se devuelve usando[myObject description]
. De todos modos, la propiedaddescription
fue simplemente un ejemplo artificial: estoy buscando una respuesta más genérica que se aplique a cualquier propiedad / función personalizada.