Search code examples
swiftstringpointersunsafe-pointers

How to extend String's UnsafePointer<Int8> initializer to accept NULL pointers?


In Swift, there's a String initialiser that takes an UnsafePointer<Int8> (or UnsafePointer<CChar> which is the same I think) as an argument.

However, there's no initialiser that takes an optional UnsafePointer, e.g. a pointer that's NULL (or nil, speaking swifty), which can be extremely helpful when working with a C API.

I'd like to extend the String class to accept optional unsafe pointers.

This is what my extension looks like. Is that correct? Is this how one would implement that feature?

extension String {
    init?(cString: UnsafePointer<Int8>?) {
        guard let cString = cString else { return nil }
        self = String(cString: cString)
    }
}

Solution

  • That's fine. You have a failable initializer which “fails” (returns nil) if the given argument is nil. Otherwise it unwraps the argument and initializes the string by assigning to self (which can be done with struct types).

    CChar is indeed the same type as Int8 on all Apple platforms (where char is a signed character). I would write the argument type as UnsafePointer<CChar>? to emphasize the connection with the char type in C.

    A (only slightly different) alternative is

    extension String {
        init?(cString: UnsafePointer<CChar>?) {
            guard let cString = cString else { return nil }
            self.init(cString: cString)
        }
    }
    

    but that is purely a matter of taste.