Skip to content

Instantly share code, notes, and snippets.

@ezura
Last active June 15, 2017 09:36
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ezura/f5aebef7bb86edbfd40b0bd1d0435e00 to your computer and use it in GitHub Desktop.
Save ezura/f5aebef7bb86edbfd40b0bd1d0435e00 to your computer and use it in GitHub Desktop.
Phantom Type @iosdc
/*:
## Reference
* [Swift: Money with Phantom Types](https://www.natashatherobot.com/swift-money-phantom-types/)
* [Swift で Phantom Type (幽霊型)](http://qiita.com/taketo1024/items/71e3272211f08d7e0cde)
* [Functional Snippet #13: Phantom Types](https://www.objc.io/blog/2014/12/29/functional-snippet-13-phantom-types/)
* [Phantom Typeでコンパイル時に状態チェックする: shibuya.swift #4](https://speakerdeck.com/kazuhiro4949/phantom-typedekonpairushi-nizhuang-tai-tietukusuru-shibuya-dot-swift-number-4)
*/
import Foundation
protocol OperationState {}
class Init: OperationState {}
class Prepared: OperationState {}
private struct OperationData {
}
class HogeOperation<State: OperationState> {
private var data: OperationData
private init(data: OperationData) {
self.data = data
}
/// いつ呼んでも良い
func mob() {}
}
extension HogeOperation where State: Init {
/// 一度だけ呼ぶこと
@warn_unused_result(message="返り値: 準備済みのインスタンス")
func prepared() -> HogeOperation<Prepared> {
let readyOp = HogeOperation<Prepared>(data: data) // 必要なデータを引き継ぎ
return readyOp
}
convenience init() {
self.init(data: OperationData())
}
}
extension HogeOperation where State: Prepared {
/// prepare 後に呼ぶこと
func execute() {
/* do somethig */
}
}
let operation = HogeOperation<Init>()
// error: 'Init' is not a subtype of 'Prepared'
//operation.execute()
let preparedOp = operation.prepared()
preparedOp.mob()
preparedOp.execute()
preparedOp.mob()
preparedOp.execute()
preparedOp.execute()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment