トップページ > プログラム > 2016年07月08日 > goWM3aH00

書き込み順位&時間帯一覧

12 位/194 ID中時間01234567891011121314151617181920212223Total
書き込み数0000000000000120000000003



使用した名前一覧書き込んだスレッド一覧
デフォルトの名無しさん (ワッチョイ c7c9-7VFp)
Swift part8 [無断転載禁止]©2ch.net

書き込みレス一覧

Swift part8 [無断転載禁止]©2ch.net
339 :デフォルトの名無しさん (ワッチョイ c7c9-7VFp)[sage]:2016/07/08(金) 13:02:17.95 ID:goWM3aH00
>>336
http://i.imgur.com/oD9dIpA.png

a、b、c全部別の意味を表すから、どれが正解かは場合による

10と.some(.some(10))で結果が同じなのは、10と書いてもコンパイラが.some(.some(.some(10)))に自動的にラップしてくれるから
なぜそんなことが許されるかというと、Int???型で「最終的に値が存在する状態」というのは.some(.some(.some(10)))以外にあり得ず、曖昧さが入り込む余地が無いから
だから10、.some(10)、.some(.some(10))、.some(.some(.some(10)))どう書いても全部結果は同じになる
本来なら.some(.some(.some(10)))って書かないといけないわけだけど、それ以外に解釈のしようがないんなら10って書けたほうが楽で便利だよねってこと

一方で、nilには外から何番目ののOptionalでnilなのかによって意味が異なってくるので、勝手にラップされるようなことはない
だからnilなのか.some(nil)なのか.some(.some(nil))なのかを、プログラマの責任できちんと意思表示しないといけない

// Swift 2.x
var a: Int???
a = 1
print(a) // Optional(Optional(Optional(1)))
a = .Some(1)
print(a) // Optional(Optional(Optional(1)))
a = .Some(.Some(1))
print(a) // Optional(Optional(Optional(1)))
a = .Some(.Some(.Some(1)))
print(a) // Optional(Optional(Optional(1)))
a = nil
print(a) // nil
a = .Some(nil)
print(a) // Optional(nil)
a = .Some(.Some(nil))
print(a) // Optional(Optional(nil))
Swift part8 [無断転載禁止]©2ch.net
341 :デフォルトの名無しさん (ワッチョイ c7c9-7VFp)[sage]:2016/07/08(金) 14:07:40.43 ID:goWM3aH00
>>333
自動アンラップなんてされないんじゃないかな
危険だし
もしかしたら仕様が定まってない昔のSwiftでは、そういうことしてた時期もあるのかもしれないけど

非Optional同士の比較演算子とは別に、Optional同士の比較演算子が定義されてるっぽい
Int同士の比較なら↓の類が使われて
public func ==(lhs: Int, rhs: Int) -> Bool
Int?同士の比較なら↓の類が使われる
public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool

今気づいたけどOptional同士の大小比較では常にnilが小さいことになるのか
var x: Int? = nil
x > 9 // false
x < 9 // true
x < Int.min // true
Int同士の比較では起こりえないInt.min未満って状態が、Int?同士の比較ではありえるんだな

なお、さらっと x < 9 とか書けるのは、>>339の理屈で自動的に.some(9)にラップされてInt?同士の比較として
public func <<T : Comparable>(lhs: T?, rhs: T?) -> Bool
で比較されてるからであって、x が勝手にアンラップされて
public func >(lhs: Int, rhs: Int) -> Bool
で比較されてるわけではない

二重Optional同士の比較ではそもそも演算子が定義されてなくてコンパイルエラーになるな
一重Optional同士なら値<=>値、値<=>nil、nil<=>nilの3パターンを考えれば住むのに対して
二重Optional同士だと値<=>値、値<=>.Some(nil)、値<=>nil、.Some(nil)<=>.Some(nil)、.Some(nil)<=>nil、nil<=>nilの6パターン
三重Optional同士だと10パターンと階乗のオーダーで複雑さが増していくからやってらんないし
true、falseの2値にむりやり帰着してしまうのもどうかってはなしだし
仮に実装したとしても使う側が使いこなせないんだろう
結局ネストしたOptionalを比較したいなら、自力でアンラップしていって、それぞれの場合に対して
自分のやりたいように対応してくださいねっていう当たり前の結論になるんじゃなかろうか
Swift part8 [無断転載禁止]©2ch.net
343 :デフォルトの名無しさん (ワッチョイ c7c9-7VFp)[sage]:2016/07/08(金) 14:36:01.17 ID:goWM3aH00
>>336
>a.last.last.last なんて取り出しかたする時に出てきそうだ

実際それするなら a.last?.last?.last でただの一重Optionalとして扱える
ネストしたOptionalは実際扱いづらいからOptionalチェーンやflatMapがある

var a1: [[Int]] = [[1]] // 外側も内側も値が入ってる
var a2: [[Int]] = [[]] // 外側には値が入ってるけど内側は空
var a3: [[Int]] = [] // 外側がそもそも空

// Optionalチェーンを使った場合
print(a1.last?.last) // Optional(1)
print(a2.last?.last) // nil
print(a3.last?.last) // nil

// mapを使った場合
print(a1.last.map { $0.last }) // Optional(Optional(1))
print(a2.last.map { $0.last }) // Optional(nil)
print(a3.last.map { $0.last }) // nil

// flatMapを使った場合
print(a1.last.flatMap { $0.last }) // Optional(1)
print(a2.last.flatMap { $0.last }) // nil
print(a3.last.flatMap { $0.last }) // nil

結局あるのか無いのかそれだけ教えてよ!ってときにはOptionalチェーンやflatMap使って、ただのOptionalとして取り出せばいいし、
どの段階で無いのかが問題になる場合(上の例ならa2とa3を区別して処理したい場合)はmapやif letのネストで細かく処理すればいい


※このページは、『2ちゃんねる』の書き込みを基に自動生成したものです。オリジナルはリンク先の2ちゃんねるの書き込みです。
※このサイトでオリジナルの書き込みについては対応できません。
※何か問題のある場合はメールをしてください。対応します。