Swift中集合类型indexOf(Element)提示错误的解决办法
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.
如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;)
初学Swift,会遇到一些潜在的小问题,比如我们在某个集合对象中查找一个元素的时候会用到indexOf方法.
在API文档里可以看到该方法有2个重载:
indexOf(_: (Self.Generator.Element) throws -> Bool) rethrows -> Self.Index?
indexOf(_: Self.Generator.Element) -> Self.Index?
Default Implementation
可以看到一个简单,一个复杂.我们这次把简单的留到后面先看复杂的那个方法签名,也就是第一个.该方法需要传递一个闭包,该闭包有唯一一个参数为Self.Generator.Element类型,返回一个Bool类型.
下面我们在playground里写一个测试类Person:
class Person{
let name:String
let age:Int
init(name:String,age:Int){
self.name = name
self.age = age
}
}
接下来我们创建一个包含2个Person对象的数组people:
var p1 = Person(name: "Tom", age: 11)
var p0 = Person(name: "Bob", age: 121)
let people = [p0,p1]
然后我们想在people中找到name为Tom的Person,使用indexOf的第一种重载,可以这么写:
let idx = people.indexOf({(p:Person) in
return p.name == p1.name
})
不出意料,idx是1,我们还可以写的更简单些:
let idx = people.indexOf {$0.name == p1.name}
好了,现在复杂的搞定了,回过头再看看那个简单的重载,我们直接这样调用:
let idx = people.indexOf(p0)
神马!?简单的竟然出错了!
这该如何是好?其实看一下错误描述,大概就可以猜到Swift此时不知道你自定义类是如何比较的,如果是Swift内置的各种struct和class就不存在这个问题,比如:
var ary = [1,2,3,4]
let idx = ary.indexOf(3) //idx will be 2
解决很简单,添加一个==方法即可:
class Person:Equatable {
let name:String
let age:Int
init(name:String,age:Int){
self.name = name
self.age = age
}
}
func ==(p0:Person,p1:Person)->Bool{
return p0.name == p1.name && p0.age == p1.age
}
var p1 = Person(name: "Tom", age: 11)
var p0 = Person(name: "Bob", age: 121)
let people = [p0,p1]
let idx = people.indexOf(p0)
最后补充一下,早期版本的Swift还有一个find函数可以完成类似的功能,但是新版本已经没有该函数了,So你懂的…
Swift中集合类型indexOf(Element)提示错误的解决办法的更多相关文章
- “sockaddr”: “struct”类型重定义的错误的解决办法《转》
原帖地址:https://blog.csdn.net/clever101/article/details/100163301 windows.h和winsock2.h存在有类型重定义,往往体现在VC程 ...
- maven提示错误的解决办法
import或者new一个的maven project的时候,提示如下错误 Description Resource Path Location TypeCannot read ...
- 当AVPlayer在被释放之后,Player一直监听的时间没有被移除,提示错误的解决办法
Xcode Consolu打印出来的提示: An instance 0x156608c0 of class AVPlayer was deallocated while key value obser ...
- Vs Code在Vue项目中v-for指令提示错误的解决办法
最近在做一个Vue项目,在其中用到v-for指令时,发现Vs Code报错,如下图(代码是没有任何问题的),在网上找了一下解决办法,希望能帮助到更多人. 解决方法: 打开 文件-首选项-设置 将 ...
- “cvc-complex-type.2.4.a: Invalid content was found starting with element 'taglib'”错误的解决办法
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" ...
- VS Code使用.vue的v-for方法提示错误的解决办法
1.在使用v-for的时候在后面跟上:key="key" <div v-for="(value, key) in [1,2,3]" :key=" ...
- Xamarin 中Visual Studio创建项目提示错误
Xamarin 中Visual Studio创建项目提示错误 错误信息:Object reference not set to an instance of an object 出现这种情况,是由于没 ...
- Swift中的类型属性(静态变量)
http://blog.haohtml.com/archives/15098 Swift中的类型属性(静态变量) Posted on 2014/06/13 类型属性语法 在 C 或 Objective ...
- Hive中集合类型
Hive中集合类型 创建表,集合是以 - 分割的 数据文件 加载数据 查询数据 查询数组中第一个字段 再建一个表,使用map 查看数据文件 加载数据 查询数据 查询键值 创建表,struct类型 查看 ...
随机推荐
- [NOI2009]变换序列
Description Input Output Sample Input 5 1 1 2 2 1 Sample Output 1 2 4 0 3 HINT 30%的数据中N≤50: 60%的数据中N ...
- [Cqoi2010]扑克牌
Description 你有n种牌,第i种牌的数目为ci.另外有一种特殊的 牌:joker,它的数目是m.你可以用每种牌各一张来组成一套牌,也可以用一张joker和除了某一种牌以外的其他牌各一张组成1 ...
- STL注意比较函数
可重复插入?: set<int ,less_equal<int> >s; s.insert(10); s.insert(10); 第二次调用insert,集合回去确认10是否已 ...
- 运行C++程序是出现错误:cannot open Debug/1.exe for writing
今天,打开VC6.0环境编了个小程序,谁知给我报了“cannot open Debug/1.exe for writing”这样一个错,然后,我就纳闷了,这是什么错丫? 想了半天,后想通,为什么会这样 ...
- 修改firefox的默认缩放比
我们在使用firefox时,发现页面的缩放比只能一个一个手动调整,当跳转到新的页面时默认缩放比又还原了,这个时候又要重新调整,相当不方便. 下面介绍修改默认缩放比的方法: 首先,打开firefox,然 ...
- 微信内置浏览器 如何小窗不全屏播放视频?也可以尝试canvas.
设置属性: <video height="100%" width="100%" autoplay="autoplay" control ...
- samba服务器配置过程
SAMBA服务器配置 yum install samba samba-client samba-swat 改变文件权限及用户 vi /etc/samba/smb.conf d+G全删注释 复制下面代码 ...
- Spring Boot Cache Redis缓存
1.集成MyBatis 1.1.引入maven依赖 1.2.生成Mapper 具体可以看MyBatis Generator官网 http://www.mybatis.org/generator/run ...
- vue+node.js+webpack开发微信公众号功能填坑——v -for循环
页面整体框架实现,实现小功能,循环出数据,整体代码是上一篇 vue+node.js+webpack开发微信公众号功能填坑--组件按需引入 修改部门代码 app.vue <yd-flexbox&g ...
- CODEVS3269混合背包+二进制优化
codevs 3296 http://codevs.cn/problem/3269/ 题目描述 Description 背包体积为V ,给出N个物品,每个物品占用体积为Vi,价值为Wi,每个物品要么至 ...