簡體   English   中英

使 Swift 數組符合協議

[英]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() {    
    }
}

如果有一組PhotoVideo ,你想成為什么?

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM