Pattern match with case class
-
Upload
kai-sasaki -
Category
Documents
-
view
1.837 -
download
2
Transcript of Pattern match with case class
Pattern match with case class
佐々木 海(Sasaki Kai) 第2回Swift勉強会
@TechBuzzSpace
Who am I?佐々木 海(Sasaki Kai)
@Lewuathe
プラットフォームエンジニア
emailとか、Push通知とか
C/C++, nodejs, Python
iOSアプリは普段作ってません
Topic
ケースクラスを使ったパターンマッチを Swiftで実装してみた話
What is case class?Scalaに組み込みの仕組み
!
!
クラス名の前にcaseキーワード
abstract class Expr case class Var(name: String) extends Expr case class Number(num: Double) extends Expr
Why case class?ファクトリメソッドの生成
Why case class?ファクトリメソッドの生成
constant memberの生成
Why case class?ファクトリメソッドの生成
constant memberの生成
toString,equalsとかの実装
Why case class?ファクトリメソッドの生成
constant memberの生成
toString,equalsとかの実装
コンストラクタパターン
What is constructor pattern?
case class User(name: String, age: Int){} !!!
What is constructor pattern?
case class User(name: String, age: Int){} !val you = User(“Nobita”, 12) !!!
What is constructor pattern?
case class User(name: String, age: Int){} !val you = User(“Nobita”, 12) !you match { case User(“Takeshi”, 13) => “He is Takeshi” case User(“Nobita”, 12) => “He is Nobita” case _ => “Who is he?” } !
What is constructor pattern?要するに
!
コンストラクタに渡された引数リストで パターンマッチを行う仕組み
BTW, Swift?Swiftではパターンマッチが使える
switch文
loop
変数binding
tuple, identifier
BTW, Swift?
でもコンストラクタパターンは使えない
SwiftCaseコンストラクタパターンによるマッチングをするためのライブラリ
https://github.com/Lewuathe/SwiftCase
How to useclass User: SwiftCase { let name: String let age: Int ! init(name: String, age: Int) { self.name = name self.age = age super.init(name, age) } } !
How to useclass User: SwiftCase { let name: String let age: Int ! init(name: String, age: Int) { self.name = name self.age = age super.init(name, age) } } !
SwiftCaseを継承させる
How to useclass User: SwiftCase { let name: String let age: Int ! init(name: String, age: Int) { self.name = name self.age = age super.init(name, age) } } !
SwiftCaseを継承させる
superクラスのinitializerに
パラメタリストを渡す
How to uselet user = User(name: “Nobita”, 12) !switch user { case User(name: “Takeshi”, age: 13): println(“He is Takeshi”) case User(name: “Nobita”, age: 12): println(“He is Nobita”) case default: println(“Who is he?”) } !// -> He is Nobita !
How to uselet user = User(name: “Nobita”, 12) !switch user { case User(name: “Takeshi”, age: 13): println(“He is Takeshi”) case User(name: “Nobita”, age: 12): println(“He is Nobita”) case default: println(“Who is he?”) } !// -> He is Nobita
直書き
Recursive matchclass UserPair: SwiftCase { let first: User let second: User ! init(first: User, second: User) { self.first = first self.second = second super.init(first, second) } } !
メンバにUser型
Recursive matchclass UserPair: SwiftCase { let first: User let second: User ! init(first: User, second: User) { self.first = first self.second = second super.init(first, second) } } !
メンバにUser型
superクラスのinitializerに
パラメタリストを渡す
Recursive matchlet nobi = User(name: “Nobita”, 12) let take = User(name: “Takeshi”, 13) !!let userPair = UserPair(first: nobi, second: take) !!
Recursive matchswitch userPair { case User(“Takeshi”, 13): println(“He is Takeshi”) case UserPair(User(name: “Nobita”, age: 100), User(name: “Takeshi”, age: 99)): println(“They are too old”) case UserPair(User(name: “Nobita”, age: 12), User(name: “Takeshi”, age: 13)): println(“Yes, that’s right”) case default: println(“Who are they?”) } !
Recursive matchswitch userPair { case User(“Takeshi”, 13): println(“He is Takeshi”) case UserPair(User(name: “Nobita”, age: 100), User(name: “Takeshi”, age: 99)): println(“They are too old”) case UserPair(User(name: “Nobita”, age: 12), User(name: “Takeshi”, age: 13)): println(“Yes, that’s right”) case default: println(“Who are they?”) } !
Recursive matchswitch userPair { case User(“Takeshi”, 13): println(“He is Takeshi”) case UserPair(User(name: “Nobita”, age: 100), User(name: “Takeshi”, age: 99)): println(“They are too old”) case UserPair(User(name: “Nobita”, age: 12), User(name: “Takeshi”, age: 13)): println(“Yes, that’s right”) case default: println(“Who are they?”) } !
メンバのメンバとmatch
Why SwiftCase?
コンストラクタパターンによるマッチング
SwiftCase同士での再帰的なマッチング
TipsExpression pattern
Type casting pattern
Equitable Protocol
Variadic Parameters
Expression Patternswitch文のパターンマッチで呼ばれる
func ~= (c1: SwiftCase, c2: SwiftCase)-> Bool { return internalMathcing(c1, c2) }
Typecasting Patternある型としてその変数が利用できるかを判定できる
let m = matchArr[i] as? SwiftCase
optional typeとしてcastした結果を返してくれる
Equitable Protocol== 演算子を定義している
今回matchingに==を使っている
Equitable Protocol== 演算子を定義している
今回matchingに==を使っている
NSObjectのサブクラスに対して
Equitable Protocol== 演算子を定義している
今回matchingに==を使っている
NSObjectのサブクラスに対して
AnyはEquitableでない
Variadic Parameters可変長引数
init(_ params: NSObject...) { // Do something }
NSObjectのコレクション型
Variadic Parameters可変長引数
init(_ params: NSObject...) { // Do something }
NSObjectのコレクション型
名前付きパラメタを要求しない
In Conclusionコンストラクタパターンは便利
Advanced Swiftの内容がよくわかった
できれば変数束縛も実装したい(たぶんできない)
ReferenceThe Swift programming language
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/index.html#//apple_ref/doc/uid/TP40014097
Advanced Swift
https://developer.apple.com/videos/wwdc/2014/?id=404
Thank you