[英]Making a Swift Array conform to a Protocol
假設某些項目可以出現在Feed
,只要它們實現了Feedable
協議定義的必要屬性。 我們還說Photo
對象是值得一看的:
extension Photo: Feedable { }
是否可以說這些照片的Array
也可能是Feedable
?
extension [Photo] : Feedable
還是我總是需要某種形式的包裝對象的,如PhotoAlbum
,以符合Feedable
?
編輯
重申Feedable
,我很好奇我是否只能制作Photo
對象的數組Feedable
。 不將任何內容類型的Array
Feedable
,也不將Feedable
數組本身Feedable
(如果您需要,這兩種方法都在下面作為解決方案提供)。
換句話說,一個解決方案(我懷疑是否存在)將允許我定義一個Feedable
類型的變量,結果如下:
var feedable: Feedable
//photo is feedable, so this is fine
feedable = Photo() //ok
//arrays of photos are feedable
let photo1 = Photo()
let photo2 = Photo()
feedable = [photo1, photo2]
//arrays of other things are not
feedable = ["no", "dice"] //nope
//even if the contents of an array are themselves Feedable, that's not sufficient. E.g. Video is Feedable, but Array of Videos is not.
let video1 = Video()
let video2 = Video()
feeble = video1 //fine
feedable = [video1, video2] //nope
也許這個要點(當然不能編譯)更清楚地表明了意圖。
您可以通過以下方式實現您的目標:
斯威夫特 4:
protocol Feedable {
func foo()
}
extension String: Feedable {
func foo() {
}
}
extension Array: Feedable where Element: Feedable {
func foo() {
}
}
// or in more generic way to support Array, Set and other collection types
extension Collection: Feedable where Element: Feedable {
func foo() {
}
}
如果有一組Photo
和Video
,你想成為什么?
1.每個元素都表現得像它們一樣。
extension Array where Element : Feedable {
func foo() {
if Element.self == Photo.self {
} else {
}
}
}
2.整個陣列表現為“視頻”。
extension Array where Element : Photo {
func foo() {
}
}
我認為目前這是不可能的。 在我的項目中,我對 ModelProducer 有同樣的問題。
protocol M: ModelType {}
protocol ModelProducerType {
associatedtype M: ModelType
var model: M? { get }
func produce()
}
struct Test: ModelType {}
class TestProducer: ModelProducerType {
var model: Test?
func produce() {
model = Test()
}
}
我使用ModelType
作為幽靈協議。 問題是,由於與您發現的原因相同,我無法制作產生多個ModelType
的模型生產者。 在這種情況下的解決方案如下:
protocol M: ModelType {}
protocol ModelProducerType {
associatedtype M: ModelType
var model: [M] { get }
func produce()
}
struct Test: ModelType {}
class TestProducer: ModelProducerType {
var model: [Test] = []
func produce() {
model = [Test()]
}
}
這從一開始就更加靈活。 我擺脫了可選變量,單個模型生產者在數組中只有一項。 也許您可以使用類似的方法。
您可以制作一個數組以符合這樣的協議:
typealias PhotoArray = [Photo]
extension PhotoArray: Feedable {}
我沒有在操場上嘗試過,但也許您可以簡單地制作一個可饋送數組:
var myPhotosArray = [Feedable]()
然后所有實現 Feedable 協議的東西都將被允許在 Array 中。 如果你只想要一個照片數組,你仍然可以子類化你的 Photo 對象來制作一個 FeedablePhoto 對象。
在 Playground 中試試這個,而不是在沒有測試的情況下投票。 嚴重 3 次投票,沒有任何理由和解釋......
import UIKit
protocol Tree: class {
func grow()
}
class BigTree: Tree {
internal func grow() {
print("Big tree growing")
}
}
class SmallTree: Tree {
internal func grow() {
print("Small tree growing")
}
}
class Car {
//not a tree
}
var manyTrees = [Tree]()
manyTrees.append(BigTree())
manyTrees.append(SmallTree())
manyTrees.append(Car()) //This makes an error "Car doesn't conform to expected type 'Tree'"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.