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:
// 利用 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 |
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] { |
I hereby claim:
To claim this, I am signing this object:
// 想像以下 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 | |
} | |
} |
// 有 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) |
/* | |
* Standard library 有個 protocol `CustomStringConvertible`,需要實作 `description: String` 來將一個物件轉化成 description string | |
* 但是若你對同一個物件想要有兩種描述方式,比如 | |
* 想要用 JSON 的方式印出來 model 的所有 property,且希望有的時候是 pretty printed 有的時候是 sorted key 怎麼辦? | |
* 你會需要有兩個物件來遵守 CustomStringConvertible,因為一個 protocol 在一個物件裡只能有一種實作 | |
* 然而用 generic struct 的話就能做到這件事 | |
* 下面的實例中你可以宣告兩個不同的 instance ,`prettyPrintedDescribing` 和 `sortedKeyDescribing` | |
* 想用哪個就用哪個,方便多了,也讓 compiler 有更多參與最佳化的空間 | |
* | |
*/ |
func getProcessStartTime() -> TimeInterval { | |
let pid = ProcessInfo.processInfo.processIdentifier | |
var procInfo = kinfo_proc() | |
var cmd: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, pid] | |
var size = MemoryLayout.stride(ofValue: procInfo) | |
if sysctl(&cmd, UInt32(cmd.count), &procInfo, &size, nil, 0) == 0 { | |
// tv_sec is timestamp measured in second; tv_usec is the rest fraction part in microsecond | |
return Double(procInfo.kp_proc.p_un.__p_starttime.tv_sec) * 1000.0 + Double(procInfo.kp_proc.p_un.__p_starttime.tv_usec) / 1000.0 | |
} else { | |
print("Can't get information of process \(pid)") |
###################### | |
# Create log file | |
###################### | |
exec > ~/Desktop/tmp/UniversalBuild_Log_$(date +"%Y%m%d%H%M%S").log 2>&1 | |
###################### |
import Foundation | |
import RxSwift | |
// MARK: Model | |
struct User: Decodable { | |
let id: Int | |
let name: String | |
} | |
let usersDecode: (Data) -> [User]? = { data in |
// From: | |
protocol Drawable { | |
func draw() | |
} | |
// To: | |
struct Drawing<Shape> { | |
var draw: (Shape) -> () | |
} |