Swift Cannot invoke #39;find#39; with an argument list of type #39;([Score], Score)#39; where Score is a struct(Swift 无法使用类型为“([Score],Score)的参数列表调用“find,其中 Score 是一个结构)
问题描述
虽然 find(["a", "b"], "c") 没有问题,但在尝试在结构数组中查找结构的索引时出现错误:
While find(["a", "b"], "c") works with no problems, I get an error when trying to find the index of a structure inside an array of structures:
struct Score
{
//...
}
var scores: [Score] = //...
var score: Score = //...
find(self.scores, score) // Error: Cannot invoke 'find' with an argument list of type '([Score], Score)'
虽然默认情况下无法相互比较的结构可能是个问题.但是将 Score 的定义改为 class给我同样的错误.
I though it could be a problem with structures that can't be compared to each other by default. But changing Scores definition to class
gives me the same error.
推荐答案
从 Swift 2.0 开始,现在有一个内置版本的 find 需要一个闭包,所以你不需要必须自己编写——而且,find 已重命名为 indexOf,现在是 CollectionType 的协议扩展,所以你可以这样称呼它一种方法:
as of Swift 2.0, there is now a built-in version of find that takes a closure so you don’t have to write your own – but also, find has been renamed indexOf, and is now a protocol extension of CollectionType, so you call it like a method:
// if you make `Score` conform to `Equatable:
if let idx = self.scores.indexOf(score) {
}
// or if you don't make it Equatable, you can just use a closure:
// (see original answer below for why you might prefer to do this)
if let idx = scores.indexOf({$0.scoreval == 3}) {
}
下面是 2.0 之前的原始答案
Original pre-2.0 answer below
虽然建议使您的类 Equatable 的答案可能会很好地工作,但我建议您在选择这样做之前要小心.原因是,正如文档所述,等式意味着可替代性,并且您的 == 运算符必须是自反的、对称的和可传递的.如果你不遵守这一点,在使用 equals、sort 等算法时可能会出现一些非常奇怪的行为.在实现 Equatable时要特别小心代码> 在非最终类上.如果你确定你能满足要求,那就去做吧,find 就可以了.
While the answers suggesting making your class Equatable may work nicely, I'd recommend a bit of caution before choosing to do this. The reason being that, as the docs state, equatability implies substitutability, and your == operator must be reflexive, symmetric and transitive. If you don't adhere to this, you might get some very weird behavior when using algorithms like equals, sort etc. Be especially cautious if implementing Equatable on non-final classes. If you're sure you can meet requirements, go for it, and find will work.
如果没有,您可以考虑的替代方法是编写一个应该在标准库中但不在标准库中的函数,这是一个采用闭包的 find:
If not, an alternative you could consider is writing a function that ought to be in the standard library but isn't, which is a find that takes a closure:
func find<C: CollectionType>(source: C, match: C.Generator.Element -> Bool) -> C.Index {
for idx in indices(source) {
if match(source[idx]) { return idx }
}
return nil
}
一旦你有了这个,你可以提供任何你喜欢的匹配标准.例如,如果您的对象是类,您可以使用引用相等:
Once you have this, you can supply any matching criteria you prefer. For example, if your objects are classes you could use reference equality:
let idx = find(scores) { $0 === $1 }
这篇关于Swift 无法使用类型为“([Score],Score)"的参数列表调用“find",其中 Score 是一个结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Swift 无法使用类型为“([Score],Score)"的参数列表调用“find",其中 Score 是一个结构
- Android - 我如何找出用户有多少未读电子邮件? 2022-01-01
- 使用自定义动画时在 iOS9 上忽略 edgesForExtendedLayout 2022-01-01
- MalformedJsonException:在第1行第1列路径中使用JsonReader.setLenient(True)接受格式错误的JSON 2022-01-01
- Android - 拆分 Drawable 2022-01-01
- 用 Swift 实现 UITextFieldDelegate 2022-01-01
- 如何检查发送到 Android 应用程序的 Firebase 消息的传递状态? 2022-01-01
- 在测试浓缩咖啡时,Android设备不会在屏幕上启动活动 2022-01-01
- 想使用ViewPager,无法识别android.support.*? 2022-01-01
- android 4中的android RadioButton问题 2022-01-01
- Android viewpager检测滑动超出范围 2022-01-01
