Swift fonksiyonları ve hesaplanan özellikler


26

Diyelim ki Eventaşağıdaki gibi bir sınıfım var :

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
    }
}

Yukarıda belirtilen 2 vakada fonksiyon veya hesaplanmış özellik kullanmak en iyi yöntem midir?


2
stackoverflow.com/questions/24035276/… ... Kısacası: 'İşlevleriniz işlevler ve özellikleriniz özellikler olsun.'
Robert Harvey,

Yanıtlar:


14

Tekdüzen Erişim Prensibi'ni takip edin ,

Bir modül tarafından sunulan tüm hizmetler, depolama veya hesaplama yoluyla uygulanıp uygulanmadıklarına ihanet etmeyen, tek tip bir gösterim yoluyla sağlanmalıdır.

Bana göre bu, tartışmasız ve bir değer döndüren fonksiyonlar yazmadığım anlamına gelir. Ben her zaman bilgisayarlı özellikleri kullanırım. Bu şekilde, sonradan hesaplanan mülkü depolanan bir mülke dönüştürmeye karar verirsem, uygulamamı her yerde parenleri kaldırma dürtüsüne sahip olmadan ve depolanan değeri döndüren ayrı bir "alıcı" yöntemi kullanmadan yapabilirim. IMHO oldukça israf görünüyor.

Saklanan bir mülkü hesaplanmış bir mülke dönüştürürsem, bunun sonuna ve uygulamanın kullanıldığı her yere parens eklemem gerekmez.


Başlangıçta @ Anton'un karmaşıklık cevabını kullandım, ancak pratikte bunun benim yaptığım gibi olduğunu anladım… varsayılan olarak özellikler.
Ashley Mills,

17

Hesaplamanın karmaşıklığına ve kullanım sıklığına bağlı olduğunu söyleyebilirim.

  • Eğer O(1)/ *, o zaman hesaplanmış özelliği kullanın.
  • Eğer O(N)+/ ise rare-use, işlevi kullanın.
  • Eğer O(N)+/ frequent-use, gelecekte karmaşıklığı telafi etmek için önbellekleme veya diğer "akıllı" teknikleri kullanmaya karar verebilir misiniz, eğer "evet" ise özelliği kullanın, eğer "hayır-hayır-hayır, sadece ağır" işlevini kullanın .

2
Komik, aynı mantığı kullanarak yapmaya başladım. Hafif bir işlem yapmak zorunda kalsanız bile, nesneyi değiştirmediği sürece, bir özellik olma izlenimini verebilirseniz, onu bir özellik haline getirin.
Dielson Sales,

9

Kısa bir süre önce Kotlin'i öğrenmeye başladım ve bilgisayarlı mülkleri ne zaman kullanacakları konusunda harika bir sezgisel deneyime sahipler:

İşlevler - Özellikler

Bazı durumlarda hiçbir argüman olmayan işlevler salt okunur özelliklerle değiştirilebilir. Anlambilim benzer olsa da, ne zaman diğerini tercih edeceğinizle ilgili bazı stilistik sözleşmeler vardır.

Temel algoritma ne zaman bir işlev yerine bir özellik tercih

  • atmaz
  • O (1) karmaşıklığına sahip
  • hesaplamak ucuz (ya da ilk çalıştırmada yakalandı)
  • çağrıları yerine aynı sonucu verir

- https://kotlinlang.org/docs/reference/coding-conventions.html


'Atmaz' aynı zamanda Swift için de önemlidir, çünkü mülkler atılamaz (henüz?)
alejandromp

"bir O (1) karmaşıklığı var" belgesinden
çıkardı

7

Swift'de, parametresiz olan fonksiyonlar ve hesaplanan özellikler neredeyse aynı özelliklere sahiptir (hesaplanan bir özellik olmasa da, parametresiz bir işlevin de kapanması olduğu bir fark olabilir).

Fark anlamsaldır. Kodunuz bir işlem gerçekleştirir ve örneğin bu eylemin sonucunun bir açıklamasını döndürürse, bir işlev kullanırım. Kodunuz bir özelliği ancak kullanıcının bakış açısından hesaplarsa, bu bir depolanmış özellik veya belki de önce önbelleğe alınmış bir değerin güncellenmesini gerektiren depolanmış bir özellik olabilirse, o zaman hesaplanan bir özelliği kullanırdım.

Büyük bir fark: Fonksiyonu veya hesaplanan özelliği iki kez çağırırsanız ne olur? Hesaplanan bir özellik için bence x = özellik; y = özellik tam olarak x = özellik ile aynı davranışa sahiptir; y = x, biraz daha yavaş çalışması dışında. İşlevler için, davranış farklı olsaydı şaşırmam.


4

Kullanım countOfAttendeesve countOfPaidAttendees().


