Arrays Swift不能调用';查找';具有类型为';([得分],得分)和#x27;其中Score是一个结构
虽然Arrays Swift不能调用';查找';具有类型为';([得分],得分)和#x27;其中Score是一个结构,arrays,swift,find,indexof,Arrays,Swift,Find,Indexof,虽然find([“a”,“b”],“c”)的工作没有问题,但我在尝试在结构数组中查找结构的索引时出错: struct Score { //... } var scores: [Score] = //... var score: Score = //... find(self.scores, score) // Error: Cannot invoke 'find' with an argument list of type '([Score], Score)' 我认为这可能是一个结
find([“a”,“b”],“c”)
的工作没有问题,但我在尝试在结构数组中查找结构的索引时出错:
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
s定义更改为class
给我同样的错误。函数
find
的接口是/was:
func find<C : CollectionType where C.Generator.Element : Equatable>(domain: C,
value: C.Generator.Element) -> C.Index?
在第二种情况下,您的元素需要是相等的:
// Where Generator.Element : Equatable
func index(of: Self.Generator.Element) -> Self.Index?
如果您决定采用equatable
路线,则以下情况适用。
注释结束]
您的得分
结构不可均衡
,因此出现错误你需要弄清楚分数相等意味着什么。可能是数字“分数”;也许它是一个“分数”和一个“用户id”。这取决于你的分数
抽象。一旦知道,您就可以使用以下方法实现=
:
func == (lhs:Score, rhs:Score) -> Bool {
return // condition for what it means to be equal
}
注意:如果您使用类
,因此分数具有“标识”,则可以通过以下方式实现:
func == (lhs:Score, rhs:Score) -> Bool { return lhs === rhs }
您的字符串示例之所以有效,是因为String
是equalable
。如果查看Swift库代码,您将看到:
extension String : Equatable {}
func ==(lhs: String, rhs: String) -> Bool
正如其他人所说,您搜索的对象必须符合equalable协议 因此,您需要向Score结构添加一个扩展,告诉编译器它符合该协议:
extension Score: Equatable {}
然后需要为该类实现==函数:
public func ==(lhs: Score, rhs: Score) -> Bool
{
return lhs.whatever == rhs.whatever //replace with code for your struct.
}
编辑:从Swift 2.0开始,现在有了一个内置版本的
find
,它接受一个闭包,这样您就不必自己编写了–而且,find
已重命名为indexOf
,现在是CollectionType
的协议扩展,因此您可以像方法一样调用它:
// 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之前的原始答案
虽然答案建议让你的班级变得平等可能会很好,但我建议在选择这样做之前要小心谨慎。原因是,正如docs所述,equalability意味着可替换性,并且您的
=
运算符必须是自反的、对称的和可传递的。如果不遵守这一点,在使用诸如equals
、sort
等算法时可能会出现一些非常奇怪的行为。如果在非final类上实现equalable
,请特别小心。如果你确信自己能够满足要求,那么就去做吧,find
将起作用
如果不是,你可以考虑的一个选择是编写一个函数,它应该在标准库中,但不是,这是一个<代码>查找< /代码>,它需要一个闭包:
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
}
你已经找到了原因
Score
必须实现equalable
协议(无论是struct还是class)。可能与这里的问题相同:为什么我在创建Score
aclass
时会遇到相同的错误?==
对类不是有效的吗?除非您按照我的回答中所述定义自定义对象,否则它对任何自定义对象都无效。在Swift 3中,indexOf
似乎已重命名为index(of:)
。
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
}
let idx = find(scores) { $0 === $1 }