Copylight © Classmethod, Inc.
Swiftの新機能!
Optional
Classmethod, Inc!
!
安達 勇一  
1
Copylight © Classmethod, Inc.
プログラミング言語 Swift
・AppleがWWDC2014で発表!
・Xcode6-betaで利用可能!
・ライセンス開発者同士の議論はNDAから外れる模様!
・多くの言語のいいとこ取り!
2
Copylight © Classmethod, Inc.
新しい概念 Optional
var numberString: String? = “1111”
//{Some "1111"}
!
if let number = numberString?.toInt() {
(number * 2).description // "2222"
} else {
"failed"
}
3
Copylight © Classmethod, Inc.
新しい概念 Optional
var assumedNum: Int! = ”111”.toInt()
!
if assumedNum {
print(assumedNum) // 111
}
4
Copylight © Classmethod, Inc. 5
?
Copylight © Classmethod, Inc.
?のルール
6
・T?でenum Optional<T> のシンタックスシュガー!
・T型、T?型の双方が代入可能!
・値が存在しないかもしれないコンテキストが!
 型に含まれている(Haskell :Maybeモナド)!
Copylight © Classmethod, Inc.
?のルール
!
enum Optional<T>
7
enum Optional<T> {
case None //値が存在しない場合
case Some(T) //値が存在する場合
}
Copylight © Classmethod, Inc.
?のルール
!
代入!
!
!
!
!
8
var str: String? = "some string"
var temp = str
str = “string" //{Some “string"}
str = temp //{Some "some string"}
Copylight © Classmethod, Inc.
?のルール
9
・メソッドチェーンの際に?を挟むことで!
 None(= nil)の時は以降のメソッドが走らない!
 Some(T)の時はTに対して次のメソッドを適用する!
!
Copylight © Classmethod, Inc.
?のルール
!
メソッドチェーン!
!
!
!
!
10
var numStr: String? = "123"
var notNumStr: String? = "1s3"
var newNumStr: String? =
numStr?.toInt()?.description //{Some “123"}
var newNotNumStr: String? =
notNumStr?.toInt()?.description //nil
Copylight © Classmethod, Inc. 11
!
Copylight © Classmethod, Inc.
!のルール
12
・T!でstruct ImplicitlyUnwrappedOptional<T>!
 のシンタックスシュガー!
・T型、T?型の双方を代入可能!
・T?の型に!を適用すると!
 T?がSome(T)ならばTを返す!
    NoneならばRuntime Errorが起きる!
・Tに!を適用するとコンパイルエラー
Copylight © Classmethod, Inc.
!のルール
!
代入!
!
!
!
!
13
var num: Int! = 1111 // 1111
var notNumStr: String? = “1s3"
num = "128".toInt() // 128
num = notNumStr?.toInt() // nil
Copylight © Classmethod, Inc.
!のルール
!
T?型に!を適用する!
!
!
!
!
T型に!を適用する
14
var notNumStr: String? = "1s3"
var notNum: Int? = notNumStr?.toInt()
notNumStr! // "1s3"
var notInt: Int = notNum! // runtime error
var integer = 17
17! // !の適用先が違うとコンパイラに怒られる
Copylight © Classmethod, Inc.
!のルール
15
!
・型そのものと、値を取得するときの返り値が異なる!
 Tを代入した時はTを返す!
 T?を代入した時、その中身がSome(T)ならばTを返す!
               Noneならばnil(=T?)を返す!
・この仕組が暗黙的アンラップ型と呼ばれる所以
Copylight © Classmethod, Inc.
!のルール
!
代入!
!
!
!
!
16
var num: Int! = 1111 // Intを代入してIntを返す
var notNumStr: String? = “1s3"
num = "128".toInt() // Int?を代入してIntを返す
num = notNumStr?.toInt()
// Int?を代入してnilを返す
Copylight © Classmethod, Inc.
!のルール
17
!
・T!で宣言しておくとnilでないことがわかっている時に!
 何回もT?に対して中身を表示する際に!を呼ばずに済む。!
・T!に入ったnilに対してTのメソッドを呼んでも!
 ランタイムエラーを起こす。!
-> if文等で中身が入っていることを確かめてから!を使う。
Copylight © Classmethod, Inc.
!のルール
!
if文で中身があることを確認!
!
!
18
var num: Int? = “123”.toInt()
var notNum: Int! = “1s3”.toInt()
if num {
print(num! + 10)
}
if notNum {
print(notNum + 10)
}
Copylight © Classmethod, Inc. 19
T型
T?型 T!型
常に代入可能
常に代入不可
nil以外代入可
Copylight © Classmethod, Inc. 20
T型
T?型 T!型
常に代入可能
常に代入不可
nil以外代入可
!を適用
Copylight © Classmethod, Inc.
メソッドチェーン再考
21
var numStr: String? = "123"
var notNumStr: String? = "1s3"
var newNumStr: String? =
numStr?.toInt()?.description //{Some “123"}
var newNotNumStr: String? =
notNumStr?.toInt()?.description //nil
・numStrはString? !
・toInt()をString -> Int?型の関数とみなす!
・.?はこの時 String? -> (String -> Int?) -> Int?型!
 の中置関数とみなせる。
