问题描述
虽然 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 Score
s 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 是一个结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!