Logo Questions Linux Laravel Mysql Ubuntu Git Menu

Extend all types in Swift?




Browsing Swift's library code I've found:

extension T! : Printable {
  var description: String { get }

The snippet seems to extend all types with the 'description' field. When I try to do the same thing in my code, I get error:

example.swift:10:11: Non-nominal type 'T!' cannot be extended

protocol MyProtocol {
  // ...

extension T! : MyProtocol { // error: Non-nominal...
  // ...

There are similar questions at:

  • How can I extend typed Arrays in Swift?
  • What's the difference between Optional<T> and optional types in Swift? Extending Optional to carry error information?

But they fail to address:

  • What's going on here? Why is the library code okay, but my code... not?
  • Is it possible to all types or all types that conform to a specific protocol?
like image 889
Andy Avatar asked Mar 20 '23 05:03


1 Answers

First of all, it does not extend all types. It extends T!, which is ImplicitlyUnwrappedOptional<T>. So it extends the implicitly unwrapped optional type, not all types.

The "header" is not really Swift code; it is automatically generated. There may be bugs in the automatic header generator that makes it not generate true Swift code in some cases. Don't take it too literally.

One weird thing that you notice in the automatically-generated "header" is that certain built-in syntax contractions are inconsistently applied -- the type declaration doesn't use the contraction, but the extension does:

struct Array<T>
extension T[]

enum Optional<T>
extension T?

struct ImplicitlyUnwrappedOptional<T>
extension T!

Probably some code in the automatic header generator too greedily replaces the above types with their contracted syntax. So first we pretend that extension T! actually says extension ImplicitlyUnwrappedOptional<T>.

However, extension ImplicitlyUnwrappedOptional<T> doesn't compile either, with the error "Use of undeclared type 'T'". In fact, in the automatically-generated "header", we wee many instances of extension declarations with type parameters, e.g. extension Dictionary<KeyType, ValueType>, that do not compile in Swift. This is another bug with the automatic header generation.

But removing the type parameter works:

extension ImplicitlyUnwrappedOptional : MyProtocol {
  // ...

This is exactly what is shown in this answer.

like image 72
newacct Avatar answered Mar 27 '23 11:03