Copylight © Classmethod, Inc.
メソッドチェーン再考
22
func toInteger (string: String) -> Int? {
return string.toInt()
}
・このstruct外の関数に関しては!
 Stringからのメソッドチェーンが適用できない
Copylight © Classmethod, Inc. 23
Copylight © Classmethod, Inc.
メソッドチェーン再考
24
・.?は他の場合でもT? -> (T -> U?) -> U?型!
 の中置関数とみなせる。!
Copylight © Classmethod, Inc.
メソッドチェーン再考
25
・.?は他の場合でもT? -> (T -> U?) -> U?型!
 の中置関数とみなせる。!
・enum Optional<T> をHaskellのMaybe T とみなして!
 モナドとして扱えないか?
Copylight © Classmethod, Inc.
メソッドチェーン再考
26
・.?は他の場合でもT? -> (T -> U?) -> U?型!
 の中置関数とみなせる。!
・enum Optional<T> をHaskellのMaybe T とみなして!
 モナドとして扱えないか?!
・Maybe モナドのバインド(>>=)を実装できれば!
 Optionalのコンテキストを保ったまま!
 関数オブジェクトに次々に適用できる
Copylight © Classmethod, Inc.
Optional で Haskellの >>=
27
operator infix >>= { associativity left }
!
func >>=<A, B> (maybe: Optional<A>,
acts: A -> Optional<B>)
-> Optional<B> {
switch maybe {
case .None: return nil
case let .Some(content): return acts(content)
}
}
Copylight © Classmethod, Inc.
func toInt8 (int: Int) -> Int8? {
switch int {
case Int(Int8.min)...Int(Int8.max):
return Optional.Some(Int8(int))
default:
return nil
}
}
!
var innerString: String? = "127"
var outerString: String? = "128"
innerString >>= toInteger >>= toInt8 // Some 127
outerString >>= toInteger >>= toInt8 // nil
28
Copylight © Classmethod, Inc. 29
Swiftの新機能 Optional

