最近重点看了一些关于Swift4及iOS11新特性的资料,所以准备做一些总结及笔记,内容主要来自前一阵买的iOS 11 by Tutorials一书及WWDC2017的视频,可能一次性的总结不会特别全面,后面也会根据新的发现进行补充,为自己这阵的学习做一个总结,也为想了解相关知识的同学提供一个入口。
One-sided ranges
Swift4中新增RangeExpression协议,这个协议x新增了简单办法去声明 one-sided range。
具体应用如下:
let range = 3...
let arr = ["a", "b", "c", "d", "e"]
print(arr[range])
//["d", "e"]
print(arr[..<2])
//["a", "b"]
神奇的创建sequences的方式
let arr = ["a", "b", "c", "d", "e"]
let asciiCodes = zip(97..., arr)
print(Array(asciiCodes))
//[(97, "a"), (98, "b"), (99, "c"), (100, "d"), (101, "e")]
在switch表达式中的应用
func findIntRange(_ index: Int) {
switch index {
case ...4:
print("小于4")
case 6...:
print("大于6")
default:
print("应该是5")
}
}
func findFloatRange(_ index: CGFloat) {
switch index {
case ...3.9:
print("小于3.9")
case 5.2...:
print("大于5.2")
default:
print("应该是...")
}
}
String
- 1
在Swift1中就引入了像操作一个collection一样去操作String的概念,现在这个概念被进一步增强了,许多collection上的功能在String上都可以应用
let str = "I am Swift Coder"
print(str.count)
// 16
// 默认为Unicode编码,无论是字母,汉字或是emoji长度都按照1计算
str.isEmpty
// false
let emos = "😀😂😇😌😙😝🧐😏"
for emo in emo { print(emo) }
同样可以用下标(subscript)去操作String,但是但是这里的下标不是Int,而是String.Index 或者 Range<String.Index>
let index = str.index(str.endIndex, offsetBy: -4)
let subStr = str[index...]
print(str[index])
//o
print(subStr)
//oder
print(str[..<index])
//I am Swift C
为了通过下标操作String时更高效及快速,Swift4中新增了Substring类型。
When you create a slice of a string, a Substring instance is the result. Operating on substrings is fast and efficient because a substring shares its storage with the original string. The Substring type presents the same interface as String, so you can avoid or defer any copying of the string’s contents.
-
2: Substring
新的Substring和String共享相同的API,当你通过下标去访问字符串时,其实就创建了一个 Substring类型
let subStr = str[index...]
print(type(of: subStr))
//Substring
//Substring 转换为String
let str = String(subStr)
-
3: Range<String.Index> 与 NSRange
苹果在Swift中对range进行了重新的定义,取名Range,用来代替Objective-C中NSRange,但是在一些 Foundation 的API中(比如:NSRegularExpression, NSAttributedString, NSLinguisticTagger)仍然要求用NSRange,因此在用Swift变成时,需要在Range 和 NSRange中进行相互转换...头疼所在。
下面小总结了下两者中转换的方法:
Swift3
//range转换为NSRange
extension String {
func nsRange(from range: Range<String.Index>) -> NSRange {
let from = range.lowerBound.samePosition(in: utf16)
let to = range.upperBound.samePosition(in: utf16)
return NSRange(location: utf16.distance(from: utf16.startIndex, to: from),
length: utf16.distance(from: from, to: to))
}
}
//NSRange转化为range
extension String {
func range(from nsRange: NSRange) -> Range<String.Index>? {
guard
let from16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location, limitedBy: utf16.endIndex),
let to16 = utf16.index(from16, offsetBy: nsRange.length, limitedBy: utf16.endIndex),
let from = String.Index(from16, within: self),
let to = String.Index(to16, within: self)
else { return nil }
return from ..< to
}
}
Swift4
官方提供了新的API(良心呀):
let text = "aaa123aaa"
///Range
var range = text.range(of: str)
///Range to NSRange
let nsRange = NSRange.init(range, in: text)
/**
*方便又快捷,同样的 NSRange to Range
*Range.init(range: NSRange, in: String)
*妈妈再也不担心
*/
网友评论