swifter技巧(100)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swifter技巧(100)相关的知识,希望对你有一定的参考价值。
一、swift新元素
Tip1:柯里化 将方法进行柯里化,把接受多个参数的方法变换成接受第一个参数的方法,并且返回接受余下的参数,返回结果的新方法。
func addTwoNumbers(a: Int)(num: Int) -> Int {
return a + num
}
let addToFour = addTwoNumbers(4)
let result = addToFour(num: 6)
func greaterThan(comparor: Int)(input: Int) -> Bool {
return input > comparor
}
let greaterThan10 = greaterThan(10);
greaterThan10(input: 13)
greaterThan10(input: 9)
将selector进行柯里化:
protocol TargetAction {
func performAction()
}
struct TargetActionWrapper<T: AnyObject>: TargetAction {
weak var target: T?
let action: (T)->()->()
func performAction() -> () {
if let t = target{
action(t)()
}
}
}
enum ControlEvent {
case TouchUpInside
case ValueChanged
}
class Control{
var actions = [ControlEvent: TargetAction]()
func setTarget<T: AnyObject>(target: T, action: (T)-> ()->(),controlEvent:ControlEvent) {
actions[controlEvent] = TargetActionWrapper(target: target, action: action)
}
func removeTargetForControlEvent(controlEvent: ControlEvent){
actions[controlEvent] = nil
}
func performActionForControlEvent(controlEvent: ControlEvent){
actions[controlEvent]?.performAction()
}
}
Tip2 将protocol的方法声明为mutating
mutating为了能在这个方法修改struct或者enum的变量,如果没有 在接口里写mutating的话,别人如果用struct或者enum来实现这接口就不能在方法里改变自己的变量
protocol Vehicle {
var numberOfWheels: Int {get}
var color: UIColor {get set}
mutating func changeColor()
}
struct MyCar: Vehicle {
let numberOfWheels = 4
var color = UIColor.blueColor()
mutating func changeColor() {
color = UIColor.redColor()
}
}
如果把mutating去掉,会报错说mycar过不了编译,不能改变结构体成员,添加后,会说没有实现Vehicle 这个接口
Tip3 sequence
/*
先定义一个实现了GeneratorType protocol 的类型,
GeneratorType需要指定一个 typealias Element
以及提供返回一个Element?的方法 next()
*/
class ReverseGenerator: GeneratorType {
typealias Element = Int
var counter: Element
init<T>(array: [T]){
self.counter = array.count - 1
}
init(start: Int){
self.counter = start
}
func next() -> Element? {
return self.counter < 0 ? nil : counter--
}
}
/*
然后定义一个实现了sequenceType
需要指定一个 typealias Generator
以及提供返回一个Generator?的方法 generate()
*/
struct ReverseSequence<T>: SequenceType {
var array: [T]
init(array: [T]){
self.array = array
}
typealias Generator = ReverseGenerator
func generate() -> Generator {
return ReverseGenerator(array: array)
}
}
let arr = [0,1,2,3,4];
for i in ReverseSequence(array: arr){
print("index \(i) is \(arr[i])")
}
Tip4 多元组Tuple
OC的时候是:
func swapMe<T>(inout a: T, inout b: T){
let temp = a
a = b
b = temp
}
引入多元组的概念后就更简单了:
func swapMe<T>(inout a: T, inout b: T){
(a,b) = (b,a)
}
还有一个常用的地方错误的处理,OC时代习惯在需要错误处理时候先做一个NSError的指针,然后把地址传到方法里等待填充。
如:NSError *error = nil;
Bool success = [[NSFileManager defaultManager]moveItemAtPath:@"/path/to/target" toPath:@"/path/to/destination" error:&error];
if(!success){
NSLog(@"%@",error);
}
引入多元组之后,这样写:
func doSomethingMightCauseError() ->(Bool,NSError?){
//。。。 做某些操作,成功结果放在succe中
if success {
return (true,nil)
}else{
return(false,NSError(domain: "SomeErrorDomain",code: 1,userInfo: nil))
}
}
//调用函数
let (success,maybeError) = doSomethingMightCauseError()
if let error = maybeError{
//发生了错误
}
Tip 5 @autoclosure 和??操作符
@autoclosure做的事情就是把一句表达式自动封装包成一个闭包
func logIfTrue(predicate: () ->Bool){
if predicate() {
print("True")
}
}
logIfTrue{2>1}
类似上面的例子,我们牙根看不明白是闭包,和函数很像,这时候@autoclosure就派上用场了。
func logIfTrue(@autoclosure predicate: () ->Bool){
if predicate() {
print("True")
}
}
logIfTrue(2>1)
最后一句提醒:@autoclosure并不支持带有输入参数的写法,也就是说只有形如()->T的参数才能使用这个特性进行简化。
Tip6 optional Chaning
以上是关于swifter技巧(100)的主要内容,如果未能解决你的问题,请参考以下文章
一个Swifter的Kotlin学习——Kotlin 基本语法
[.NET 开源] 高性能的 Swifter.MessagePack 已发布,并附带新版本的 Swifter.Json 和 Swifter.Data。