Swiftの新機能 Optional

  • 1.
    Copylight © Classmethod,Inc. Swiftの新機能! Optional Classmethod, Inc! ! 安達 勇一   1
  • 2.
    Copylight © Classmethod,Inc. プログラミング言語 Swift ・AppleがWWDC2014で発表! ・Xcode6-betaで利用可能! ・ライセンス開発者同士の議論はNDAから外れる模様! ・多くの言語のいいとこ取り! 2
  • 3.
    Copylight © Classmethod,Inc. 新しい概念 Optional var numberString: String? = “1111” //{Some "1111"} ! if let number = numberString?.toInt() { (number * 2).description // "2222" } else { "failed" } 3
  • 4.
    Copylight © Classmethod,Inc. 新しい概念 Optional var assumedNum: Int! = ”111”.toInt() ! if assumedNum { print(assumedNum) // 111 } 4
  • 5.
  • 6.
    Copylight © Classmethod,Inc. ?のルール 6 ・T?でenum Optional<T> のシンタックスシュガー! ・T型、T?型の双方が代入可能! ・値が存在しないかもしれないコンテキストが!  型に含まれている(Haskell :Maybeモナド)!
  • 7.
    Copylight © Classmethod,Inc. ?のルール ! enum Optional<T> 7 enum Optional<T> { case None //値が存在しない場合 case Some(T) //値が存在する場合 }
  • 8.
    Copylight © Classmethod,Inc. ?のルール ! 代入! ! ! ! ! 8 var str: String? = "some string" var temp = str str = “string" //{Some “string"} str = temp //{Some "some string"}
  • 9.
    Copylight © Classmethod,Inc. ?のルール 9 ・メソッドチェーンの際に?を挟むことで!  None(= nil)の時は以降のメソッドが走らない!  Some(T)の時はTに対して次のメソッドを適用する! !
  • 10.
    Copylight © Classmethod,Inc. ?のルール ! メソッドチェーン! ! ! ! ! 10 var numStr: String? = "123" var notNumStr: String? = "1s3" var newNumStr: String? = numStr?.toInt()?.description //{Some “123"} var newNotNumStr: String? = notNumStr?.toInt()?.description //nil
  • 11.
  • 12.
    Copylight © Classmethod,Inc. !のルール 12 ・T!でstruct ImplicitlyUnwrappedOptional<T>!  のシンタックスシュガー! ・T型、T?型の双方を代入可能! ・T?の型に!を適用すると!  T?がSome(T)ならばTを返す!     NoneならばRuntime Errorが起きる! ・Tに!を適用するとコンパイルエラー
  • 13.
    Copylight © Classmethod,Inc. !のルール ! 代入! ! ! ! ! 13 var num: Int! = 1111 // 1111 var notNumStr: String? = “1s3" num = "128".toInt() // 128 num = notNumStr?.toInt() // nil
  • 14.
    Copylight © Classmethod,Inc. !のルール ! T?型に!を適用する! ! ! ! ! T型に!を適用する 14 var notNumStr: String? = "1s3" var notNum: Int? = notNumStr?.toInt() notNumStr! // "1s3" var notInt: Int = notNum! // runtime error var integer = 17 17! // !の適用先が違うとコンパイラに怒られる
  • 15.
    Copylight © Classmethod,Inc. !のルール 15 ! ・型そのものと、値を取得するときの返り値が異なる!  Tを代入した時はTを返す!  T?を代入した時、その中身がSome(T)ならばTを返す!                Noneならばnil(=T?)を返す! ・この仕組が暗黙的アンラップ型と呼ばれる所以
  • 16.
    Copylight © Classmethod,Inc. !のルール ! 代入! ! ! ! ! 16 var num: Int! = 1111 // Intを代入してIntを返す var notNumStr: String? = “1s3" num = "128".toInt() // Int?を代入してIntを返す num = notNumStr?.toInt() // Int?を代入してnilを返す
  • 17.
    Copylight © Classmethod,Inc. !のルール 17 ! ・T!で宣言しておくとnilでないことがわかっている時に!  何回もT?に対して中身を表示する際に!を呼ばずに済む。! ・T!に入ったnilに対してTのメソッドを呼んでも!  ランタイムエラーを起こす。! -> if文等で中身が入っていることを確かめてから!を使う。
  • 18.
    Copylight © Classmethod,Inc. !のルール ! if文で中身があることを確認! ! ! 18 var num: Int? = “123”.toInt() var notNum: Int! = “1s3”.toInt() if num { print(num! + 10) } if notNum { print(notNum + 10) }
  • 19.
    Copylight © Classmethod,Inc. 19 T型 T?型 T!型 常に代入可能 常に代入不可 nil以外代入可
  • 20.
    Copylight © Classmethod,Inc. 20 T型 T?型 T!型 常に代入可能 常に代入不可 nil以外代入可 !を適用
  • 21.
    Copylight © Classmethod,Inc. メソッドチェーン再考 21 var numStr: String? = "123" var notNumStr: String? = "1s3" var newNumStr: String? = numStr?.toInt()?.description //{Some “123"} var newNotNumStr: String? = notNumStr?.toInt()?.description //nil ・numStrはString? ! ・toInt()をString -> Int?型の関数とみなす! ・.?はこの時 String? -> (String -> Int?) -> Int?型!  の中置関数とみなせる。
  • 22.
    Copylight © Classmethod,Inc. メソッドチェーン再考 22 func toInteger (string: String) -> Int? { return string.toInt() } ・このstruct外の関数に関しては!  Stringからのメソッドチェーンが適用できない
  • 23.
  • 24.
    Copylight © Classmethod,Inc. メソッドチェーン再考 24 ・.?は他の場合でもT? -> (T -> U?) -> U?型!  の中置関数とみなせる。!
  • 25.
    Copylight © Classmethod,Inc. メソッドチェーン再考 25 ・.?は他の場合でもT? -> (T -> U?) -> U?型!  の中置関数とみなせる。! ・enum Optional<T> をHaskellのMaybe T とみなして!  モナドとして扱えないか?
  • 26.
    Copylight © Classmethod,Inc. メソッドチェーン再考 26 ・.?は他の場合でもT? -> (T -> U?) -> U?型!  の中置関数とみなせる。! ・enum Optional<T> をHaskellのMaybe T とみなして!  モナドとして扱えないか?! ・Maybe モナドのバインド(>>=)を実装できれば!  Optionalのコンテキストを保ったまま!  関数オブジェクトに次々に適用できる
  • 27.
    Copylight © Classmethod,Inc. Optional で Haskellの >>= 27 operator infix >>= { associativity left } ! func >>=<A, B> (maybe: Optional<A>, acts: A -> Optional<B>) -> Optional<B> { switch maybe { case .None: return nil case let .Some(content): return acts(content) } }
  • 28.
    Copylight © Classmethod,Inc. func toInt8 (int: Int) -> Int8? { switch int { case Int(Int8.min)...Int(Int8.max): return Optional.Some(Int8(int)) default: return nil } } ! var innerString: String? = "127" var outerString: String? = "128" innerString >>= toInteger >>= toInt8 // Some 127 outerString >>= toInteger >>= toInt8 // nil 28
  • 29.