Search code examples
cocoaswiftprotocolsswift-playgroundnsnull

Making NSNull conform to NilLiteralConvertible


I'm trying to make NSNull conform to NilLiteralConvertible, but I'm running into an enormous amount of frustration:

extension NSNull : NilLiteralConvertible{

    required convenience init(nilLiteral: ()){
        self.init()
    }
}

First of all, I'm forced to make the init a convenience one, as I can't add designated initialisers in an extension.

Then, the compiler goes crazy and insists that the init must be made required and immediately after complains that required initialisers must be added directly to the class and not in an extension. WTF?!

playground

Anybody knows what's going on and how to make NSNull conform to this simple protocol?

I'm testing this in an Xcode playground.


Solution

  • There should be no reason to conform NSNull to NilLiteralConvertible. Although the protocol is public, it's mostly used internally by NSZone and the implementation of Optionals in the language (see references in the source here). You can get the desired behavior your want by just declaring a variable as Optional<NSNull>. The Optional enum conforms to NilLiteralConvertible for you, as shown in the source of Optional.swift:

    This doesn't work:

    var null: NSNull
    
    null = NSNull()  // <null>
    null = nil // error: nil cannot be assigned to type 'NSNull'
    

    But this does:

    var null: NSNull?
    
    null = NSNull() // <null>
    null = nil // nil