Na sessão de introdução ao Swift WWDC, uma propriedade somente leitura description
é demonstrada:
class Vehicle {
var numberOfWheels = 0
var description: String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description)
Existem implicações em escolher a abordagem acima em vez de usar um método:
class Vehicle {
var numberOfWheels = 0
func description() -> String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description())
Parece-me que os motivos mais óbvios para você escolher uma propriedade computada somente leitura são:
- Semântica - neste exemplo, faz sentido
description
ser uma propriedade da classe, ao invés de uma ação que ela executa. - Brevidade / Clareza - evita a necessidade de usar parênteses vazios ao obter o valor.
Obviamente, o exemplo acima é muito simples, mas existem outras boas razões para escolher um em vez do outro? Por exemplo, existem alguns recursos de funções ou propriedades que orientariam sua decisão de qual usar?
NB À primeira vista, esta parece ser uma pergunta OOP bastante comum, mas estou ansioso para saber de quaisquer recursos específicos do Swift que orientariam as melhores práticas ao usar esta linguagem.
methods
properties
semantics
swift
Stuart
fonte
fonte
get {}
? Eu não sabia disso, obrigado!Respostas:
Parece-me que é principalmente uma questão de estilo: prefiro fortemente usar propriedades apenas para isso: propriedades; significando valores simples que você pode obter e / ou definir. Eu uso funções (ou métodos) quando o trabalho real está sendo feito. Talvez algo precise ser calculado ou lido do disco ou de um banco de dados: neste caso, eu uso uma função, mesmo quando apenas um valor simples é retornado. Assim posso ver facilmente se uma chamada é barata (propriedades) ou possivelmente cara (funções).
Provavelmente obteremos mais clareza quando a Apple publicar algumas convenções de codificação Swift.
fonte
Bem, você pode aplicar os conselhos de Kotlin https://kotlinlang.org/docs/reference/coding-conventions.html#functions-vs-properties .
fonte
Embora uma questão de propriedades computadas vs métodos em geral seja difícil e subjetiva, atualmente há um argumento importante no caso de Swift para preferir métodos em vez de propriedades. Você pode usar métodos em Swift como funções puras, o que não é verdade para propriedades (a partir do Swift 2.0 beta). Isso torna os métodos muito mais poderosos e úteis, pois podem participar da composição funcional.
fonte
Já que o tempo de execução é o mesmo, esta questão se aplica ao Objective-C também. Eu diria que com propriedades que você obtém
readwrite
didSet
para notificações de mudançaQuanto a algo específico para Swift, o único exemplo que tenho é que você pode usar
@lazy
para uma propriedade.fonte
Há uma diferença: se você usar uma propriedade, poderá substituí-la e torná-la leitura / gravação em uma subclasse.
fonte
willSet
edidSet
à classe base , sem saber nada sobre as classes derivadas futuras, pode detectar alterações na propriedade substituída. Mas você não pode fazer nada parecido com funções, eu acho.No caso somente leitura, uma propriedade computada não deve ser considerada semanticamente equivalente a um método, mesmo quando se comportam de forma idêntica, porque a eliminação da
func
declaração confunde a distinção entre as quantidades que compõem o estado de uma instância e as quantidades que são meramente funções do Estado. Você economiza digitação()
no local da chamada, mas corre o risco de perder a clareza do seu código.Como um exemplo trivial, considere o seguinte tipo de vetor:
Ao declarar o comprimento como um método, fica claro que é uma função do estado, que depende apenas de
x
ey
.Por outro lado, se você expressasse
length
como uma propriedade computadaentão quando você dot-guia completo em seu IDE em uma instância de
VectorWithLengthAsProperty
, ele ficaria como sex
,y
,length
eram propriedades em pé de igualdade, que é conceitualmente incorreto.fonte
Existem situações em que você prefere propriedades computadas a funções normais. Por exemplo: retornar o nome completo de uma pessoa. Você já sabe o nome e o sobrenome. Portanto, realmente a
fullName
propriedade é uma propriedade, não uma função. Neste caso, é uma propriedade computada (porque você não pode definir o nome completo, você pode apenas extraí-lo usando o nome e o sobrenome)fonte
Do ponto de vista do desempenho, parece não haver diferença. Como você pode ver no resultado do benchmark.
essência
main.swift
fragmento de código:Resultado:
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
No gráfico:
fonte
Date()
não é adequado para benchmarks, pois usa o relógio do computador, que está sujeito a atualizações automáticas pelo sistema operacional.mach_absolute_time
obteria resultados mais confiáveis.Semanticamente falando, as propriedades computadas devem ser fortemente acopladas ao estado intrínseco do objeto - se outras propriedades não mudarem, então consultar a propriedade computada em momentos diferentes deve dar a mesma saída (comparável via == ou ===) - semelhante para chamar uma função pura nesse objeto.
Os métodos, por outro lado, saem da caixa com a suposição de que nem sempre podemos obter os mesmos resultados, porque o Swift não tem uma maneira de marcar funções como puras. Além disso, os métodos em OOP são considerados ações, o que significa que executá-los pode resultar em efeitos colaterais. Se o método não tiver efeitos colaterais, ele pode ser convertido com segurança em uma propriedade computada.
Observe que as duas instruções acima são puramente de uma perspectiva semântica, pois pode muito bem acontecer que as propriedades computadas tenham efeitos colaterais que não esperamos e os métodos sejam puros.
fonte
Historicamente, a descrição é uma propriedade em NSObject e muitos esperariam que continuasse a mesma em Swift. Adicionar parênteses depois disso apenas aumentará a confusão.
EDIT: Depois de um downvoting furioso, tenho que esclarecer algo - se for acessado por meio da sintaxe de ponto, pode ser considerado uma propriedade. Não importa o que está sob o capô. Você não pode acessar métodos usuais com sintaxe de ponto.
Além disso, chamar essa propriedade não requer parênteses extras, como no caso do Swift, o que pode causar confusão.
fonte
description
é um método obrigatório noNSObject
protocolo e, portanto, em objetivo-C é retornado usando[myObject description]
. De qualquer forma, a propriedadedescription
era simplesmente um exemplo artificial - estou procurando uma resposta mais genérica que se aplique a qualquer propriedade / função personalizada.