[英]Making a Swift Array conform to a Protocol
Let's say that certain items can appear in a Feed
, so long as they implement the necessary properties defined by the Feedable
protocol.假设某些项目可以出现在
Feed
,只要它们实现了Feedable
协议定义的必要属性。 Let's also say that the Photo
object is feed-worthy:我们还说
Photo
对象是值得一看的:
extension Photo: Feedable { }
Is it possible to say that an Array
of these photos might also be Feedable
?是否可以说这些照片的
Array
也可能是Feedable
?
extension [Photo] : Feedable
Or do I always need some kind of wrapper object, such as a PhotoAlbum
, to conform to Feedable
?还是我总是需要某种形式的包装对象的,如
PhotoAlbum
,以符合Feedable
?
Edit编辑
To re-iterate, I was curious whether I can make only arrays of Photo
objects Feedable
.重申
Feedable
,我很好奇我是否只能制作Photo
对象的数组Feedable
。 Not making Array
of any content type Feedable
, not making an array of Feedable
s itself Feedable
(both of which are offered as solutions below if that's what you need).不将任何内容类型的
Array
Feedable
,也不将Feedable
数组本身Feedable
(如果您需要,这两种方法都在下面作为解决方案提供)。
In other words, a solution (which I doubt exists) would allow me to define a variable of type Feedable
with the following outcomes:换句话说,一个解决方案(我怀疑是否存在)将允许我定义一个
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
Perhaps this gist (which doesn't compile of course) shows the intention more clearly.也许这个要点(当然不能编译)更清楚地表明了意图。
You can achieve your goal in this way:您可以通过以下方式实现您的目标:
Swift 4:斯威夫特 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() {
}
}
If there was an array of Photo
and Video
,what would you like to be?如果有一组
Photo
和Video
,你想成为什么?
1.Every element performs like what they are. 1.每个元素都表现得像它们一样。
extension Array where Element : Feedable {
func foo() {
if Element.self == Photo.self {
} else {
}
}
}
2.The whole array performs as 'Video'. 2.整个阵列表现为“视频”。
extension Array where Element : Photo {
func foo() {
}
}
I think this is currently not possible.我认为目前这是不可能的。 In my project I have the same issue with a ModelProducer.
在我的项目中,我对 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()
}
}
I use ModelType
as a ghost protocol.我使用
ModelType
作为幽灵协议。 The problem is I cannot make a model producer that produces multiple ModelType
s, because of the same reason you discovered.问题是,由于与您发现的原因相同,我无法制作产生多个
ModelType
的模型生产者。 The solution in this case was the following:在这种情况下的解决方案如下:
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()]
}
}
This is more flexible from the start.这从一开始就更加灵活。 I get rid of the optional variable and single model producers just have one item in the array.
我摆脱了可选变量,单个模型生产者在数组中只有一项。 Maybe you can use a similar approach.
也许您可以使用类似的方法。
You can make an array to conform a protocol like this:您可以制作一个数组以符合这样的协议:
typealias PhotoArray = [Photo]
extension PhotoArray: Feedable {}
I didn't try in playground but maybe you can simply make an Array of Feedable:我没有在操场上尝试过,但也许您可以简单地制作一个可馈送数组:
var myPhotosArray = [Feedable]()
Then everything implementing the Feedable protocol would be allowed in the Array.然后所有实现 Feedable 协议的东西都将被允许在 Array 中。 If you want only a photo array, You can still subclass your Photo object to make a FeedablePhoto object.
如果你只想要一个照片数组,你仍然可以子类化你的 Photo 对象来制作一个 FeedablePhoto 对象。
Try this in Playground instead of downvoting without even testing.在 Playground 中试试这个,而不是在没有测试的情况下投票。 Seriously 3 downvotes without any reasons and explanations...
严重 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.