Swift 无法使用类型为“([Score],Score)"的参数列表调用“find",其中 Score 是一个结构 [英] Swift Cannot invoke 'find' with an argument list of type '([Score], Score)' where Score is a struct

查看:33
本文介绍了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 的答案可能会很好地工作,但我建议您在选择这样做之前要小心.原因是,正如文档所述,等式意味着可替代性,并且您的 == 运算符必须是自反的、对称的和可传递的.如果你不遵守这一点,在使用 equalssort 等算法时可能会出现一些非常奇怪的行为.在实现 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 是一个结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