21389


Optional型に、nilが代入できる理由は、NilLiteralConvertible プロトコルを実装しているからだと。

var a : Int? = nil  
上記のようにnilをオプショナル型に代入するとき、  
NilLiteralConvertible のイニシャライザがよばれることで、  
nilの代入が可能となるみたいなのですが、  
NilLiteralConvertible のイニシャライザの定義が次のようなっています。

[code]

    init(nilLiteral: ())
    
[/code]

これは、型の指定が、空のタプルにもみえますが、空のタプルは「型」ではないですし、  
なぜ、このイニシャライザ呼ばれることになるのでしょうか。  
また型の「（）」は何をいみしているのでしょうか？

教えてください。


CC BY-SA 3.0
2016-01-27T07:26:15.347
21371
2016-01-27T13:12:25.670
11148
question
swift
Optional型にnilリテラルを代入できる理由について


Swift言語の中には、1つだけ「型」とその型に含まれる「値」に同じ表記を使うものがあって、それが`()`、型として使う場合の別名は`Void`です。

他言語のvoidの使い方に慣れていると非常に戸惑ってしまうのですが、SwiftではVoid型の変数を宣言して、値を代入できたりなんかもします。

[code]

    var myVoid: Void = ()
    
[/code]

この(初期値付きの)変数宣言は、次と全く同じものです。

[code]

    var myVoid: () = ()
    
[/code]

この場合、前半の`()`は型、後半の`()`は値(つまり空tuple)として使われています。

Swiftで、引数なしで値を返さない関数型の表記は、`()->()`、`()->Void`とか`Void->Void`とかいろいろ書かれます(`Void->()`も同じだがあまり見たことがないです)が、全て同じ意味です。

つまり、

[code]

    init(nilLiteral: ())
    
[/code]

というイニシャライザは

[code]

    init(nilLiteral: Void)
    
[/code]

と全く同じで、引数として空タプルだけを受け取ることを表しています。

他言語のnullもよく突き詰めて考えると意味不明だったりするのですが、Swiftのnilは「リテラル(Swiftではリテラルには型は無い)で、literal
convertibleなメソッドを持つことで、必要な値に変身します」と言うのはわたし的には(他言語よりは)わかりやすいように思うのですが…。

(ご質問の中の1点に答えられていないような気がしたので追記です。)  
_なぜ、このイニシャライザ呼ばれることになるのでしょうか。_  
引数を持たない関数を呼び出すときに、なぜ空tupleを渡すとこの関数が呼ばれることになるのか、とはあまり考えないのではないかと思います。NilLiteralConvertibleの場合、引数に渡すべき値が無いので「外部名はあるが引数は持たない」イニシャライザを使っているわけです。


CC BY-SA 3.0
2016-01-27T10:43:32.307
21389
2016-01-27T13:12:25.670
2016-01-27T13:12:25.670
13972
13972
21371
answer