【问题标题】:Cannot invoke 'handler' with argument list of type '([Post])'无法使用类型为“([Post])”的参数列表调用“处理程序”
【发布时间】:2015-05-22 02:26:18
【问题描述】:

我都这样做,但不明白为什么这个操场的最后一行会引发编译器错误:

protocol Model { }

struct Post: Model {
  var content = "Hello"
}

struct Posts: Model {
  var allPosts: [Post] = [Post(), Post(), Post()]
}

func handler(items: [Model]) { }

var posts = Posts()
handler(posts.posts)

如果您在字里行间阅读,我的目标是能够使用一个参数调用一个函数,该参数是一个符合协议的结构数组。该函数应该能够处理不同类型结构的数组。很想知道我缺少什么,以及您是否有更好的解决方案的建议。

谢谢!

【问题讨论】:

  • 您的处理函数需要一个模型数组,而您正在传递一个 Post 数组,您需要将其更改为 func handler(items: [Post]) { }
  • 不幸的是,这对我的情况没有帮助。正如我在帖子中提到的,我有一个硬性要求:函数应该能够处理不同类型结构的数组
  • 对不起,我错过了,在这种情况下,您需要使用@Lei Wang 推荐的泛型,但如果他说的不是限制,而是 swift 中的强大工具,则相反。更多细节在这里

标签: ios swift generics


【解决方案1】:

这似乎是Swift 的限制。但是您可以使用Generics 做一些这样的解决方法:

func handler<T: Model>(items: [T]) { }

或者让你的协议成为一个@objc 协议,你只能应用于类类型:

@objc protocol Model { }

class Post: Model {
    var content = "Hello"
}

【讨论】:

  • 谢谢@Lei!那肯定解决了。如果您有任何想法,我有一个后续问题:您将如何将此技术应用于类型别名?我的处理程序函数实际上不是一个函数,而是一个类型别名(即 typealias CompletionHandler = ([Model]?) -> Void。或者这也是一个限制,我是否必须做一些类似拳击的事情(例如stackoverflow.com/questions/27084586/generic-typealias-in-swift) ?
  • @Lei Wrang,这不是swift中的限制,这实际上是swift中引入的一个非常强大的工具,称为Generics。
  • @IcaroNZ 好吧,我认为在这种情况下应该接受符合协议的结构。如果输入参数不是数组,它会起作用。
  • @IcaroNZ 我认为将对象数组向下转换为协议数组可能需要涉及 Objective-C。
  • @rainypixels typealias 在泛型中不起作用。在这种情况下,也许拳击是一个不错的选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多