使Swift数组符合协议

f4t66c6m  于 2023-06-21  发布在  Swift
关注(0)|答案(6)|浏览(146)

假设某些项可以出现在Feed中,只要它们实现了Feedable协议定义的必要属性。让我们也假设Photo对象是有feed-worthy的:

extension Photo: Feedable { }

有没有可能说这些照片中的Array也可能是Feedable

extension [Photo] : Feedable

还是我总是需要某种 Package 器对象(如PhotoAlbum)来符合Feedable

编辑

为了重新迭代,我很好奇是否可以只生成Photo对象的数组Feedable。不生成任何内容类型的ArrayFeedable,不生成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(当然不能编译)更清楚地表明了意图。

cczfrluj

cczfrluj1#

你可以通过这种方式实现你的目标:
Swift 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() {    
    }
}
k5ifujac

k5ifujac2#

如果有一个由PhotoVideo组成的数组,你希望它是什么?
1.每一个元素都像他们一样工作。

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

        } else {

        }
    }
}

2.整个数组执行“视频”。

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

    }
}
wkftcu5l

wkftcu5l3#

我认为这在目前是不可能的。在我的项目中,我遇到了与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()]
    }
}

从一开始就更加灵活。我去掉了可选变量,单个模型生产者在数组中只有一个元素。也许你可以使用类似的方法。

kzipqqlq

kzipqqlq4#

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

typealias PhotoArray = [Photo]

extension PhotoArray: Feedable {}
xmq68pz9

xmq68pz95#

这里的答案几乎都是你想做的事情。特别是this one,只需一次更改,它就可以被限制为type的元素,而不是确认为protocol的元素。

Swift 5.8

extension Array: Feedable where Element == Photo {
   
}

有了这个扩展,发布在问题上的代码在预期的地方显示错误,在其他地方都可以。

xxb16uws

xxb16uws6#

我没有尝试在操场上,但也许你可以简单地使一个数组的饲料:

var myPhotosArray = [Feedable]()

然后,在阵列中将允许实现可馈送协议的所有内容。如果你只想要一个照片数组,你仍然可以子类化你的照片对象来创建一个FeedablePhoto对象。
在Playground中尝试这个,而不是在没有测试的情况下进行向下投票。严重的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'"

相关问题