Swifter Swift必备Tips
1. 柯里化
func addTo(_ adder: Int) -> (Int) -> Int {
return { num in
adder + num
}
}
let addToOne = addTo(1)
let addToTwo = addTo(2)
print(addToOne(10)) // 11
print(addToTwo(10)) // 12
2. Sequence for-in迭代
struct IntArray: Sequence {
var array: [Int]
func makeIterator() -> IntArrayIterator {
return IntArrayIterator(array: array)
}
}
struct IntArrayIterator: IteratorProtocol {
var array: [Int]
var index = 0
mutating func next() -> Int? {
guard index < array.count else { return nil }
defer {
index += 1
}
return array[index]
}
}
let array = IntArray(array: [0, 1, 2, 3])
for item in array {
print(item)
}
3. 元组多返回值
func getColor() -> (R: Int, G: Int, B: Int) {
return (255, 255, 255)
}
print(getColor()) // (R: 255, G: 255, B: 255)
4. @autoclosure 自动闭包
func closure(_ number: @autoclosure () -> Int) -> Int {
let number = number()
return number
}
print(closure(3)) // 3
4. @escaping 逃逸闭包
import Dispatch
func asyncAfter(seconds: Int, execute: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(seconds)) {
execute()
}
}
asyncAfter(seconds: 3) {
print("3秒后执行")
}
5. 操作符重载
struct ValueInt {
let value: Int
static func +(left: ValueInt, right: ValueInt) -> Int {
left.value + right.value
}
}
let a = ValueInt(value: 1)
let b = ValueInt(value: 3)
print(a + b) // 4
6. 函数参数传递
-
值类型参数
不更改原值
func increased(_ variable: Int) -> Int { var variable = variable variable += 1 return variable } print(increased(0)) // 1
更改原值
func increase(_ variable: inout Int) { variable += 1 } var variable = 0 increase(&variable) print(variable) // 1
-
引用类型参数
不更改原值
class ReferenceInt { var value: Int init(_ value: Int) { self.value = value } } func increased(_ variable: ReferenceInt) -> ReferenceInt { let variable = ReferenceInt(variable.value) variable.value += 1 return variable } let variable = ReferenceInt(0) print(increased(variable).value) // 1 print(variable.value) // 0
更改原值
func increase(_ variable: ReferenceInt) { variable.value += 1 } let variable = ReferenceInt(0) increase(variable) print(variable.value)
7. 字面量表达协议
struct ValueInt: ExpressibleByIntegerLiteral {
var value: Int
init(integerLiteral value: IntegerLiteralType) {
self.value = value
}
}
let variable: ValueInt = 3
print(variable.value) // 3
8. subscript 下标访问
struct IntArray {
var array: [Int]
subscript(index: Int) -> Int {
get {
array[index]
}
set {
array[index] = newValue
}
}
}
var array = IntArray(array: [0, 1, 2, 3])
print(array[1]) // 1
array[3] = 4
print(array[3]) // 4
9. typealias 类型别名
typealias IntArray = Array<Int>
protocol A {
var a: Int { get }
}
protocol B {
var b: Int { get }
}
typealias C = A & B
struct D: C {
var a: Int
var b: Int
}
10. associatedType 相关类型
protocol ArrayExtension {
associatedtype T
mutating func appendAndPrint(_ newElement: T)
}
extension Array: ArrayExtension {
typealias T = Element
mutating func appendAndPrint(_ newElement: Element) {
print(newElement)
append(newElement)
}
}
var array = Array<Int>()
array.appendAndPrint(1) // 1
11. 可变参数
func sum(_ number: Int...) -> Int {
return number.reduce(0, +)
}
print(sum(0, 1, 2, 3)) // 6
12. 初始化顺序
class Rectangle {
var name: String
init() {
name = "长方形"
}
}
class Square: Rectangle {
var sideLength: Int
override init() {
sideLength = 10
super.init()
name = "正方形"
}
}
13. 可空初始化
struct PositiveNumberString {
var value: String
init?(_ value: Int) {
guard value > 0 else { return nil }
self.value = String(value)
}
}
let str = PositiveNumberString(-1)
print(str as Any) // nil
14. 函数默认参数
func printInt(_ value: Int = 0) {
print(value)
}
printInt() // 0
printInt(1) // 1
15. ... ..< 区间操作符
let range = 0..<3
let closedRange = 0...3
print([Int](range)) // [0, 1, 2]
print([Int](closedRange)) // [0, 1, 2, 3]
print(("a"..."z").contains("c")) // true
16. 元类型
struct Type {
static func staticMethod() {
print("静态方法")
}
func instanceMethod() {
print("实例方法")
}
}
let instance: Type = Type()
instance.instanceMethod() // 实例方法
let type: Type.Type = Type.self
type.staticMethod() // 静态方法
18. 属性观察
struct ValueInt {
var value: Int {
willSet {
print("值即将从\(value)更改为\(newValue)")
}
didSet {
print("值已经从\(oldValue)更改为\(value)")
}
}
}
var variable = ValueInt(value: 0)
variable.value = 1 // 值即将从0更改为1 \n 值已经从0更改为1
19. lazy 懒加载
struct LazyMan {
var food: String = {
print("吃饭")
return "食物"
}()
lazy var work: String = {
print("起床")
return "工作"
}()
}
var man = LazyMan() // 吃饭
print(man.work) // 起床 \n 工作
20. 懒实现序列
let array = [0, 1, 2, 3]
let result = array.lazy.map { item -> Int in
print("正在映射\(item)")
return item + 1
}
for item in result {
print("映射结果\(item)")
break
}
// 正在映射0
// 映射结果1
let array = [0, 1, 2, 3]
let result = array.map { item -> Int in
print("正在映射\(item)")
return item + 1
}
for item in result {
print("映射结果\(item)")
break
}
// 正在映射0
// 正在映射1
// 正在映射2
// 正在映射3
// 映射结果1
21. Optional Map
var variable: Int? = 0
let result = variable.map { variable in
variable + 1
}
print(result as Any) // Optional(1)
var variable: Int? = 0
var result: Int? = nil
if let variable = variable {
result = variable + 1
}
print(result as Any) // Optional(1)
22. where 模式匹配
let model = "iPhone12 mini"
switch model {
case let model where model.hasPrefix("iPhone"):
print("iPhone")
default:
break
}
// iPhone
for i in 0..<10 where i < 3 {
print(i)
}
// 0 \n 1 \n 2
23. indirect 嵌套enum
indirect enum LinkedNode {
case empty
case node(Int, LinkedNode)
}
let linkedList = LinkedNode.node(0, .node(1, .node(2, .empty)))
print(linkedList) // node(0, node(1, .node(2, .empty)))
24. 实例方法的其它调用方式
struct ValueInt {
let value: Int
func call(_ way: String) {
print(self.value, way)
}
}
let v0 = ValueInt(value: 0)
v0.call("(value:)") // 0 (value:)
let v1 = ValueInt.init(value: 1)
v1.call(".init(value:)") // 1 .init(value:)
ValueInt.call(v0)("ValueInt.call(_ self:)") // 0 ValueInt.call(_ self:)
let call = ValueInt.call
call(v0)("call(_ self:)") // 0 call(_ self:)
25. 单例模式
struct Singleton {
static let shared = Singleton()
}
26. 条件编译
#if os(iOS) || os(tvOS)
import UIKit
#elseif os(watchOS)
import WatchKit
#elseif os(macOS)
import AppKit
#endif
27. 注释标记
// MARK: - 分割线
// TODO: 待办
// FIXME: 待修复
28. 可选协议
import Foundation
// objc标记的协议只能被class类实现
@objc protocol OptionalProtocol {
@objc optional func optionalMethod()
}
使用协议扩展来实现可选协议
protocol OptionalProtocol {
func optionalMethod()
}
extension OptionalProtocol {
func optionalMethod() {
}
}
29. 判断实例类型
print(type(of: 1)) // Int
print(1 is Int) // true
30. == === 判断相等
class ReferenceInt {
var value: Int
init(_ value: Int) {
self.value = value
}
static func ==(left: ReferenceInt, right: ReferenceInt) -> Bool {
return left.value == right.value
}
}
let a = ReferenceInt(0)
let b = ReferenceInt(0)
print(a == b) // true
print(a === b) // false
31. 格式化字符串
import Foundation
print(String(format: "%.2f", 3.333333)) // 3.33
32. OptionSet 操作集合
struct Options: OptionSet {
let rawValue: Int
static let left = Options(rawValue: 1)
static let top = Options(rawValue: 1 << 1)
static let right = Options(rawValue: 1 << 2)
static let bottom = Options(rawValue: 1 << 3)
}
var option: Options = .left
print(option) // Options(rawValue: 1)
option = .top
print(option) // Options(rawValue: 2)
option = .right
print(option) // Options(rawValue: 4)
option = .bottom
print(option) // Options(rawValue: 8)
option = [.left, .top]
print(option) // Options(rawValue: 3)
option = [.left, .top, .right, .bottom]
print(option) // Options(rawValue: 15)
33. enumerate 数组列举
for (index, item) in (10..<13).enumerated() {
print(index, item)
}
// 0 10 \n 1 11 \n 2 12
34. Associated Object扩展存储属性
import ObjectiveC
// 只能为class类扩展
class IPhone {
}
private var key: Void?
extension IPhone {
var storage: Int? {
get {
return objc_getAssociatedObject(self, &key) as? Int
}
set {
objc_setAssociatedObject(self, &key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
var iPhone = IPhone()
print(iPhone.storage as Any) // nil
iPhone.storage = 128
print(iPhone.storage as Any) // Optional(128)
35. Lock 锁
import Foundation
func synchronized(_ lock: AnyObject, execute: () -> Void) {
objc_sync_enter(lock)
execute()
objc_sync_exit(lock)
}
class SafeData {
var data = 0
func add(_ number: Int) {
synchronized(self) {
data += number
}
}
}
let safeData = SafeData()
for _ in 0..<10000 {
DispatchQueue.global().async {
safeData.add(1)
}
}
print(safeData.data) // 10000
36. 编译符号
#file // 符号所在文件路径
#line // 符号所在行号
#column // 符号所在列
#function // 符号所在方法名
37. 溢出操作符
var max = UInt.max
print(String(max, radix: 2))
// 1111111111111111111111111111111111111111111111111111111111111111
max = max &+ 1
print(String(max, radix: 2)) // 0
38. 属性访问控制
private
fileprivate
internal
public
open
39. Swift解释执行
#!/usr/bin/env swift
print("hello")
40. swiftc编译
swiftc main.swift
41. 自定义打印输出
struct ValueInt: CustomStringConvertible {
let value: Int
var description: String {
return "这是一个自定义的描述\(value)"
}
}
print(ValueInt(value: 1)) // 这是一个自定义的描述1
42. 断言
// 断言只在Debug模式下有效
assert(1 == 1)
43. 错误退出
fatalError()
44. 指针操作
//#include "stdio.h"
//
//int main() {
// int a[] = {0, 1, 2};
// int *p = a;
// *(p+2) = 3;
// for(int i; i < 3; i ++) {
// printf("%d\n", a[i]);
// }
// // 0 \n 1 \n 3 \n
// return 0;
//}
var array = [0, 1, 2]
let pointer = UnsafeMutableBufferPointer<Int>(start: &array, count: array.count).baseAddress
pointer?.advanced(by: 2).pointee = 3
print(array) // [0, 1, 3]
45. 条件协议扩展
protocol NumberProtocol {
}
extension Int: NumberProtocol {}
extension NumberProtocol where Self == Int {
func int() {
print("只有Int类型才可以有此方法")
}
}