W sesji Wprowadzenie do Swift WWDC description
pokazano właściwość tylko do odczytu :
class Vehicle {
var numberOfWheels = 0
var description: String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description)
Czy istnieją jakiekolwiek implikacje dla wyboru powyższego podejścia zamiast użycia metody zamiast tego:
class Vehicle {
var numberOfWheels = 0
func description() -> String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description())
Wydaje mi się, że najbardziej oczywistymi powodami, dla których wybrałbyś obliczoną właściwość tylko do odczytu, są:
- Semantyka - w tym przykładzie sensowne jest,
description
aby być właściwością klasy, a nie działaniem, które wykonuje. - Zwięzłość / przejrzystość - zapobiega konieczności używania pustych nawiasów podczas pobierania wartości.
Oczywiście powyższy przykład jest zbyt prosty, ale czy istnieją inne dobre powody, aby wybrać jeden z nich? Na przykład, czy są jakieś cechy funkcji lub właściwości, które pomogłyby w podjęciu decyzji, której użyć?
NB Na pierwszy rzut oka wydaje się to dość powszechnym pytaniem OOP, ale chciałbym poznać wszelkie funkcje specyficzne dla Swift, które wskazywałyby na najlepsze praktyki podczas używania tego języka.
methods
properties
semantics
swift
Stuart
źródło
źródło
get {}
? Nie wiedziałem, dzięki!Odpowiedzi:
Wydaje mi się, że to głównie kwestia stylu: zdecydowanie wolę używać właściwości właśnie do tego: właściwości; czyli proste wartości, które możesz uzyskać i / lub ustawić. Używam funkcji (lub metod), gdy wykonywana jest rzeczywista praca. Może trzeba coś obliczyć lub odczytać z dysku lub z bazy danych: w tym przypadku używam funkcji, nawet jeśli zwracana jest tylko prosta wartość. W ten sposób mogę łatwo sprawdzić, czy połączenie jest tanie (właściwości), czy prawdopodobnie drogie (funkcje).
Prawdopodobnie uzyskamy większą przejrzystość, gdy Apple opublikuje pewne konwencje kodowania Swift.
źródło
Cóż, możesz zastosować porady Kotlina https://kotlinlang.org/docs/reference/coding-conventions.html#functions-vs-properties .
źródło
Podczas gdy kwestia obliczonych właściwości w porównaniu z metodami jest ogólnie trudna i subiektywna, w przypadku Swifta istnieje jeden ważny argument przemawiający za preferowaniem metod nad właściwościami. Możesz używać metod w Swift jako czystych funkcji, co nie jest prawdą dla właściwości (od wersji Swift 2.0 beta). Dzięki temu metody są znacznie bardziej wydajne i użyteczne, ponieważ mogą uczestniczyć w składzie funkcjonalnym.
źródło
Ponieważ środowisko wykonawcze jest takie samo, to pytanie dotyczy również celu-C. Powiedziałbym, z właściwościami, które dostajesz
readwrite
didSet
do powiadomień o zmianachJeśli chodzi o coś specyficznego dla języka Swift, jedynym przykładem, jaki mam, jest to, że można go użyć
@lazy
dla właściwości.źródło
Jest różnica: jeśli używasz właściwości, możesz ją ostatecznie przesłonić i sprawić, by była odczytywana / zapisywana w podklasie.
źródło
willSet
ididSet
do klasy bazowej , bez znajomości przyszłych klas pochodnych, może wykrywać zmiany w przesłoniętej właściwości. Ale myślę, że nie można zrobić czegoś takiego z funkcjami.W przypadku tylko do odczytu, właściwość komputerowej powinno nie być uważane semantycznie równoważne metody, nawet wtedy, gdy zachowują się identycznie, ponieważ upuszczając
func
deklarację zaciera różnicę między ilościami, które składają się na stan z instancji i ilości, które są jedynie funkcje z stan. Oszczędzasz na wpisywaniu tekstu()
w witrynie wywoławczej, ale ryzykujesz utratę przejrzystości kodu.Jako trywialny przykład rozważmy następujący typ wektora:
Deklarując długość jako metodę, staje się jasne, że jest to funkcja stanu, która zależy tylko od
x
iy
.Z drugiej strony, gdybyś miał wyrazić
length
jako obliczoną właściwośćwtedy, gdy kropka-tab-kompletne IDE na instancji
VectorWithLengthAsProperty
, to będzie wyglądać tak, jakbyx
,y
,length
były nieruchomości na równi, która jest konceptualnie błędne.źródło
Są sytuacje, w których wolisz obliczoną właściwość od normalnych funkcji. Takich jak: zwrot pełnego imienia i nazwiska osoby. Znasz już imię i nazwisko. Tak więc
fullName
właściwość jest własnością, a nie funkcją. W tym przypadku jest to właściwość computed (ponieważ nie możesz ustawić pełnej nazwy, możesz ją po prostu wyodrębnić, używając imienia i nazwiska)źródło
Z punktu widzenia wydajności wydaje się, że nie ma różnicy. Jak widać w wyniku benchmarku.
sens
main.swift
fragment kodu:Wynik:
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
Na wykresie:
źródło
Date()
nie nadaje się do testów porównawczych, ponieważ wykorzystuje zegar komputera, który podlega automatycznym aktualizacjom przez system operacyjny.mach_absolute_time
uzyska bardziej wiarygodne wyniki.Mówiąc semantycznie, obliczone właściwości powinny być ściśle sprzężone z wewnętrznym stanem obiektu - jeśli inne właściwości się nie zmieniają, zapytanie o obliczoną właściwość w różnych momentach powinno dać te same dane wyjściowe (porównywalne przez == lub ===) - podobne do wywołania czystej funkcji na tym obiekcie.
Z drugiej strony metody wychodzą z pudełka przy założeniu, że nie zawsze możemy uzyskać takie same wyniki, ponieważ Swift nie ma sposobu na oznaczanie funkcji jako czystych. Również metody w OOP są uważane za akcje, co oznacza, że ich wykonanie może spowodować skutki uboczne. Jeśli metoda nie ma skutków ubocznych, można ją bezpiecznie przekonwertować na obliczoną właściwość.
Zauważ, że oba powyższe stwierdzenia są czysto semantyczne, ponieważ może się zdarzyć, że obliczone właściwości będą miały skutki uboczne, których się nie spodziewamy, a metody będą czyste.
źródło
Z historycznego punktu widzenia opis jest właściwością NSObject i wielu spodziewałoby się, że będzie on kontynuowany w Swift. Dodanie parens po nim tylko wprowadzi zamieszanie.
EDYCJA: Po wściekłym przegłosowaniu muszę coś wyjaśnić - jeśli dostęp do niego uzyskuje się za pomocą składni kropkowej, można to uznać za właściwość. Nie ma znaczenia, co jest pod maską. Nie możesz uzyskać dostępu do zwykłych metod ze składnią kropkową.
Poza tym wywołanie tej właściwości nie wymagało dodatkowych parenów, jak w przypadku Swifta, co może prowadzić do nieporozumień.
źródło
description
jest to metoda wymagana wNSObject
protokole, więc w celu-C jest zwracane za pomocą[myObject description]
. W każdym razie właściwośćdescription
była po prostu wymyślonym przykładem - szukam bardziej ogólnej odpowiedzi, która dotyczy dowolnej niestandardowej właściwości / funkcji.