Powiedz, że mam klasę Event
w następujący sposób:
class Event {
private var attendees: [Person] = []
// Case 1
//*******
// Should I use a func…
func countOfAttendees() -> Int {
return attendees.count
}
// …or a var
var countOfAttendees: Int {
return attendees.count
}
// Case 2
//*******
// Should I use a func…
func countOfPaidAttendees() -> Int {
return attendees.filter({$0.hasPaid}).count
}
// …or a var
var countOfPaidAttendees: Int {
return attendees.filter({$0.hasPaid}).count
}
}
Czy najlepszą praktyką jest używanie funkcji lub obliczonych właściwości w 2 przypadkach wskazanych powyżej?
functions
swift-language
Ashley Mills
źródło
źródło
Odpowiedzi:
Przestrzegaj zasady jednolitego dostępu ,
Dla mnie oznacza to, że nie piszę funkcji, które nie przyjmują argumentów i nie zwracają wartości. Zawsze używam obliczonych właściwości. W ten sposób, jeśli później zdecyduję się zmienić właściwość obliczoną na właściwość przechowywaną, mogę to zrobić bez potrzeby usuwania parens wszędzie w mojej aplikacji i bez osobnej metody „getter”, która po prostu zwraca wartość przechowywanej nieruchomość, która wydaje się dość marnotrawstwem IMHO.
A jeśli zmienię przechowywaną właściwość na obliczoną, nie muszę dodawać parens na jej końcu i wszędzie tam, gdzie jest używana w aplikacji.
źródło
Powiedziałbym, że zależy to od złożoności obliczeń w zależności od częstotliwości użytkowania.
O(1)
/*
, użyj właściwości obliczeniowej.O(N)+
/rare-use
, użyj funkcji.O(N)+
/frequent-use
, zastanów się, czy w przyszłości możesz zdecydować się na użycie buforowania lub innych „inteligentnych” technik w celu skompensowania złożoności, jeśli „tak”, użyj właściwości, jeśli „nie-nie-nie, to jest po prostu ciężkie”, użyj funkcji .źródło
Niedawno zacząłem uczyć się Kotlin i mają świetną heurystykę na temat tego, kiedy użyć obliczonych właściwości:
- https://kotlinlang.org/docs/reference/coding-conventions.html
źródło
W Swift funkcje bez parametrów i właściwości obliczeniowych mają prawie takie same możliwości (może istnieć różnica, że funkcja bez parametru jest również zamknięciem, podczas gdy właściwość obliczona nie jest).
Różnica jest semantyczna. Jeśli twój kod wykonuje akcję i zwraca na przykład opis wyniku tej akcji, użyłbym funkcji. Jeśli kod oblicza właściwość, ale z punktu widzenia użytkownika może to być właściwość przechowywana, a może właściwość przechowywana, która wymaga najpierw aktualizacji pewnej wartości z pamięci podręcznej, wówczas użyłbym właściwości obliczonej.
Duża różnica: co się stanie, jeśli wywołasz funkcję lub obliczoną właściwość dwukrotnie? W przypadku obliczonej właściwości oczekuję, że x = właściwość; y = właściwość ma dokładnie takie samo zachowanie jak x = właściwość; y = x, ale może działać trochę wolniej. W przypadku funkcji nie byłbym zaskoczony, gdyby zachowanie było inne.
źródło
Użyj
countOfAttendees
icountOfPaidAttendees()
.Obliczona zmienna to taka, która zwraca obliczoną wartość za każdym razem, gdy jest dostępna. Oznacza to, że nie przechowuje wartości. Wewnętrznie jest implementowany jako funkcja.
Jaka jest różnica z funkcją?
Powinieneś użyć zmiennej, kiedy
Nieistotne powody, dla których preferuje się zmienną nad funkcją
Zasoby
Od WWDC 2014 - 204 Co nowego w Cocoa > 24:40 Kiedy używać @property
Od Swift Style autorstwa Erica Sadun > Właściwości obliczeniowe a metody
Z konwencji kodowania Kotlin> funkcje a właściwości . Zobacz odpowiedź Daniela powyżej .
Inne zasoby bez istotnych informacji:
źródło
Użyłbym
func
. Programowanie obiektowe działa dobrze bez obliczonych właściwości. Ponieważ odzyskujesz wartość, która została obliczona / przefiltrowana, niektórzy mogą argumentować, że obliczona właściwość wydaje się właściwa. Ale oto moja skarga, jeśli to zrobisz, wtedy czytelność będzie hitem, ponieważ wydaje się to wartością.W tym kontekście nie ma sensu przypisywanie obliczonej wartości (i na szczęście IDE pomaga nam tego uniknąć), ale co, jeśli spróbuję przypisać obliczoną wartość, która wygląda jak wartość?
Podczas korzystania z func dzwoniący wie, że nie masz do czynienia z wartością bezpośrednio:
Myślę, że jeśli jest to obiekt behawioralny, powinien wyglądać raczej tak, jak zachowuje się niż struktura danych. Jeśli twój obiekt jest głupi i nie ma żadnego zachowania, to po co próbować go otaczać? W takim przypadku równie dobrze możesz mieć publiczność
źródło