Hesaplanan değişken, her erişildiğinde hesaplanan bir değer veren değerdir. Yani, bir değer saklamaz. Dahili olarak bir işlev olarak uygulanır.

Bir fonksiyondaki fark nedir?

  • Anlamsal olarak, bir değişken durumdur, işlev bir eylemdir.
  • Bir işlev, özel depolamaya erişimi düzenler. Hesaplanan değişken aynı şeyi daha kompakt bir şekilde yapabilir. Örnek .
  • Bir hesaplanan değişken, KVO ile birlikte kullanılabilir, #keypath olarak geçirilir ve gözlemlemek için olanaklara sahiptir: willSet, didSet.

Ne zaman bir değişken kullanmalısınız

  • atmaz
  • basit bir özellik döndürür
  • adında bir yan etkisi veya fiili yoktur.
  • O (1), yani, önemli bir maliyet getirmiyor. Örnekte O (n) olacaktır.
  • bu idempotent. Birden çok aynı başlatma, aynı değeri döndürür veya nesneyi aynı duruma getirir.

Bir işlevi yerine bir değişkeni tercih etmenin alakasız sebepleri

  • Hesaplanan bir değişken sizi yazımdan () saklar. Ancak, netlik, kısalıktan daha önemlidir, bu yüzden bu zayıf bir argümandır.
  • Salt okunur bir değişken, okuma / yazma olarak geçersiz kılınabilir. Bir fonksiyon her zaman sadece okunur olduğunu gösterir. Ancak, Apple, array.count gibi salt okunur değişkenler için özellikler kullanır. Şüphe durumunda, platformla tutarlılık isteyin.

kaynaklar

Gönderen  WWDC 2014 - 204 Kakao yenilikler  > 24:40 zaman bir @property kullanmak

Bir nesnenin değeri veya durumu ya da diğer nesnelerle olan ilişkisi hakkında her şey için özellik kullanın. Kötü adaylar:

  • İşleri yapan yöntemler: yükleme, ayrıştırma, geçiş,…. Adında fiiller var.
  • Jeneratörler: init, kopya, numaralandırılmış,…. Bu yöntemler iddiasız değildir.
  • Durumu değiştiren yöntemler: nextObject.

Gönderen  Erica Sadun tarafından Swift Tarzı  > Bilgisayarlı Özellikleri vs Yöntemleri

Bir özellik, bir eylemi gerçekleştirirken özellik, bir örneğin doğasında var olan kalitesini ifade eder.

  • Yöntemlerin parametreleri var; özellikleri yok. Yan etkileri olan herhangi bir çağrı için yöntemleri tercih edin. Bir yöntem bir şey yaparsa (örneğin, yükler, ayrıştırır, değiştirir veya yazdırır) veya bir fiil adı varsa, bu bir özellik olmamalıdır.
  • Alabileceğiniz ve / veya ayarlayabileceğiniz basit değerler için özellikleri tercih edin.
  • Özellikler, bir tür örneğinin anlamsal içsel kalitesini ifade etmelidir.
  • Özellikler willSet ve didSet aracılığıyla gözlemci eklemenizi sağlar. Depolanan örnek özelliklerinden farklı olarak, depolanan tür özelliklerine her zaman varsayılan bir değer verilmelidir.

Gönderen  KOTLIN özellikleri vs konvansiyonlar> işlevlerini kodlama . Bkz yukarıdaki Daniel'in cevabı .

İlgili bilgi içermeyen diğer kaynaklar:


3

Ben kullanmayı tercih ediyorum func. Nesneye yönelik programlama, hesaplanan özellikler olmadan gayet iyi çalışır. Geri hesaplanan / filtre edilen bir değer elde ettiğiniz için, bazıları hesaplanan bir özelliğin doğru hissettiğini iddia edebilir. Ama işte benim şikayetim, eğer bunu yaparsanız okunabilirlik çok etkileyicidir çünkü bir değer gibi geliyor.

Bu bağlamda, hesaplanan değeri tayin etmeyi denemek mantıklı olmaz (ve neyse ki IDE bundan kaçınmamıza yardımcı olur), fakat hesaplanan ancak bir değere benzeyen bir şey atamaya çalışırsam ne olur?

event.countOfAttendees = 0; // not possible

Arayan func'u kullanırken, arayanın doğrudan bir değerle ilgilenmediğinizi bilir:

event.countOfAttendees()

Davranışsal bir nesnesiyse, bir veri yapısı gibi görünmek yerine davranıyor gibi görünmesi gerektiğini düşünüyorum. Nesneniz aptalsa ve herhangi bir davranışı yoksa, neden kapsüllemeye çalışın? Bu durumda, katılımcıların herkese açık olması gerekebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.