Swift学习笔记(1)
之前也有一篇学习笔记,后来发现如果这样学习下去,明年这个时候都很难出师(老师=互联网上海量的资料及乐于分享知识的各位大牛)。意识到这个问题是因为这几天我在阅读一本书《禅与摩托车维修艺术》及看完 iOS开发和七七八八
上的字符串学习笔记。原来我对语言的认识只停留在教材文字的表面,而文字背后的东西却不得而知。编程是一门艺术,不是语法的堆砌,如果没有了解语言的内涵及工作原理,那么写出来的代码不是生涩难懂毫无美感就是效率低下。所以,从决定学习iOS编程到现在两个月的时间过去了,我选择推倒一切,从零开始。之前的那篇笔记我没有删除,但做了标注。
另外:从这篇笔记开始采用Todo的模式来组织文字,做笔记的同时通过GTD的方式来管理及统计学习的过程,这在orgmode中实现是轻而易举的事情。
TODO 字符串[String]
nil | 1:56 | ||
TODO 字符串[String] | 1:56 | ||
TODO 待解决的问题 | 0:04 | ||
DONE 上下标的问题 | 0:04 | ||
知识点 | 1:52 |
TODO 待解决的问题
DONE 上下标的问题
- State "DONE" from "TODO"
字符串“xiaoguo”的上标为0,下标为7,而字符串长度也为7,那最后一个下标所指向的是什么呢?如果是 \n
,那又该如何验证呢?
let str = "xiaoguo" let i = str.endIndex print(str[i]) // fatal error: Can't form a Character from an empty String // 这里说明是一个空字符串
原因如下:使用startIndex属性可以获取一个String的第一个Character的索引。使用endIndex属性可以获取最后一个Character的后一个位置的索引。因此,endIndex属性不能作为一个字符串的有效下标。如果String是空串,startIndex和endIndex是相等的。
DONE Index类型实际上是什么
- State "DONE" from "TODO"
通过startIndex和endIndex获得的上下标不是Int类型,而是Index类型,这个Index类型到底是个什么东东?
通过String定义可以看出属性Index是个结构体,具体代码如下:
extension String : CollectionType { struct Index : BidirectionalIndexType, Comparable, Reflectable { func successor() -> String.Index func predecessor() -> String.Index func getMirror() -> MirrorType } var startIndex: String.Index { get } var endIndex: String.Index { get } subscript (i: String.Index) -> Character { get } func generate() -> IndexingGenerator<String> }
TODO 作业,从包含多个‘hi’的字符串中提取所有的‘hi’,返回一个包含range范围的数组
DONE 实现字符串的反转,“abc” -> “cba”
var stringReverse = "abcdefghijklmnopqrstuvwxyz" var characterArray = [Character]() for c in stringReverse.characters { characterArray.append(c) } // $0 指累加器(accumulator),$1 指遍历数组得到的一个元素 stringReverse = String(characterArray.reduce([Character](), combine: {[$1] + $0})) print(stringReverse)
知识点
- Swift 中 String 是 struct
- Swfit里面的String很有意思,它并不是由很多个Character组成的,而是在其上面又封装了一些东西。另外因为要兼容不同的编码,每个组成字符所占的内存也不一样(例如中文和英文的区别),所以它的下标并不是一个Int型,也不能通过下标来直接定位、获取字符。
- 字符串最常用的两个参数:下标(Index)和范围(Range),几乎所有API都要用到它们。
- 删除字符串中的某个字符或者连续的几个字符,需要通过获得Index和Range来进行。
字符串中检索某个单词方法:rangeOfString
var str = "Hello Apple.Hello Swift" str.rangeOfString("Hello")//正向检索; str.rangeOfString("Hello", options: NSStringCompareOptions.BackwardsSearch)//反向检索; str.rangeOfString("swift")//大小写完全匹配 str.rangeOfString("swift", options: NSStringCompareOptions.CaseInsensitiveSearch)//忽略大小写
返回值是一个Range范围,这里有两个‘Hello’,无论是正向还是反向检索都只能返回一个range。
截取子串
var str = "Hello Apple.Hello Swift" var toIndex = advance(str.startIndex, 4) str.substringToIndex(toIndex)//截取从开始到第4个位置的字符串; var fromIndex = advance(str.startIndex, 7) str.substringFromIndex(fromIndex)//截取从第7个位置开始到最后的字符串; str.substringWithRange(Range<String.Index>(start: toIndex, end: fromIndex))//截取从第4个位置到第7个位置的字符串;
截取之后,原来的字符串不变。
替换字符串
思路,得到所有需要替换的字符串,把每个字符串的range保存进数组,然后挨个替换。