I hereby claim:
- I am pofat on github.
- I am pofat (https://keybase.io/pofat) on keybase.
- I have a public key ASDG9WSBfhua2AKTJqJhSDqdAuCPFwSEfVnVlhryt9fTVQo
To claim this, I am signing this object:
| /* | |
| * Standard library 有個 protocol `CustomStringConvertible`,需要實作 `description: String` 來將一個物件轉化成 description string | |
| * 但是若你對同一個物件想要有兩種描述方式,比如 | |
| * 想要用 JSON 的方式印出來 model 的所有 property,且希望有的時候是 pretty printed 有的時候是 sorted key 怎麼辦? | |
| * 你會需要有兩個物件來遵守 CustomStringConvertible,因為一個 protocol 在一個物件裡只能有一種實作 | |
| * 然而用 generic struct 的話就能做到這件事 | |
| * 下面的實例中你可以宣告兩個不同的 instance ,`prettyPrintedDescribing` 和 `sortedKeyDescribing` | |
| * 想用哪個就用哪個,方便多了,也讓 compiler 有更多參與最佳化的空間 | |
| * | |
| */ |
| // 會帶真實型別進去 | |
| func doSomething<T: MyPotocol>(_ arg: T) { } | |
| // 有 existentail container | |
| func doSomething(_ arg: MyProtofcol) { } |
| import Foundation | |
| // struct for printing out instance address | |
| struct MemoryAddress<T>: CustomStringConvertible { | |
| let intValue: Int | |
| var description: String { | |
| let length = 2 + 2 * MemoryLayout<UnsafeRawPointer>.size | |
| return String(format: "%0\(length)p", intValue) | |
| } |
| // 有 associatedtype 的 protocol | |
| public protocol IteratorProtocol { | |
| associatedtype Element | |
| mutating func next() -> Element? | |
| } | |
| // 有 Self 的 protocol, Hashable 的 Self 來自所繼承的 Equatable | |
| public protocol Hashable: Equatable { | |
| var hashValue: Int { get } | |
| func hash(into hasher: inout Hasher) |
| // 利用 init with closure 來自動代入 `Element` 真實的型別,而不是直接用 <某型別> 的方式來指定 | |
| // 先宣告一個 generic struct | |
| struct MyAnyIterator<Element> { | |
| // 內部使用的 Box ,裡面就是把 closure 存起來,本身也滿足 IteratorProtocol | |
| private class AnyIteratorBox<Element>: IteratorProtocol { | |
| typealias Base = () -> Element? | |
| private var _base: Base | |
| init(_ base: @escaping Base) { | |
| self._base = base |
| // 想像以下 function 定義在某一個 module 裡,外部無法決定也不依賴具體的型別 (此 func 你可以呼叫但裡面實作看不到) | |
| func getIterator() -> some IteratorProtocol { | |
| var state = (0, 1) | |
| return MyAnyIterator { () -> Int in | |
| let upcomingNumber = state.0 | |
| state = (state.1, state.0 + state.1) | |
| return upcomingNumber | |
| } | |
| } |
I hereby claim:
To claim this, I am signing this object:
| enum Either<A, B> { | |
| case left(A) | |
| case right(B) | |
| } | |
| extension Either: Decodable where A: Decodable, B: Decodable { | |
| init(from decoder: Decoder) throws { | |
| let container = try decoder.singleValueContainer() | |
| if let a = try? container.decode(A.self) { | |
| self = .left(a) |
| import Foundation | |
| // Time Complexity: O(N), N stands for the level of key path | |
| extension Dictionary where Key == String { | |
| subscript(keyPath keyPath: String) -> Any? { | |
| get { | |
| guard !keyPath.isEmpty else { return nil } | |
| var value: Any? = self | |
| for key in keyPath.components(separatedBy: ".") { | |
| if let node = (result as? [Key: Any])?[key] { |
| import Foundation | |
| import UIKit | |
| UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, NSStringFromClass(UIApplication.self), NSStringFromClass(AppDelegate.self)) | |
| // Remeber to comment or remove `@UIApplicationMain` in your AppDelegate.swift |