Opsiyonel Olmayan ile Swift Protokolü Opsiyonel uyumluluk
İsteğe bağlı özelliğe sahip bir protokolüm var.
Bu protokole uyan türlerin çoğu, eşleşen bir isteğe bağlı özelliğe sahip olacaktır. Bununla birlikte, aynı tür ve adda isteğe bağlı olmayan bir özelliğe sahiptir.
protocol SomeProtocol {
var foo: Int? { get }
}
struct StructA: SomeProtocol {
let foo: Int?
}
struct StructB: SomeProtocol {
let foo: Int // Type 'StructB' does not conform to protocol 'SomeProtocol'
}
Xcode'un "Düzelt - Protokol saplamaları eklemek istiyor musunuz?" düğmesi, mülkün isteğe bağlı sürümünü ekler, ancak yapının artık geçersiz yinelenen değişken adları vardır:
struct StructB: SomeProtocol {
let foo: Int
var foo: Int? { return foo } // Invalid redeclaration of 'foo'
}
Gelen { get }
-sadece durumda, nedeniyle isteğe bağlı olmayan bu olur "sadece iş" hep kısıtları sağlayan farz etmişti, isteğe bağlı bir dönüş türüne sahip bir işlevde isteğe bağlı olmayan bir dönüş biçimine benzerdir, isteğe bağlı. Ama görünüşe göre durum böyle değil.
Bu, işlevler için de aynı şekilde çalışır; bir protokol func bar() -> Int?
, uygun bir tip bildirimi ile karşılanmaz func bar() -> Int
.
Bu sorunun etrafında herhangi bir yol var mı? Değişkenleri yeniden adlandırmamayı veya ara alıcılar eklememeyi tercih ederim.
Swift için bu durum düşünüldü mü? İsteğe bağlı olmayanın isteğe bağlı bir protokol değişkenini karşılamasına izin vermemenin mantığı nedir?
Yanıtlar
Protokol, isteğe bağlı bir döndüren varsayılan bir uygulama sağlıyorsa:
protocol SomeProtocol {
var foo: Int? { get }
}
extension SomeProtocol {
var foo: Int? { return nil }
}
protokole uygun türler daha sonra değişkenin / işlevin isteğe bağlı olmayan geçersiz bir sürümünü sağlayabilir:
struct StructB: SomeProtocol {
let foo: Int
}
Bunu Swift Evolution forumunda tartışılan buldum:
İlk bakışta, isteğe bağlı olmayan türlerle protokol gereksinimlerini karşılamamıza izin veren bir kural olduğunu düşündüm, ancak bu bir hatayla sonuçlandı. Ancak daha fazla araştırmadan sonra, gereksinimi isteğe bağlı olmayan bir sürümle "geçersiz kılmak" için varsayılan bir uygulamanın olması gerektiğini fark ettim.
https://forums.swift.org/t/how-does-this-rule-work-in-regard-of-ambiguity/19448
Bu Swift ekibi, isteğe bağlı olmayan türlerin isteğe bağlı değer protokollerini karşılamasına izin vermeyi de tartışıyor:
Failable init'lerde olduğu gibi isteğe bağlı olmayan türlerde protokol gereksinimi tatminine izin vermek mantıklı olur mu? (Muhtemelen bazı üstü kapalı isteğe bağlı promosyonlarla.)
Evet, kesinlikle! Bunun mevcut kodun davranışını değiştirdiği kısım dışında, bu yüzden çok dikkatli olmalıyız. Bu, [SR-522] ' nin bir parçası olarak kabul edilir Protokol işlevlerinin eşdeğişken dönüşleri olamaz
Burada Stack Overflow'da izlenen:
Neden bir protokoldeki yalnızca elde edilebilir özellik gereksinimi, uygun bir özellik tarafından karşılanamıyor?