swift

Swift 4中的新特性(Whatʼs New in Swift

2017-12-11  本文已影响10人  sayHellooX

最近重点看了一些关于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

在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.

新的Substring和String共享相同的API,当你通过下标去访问字符串时,其实就创建了一个 Substring类型

let subStr =  str[index...]
print(type(of: subStr))
//Substring
//Substring 转换为String
let str =  String(subStr)

苹果在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)
*妈妈再也不担心
*/
上一篇 下一篇

猜你喜欢

热点阅读