使Swift数组符合协议

时间:2016-03-31 02:59:01

标签: ios arrays swift protocols

假设某些项目可以显示在Feed中,只要它们实现Feedable协议定义的必要属性即可。我们还要说Photo对象是值得的:

extension Photo: Feedable { }

是否可以说这些照片的Array也可能是Feedable

extension [Photo] : Feedable

或者我是否总是需要某种包装器对象(例如PhotoAlbum)来符合Feedable

修改

为了重新迭代,我很好奇我是否只能制作Photo个对象Feedable的数组。未对任何内容类型Array进行Feedable,而不是创建Feedable s本身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

或许this gist(当然没有编译)会更清楚地表明意图。

5 个答案:

答案 0 :(得分:2)

如果有PhotoVideo的数组,您希望得到什么?

1.每个元素都表现得像它们一样。

extension Array where Element : Feedable {
    func foo() {
        if Element.self == Photo.self {

        } else {

        }
    }
}

2.整个阵列表现为“视频”。

extension Array where Element : Photo {
    func foo() {

    }
}

答案 1 :(得分:1)

我认为目前这是不可能的。在我的项目中,我对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作为ghost协议。问题是我无法使模型生成器生成多个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()]
    }
}

从一开始就更加灵活。我摆脱了可选变量,单个模型生成器只在数组中有一个项目。也许你可以使用类似的方法。

答案 2 :(得分:0)

您可以通过以下方式实现目标:

迅速4:

protocol Feedable {
    func foo()
}

extension String: Feedable {
    func foo() {    
    }
}

extension Array: Feedable where Element: Feedable {
    func foo() {    
    }
}

答案 3 :(得分:0)

你可以制作一个数组来符合这样的协议:

typealias PhotoArray = [Photo]

extension PhotoArray: Feedable {}

答案 4 :(得分:-5)

我没有在游乐场尝试过,但也许你可以简单地制作一个Feedable数组:

var myPhotosArray = [Feedable]()

然后,Array中将允许实现Feedable协议的所有内容。如果您只想要一个照片数组,您仍然可以将您的Photo对象子类化为一个FeedablePhoto对象。

在Playground中尝试此操作,而不是在没有测试的情况下进行downvoting。 严重的3个downvotes没有任何理由和解释...

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'"