Swift无法使用类型为"([Score],Score)"的参数列表调用"find",其中Score为结构

Riv*_*era 6 arrays find indexof swift

虽然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)'
Run Code Online (Sandbox Code Playgroud)

我可能是一个问题,结构默认情况下无法相互比较.但改变Scores定义class 给我同样的错误.

Air*_*ity 14

编辑:从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}) {

}
Run Code Online (Sandbox Code Playgroud)

原始2.0之前的答案


虽然答案表明让你的课程Equatable可以很好地工作,但在选择这样做之前我会建议你谨慎一点.原因在于,正如文档所述,等同性意味着可替代性,并且您的==运算符必须是自反的,对称的和可传递的.如果您不遵守这一点,在使用类似算法等时可能会遇到一些非常奇怪的行为.如果在非最终类上实现equals,sort请特别谨慎Equatable.如果您确定自己能够满足要求,那么就去做吧find.

如果没有,你可以考虑的替代方法是编写一个应该在标准库中的函数,但不是,这是一个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
}
Run Code Online (Sandbox Code Playgroud)

完成后,您可以提供您喜欢的任何匹配条件.例如,如果您的对象是类,则可以使用引用相等:

let idx = find(scores) { $0 === $1 }
Run Code Online (Sandbox Code Playgroud)


GoZ*_*ner 7

该函数的接口find是/是:

func find<C : CollectionType where C.Generator.Element : Equatable>(domain: C,
    value: C.Generator.Element) -> C.Index?
Run Code Online (Sandbox Code Playgroud)

这是说的CollectionTypeC话,必须要有元素Equatable,此外,该value还必须Equatable.

[ 注意Swift 3.0:从Swift 3.0开始,你需要使用有index两种变体的功能.在第一个中,您将提供自己的谓词:

func index(where: (Self.Generator.Element) -> Bool) -> Self.Index?
Run Code Online (Sandbox Code Playgroud)

在第二个中,您的元素需要是等同的:

// Where Generator.Element : Equatable
func index(of: Self.Generator.Element) -> Self.Index?
Run Code Online (Sandbox Code Playgroud)

如果您决定前往该equatable路线,则以下情况适用. 注意结束 ]

您的Score结构不是Equatable,因此错误. 你需要弄清楚分数是否相等才意味着什么. 也许这是一些数字'得分'; 也许它是'得分'和'用户ID'.这取决于你的Score抽象.一旦你知道,你实现==使用:

func == (lhs:Score, rhs:Score) -> Bool {
 return // condition for what it means to be equal
}
Run Code Online (Sandbox Code Playgroud)

注意:如果您使用class并且因此得分具有"身份",那么您可以将其实现为:

func == (lhs:Score, rhs:Score) -> Bool { return lhs === rhs }
Run Code Online (Sandbox Code Playgroud)

你的字符串示例String是因为Equatable.如果您查看Swift库代码,您将看到:

extension String : Equatable {}
func ==(lhs: String, rhs: String) -> Bool
Run Code Online (Sandbox Code Playgroud)