Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ArrayLiteralConvertible: Just a normal protocol?

Trying to understand and appreciate how ArrayLiteralConvertible works...

struct Struct<T>: ArrayLiteralConvertible {

    init(arrayLiteral elements: T...) {
        for element in elements {
            print(element)
        }
    }
}

let str: Struct<Int> = [1,2,3]

Output:

1
2
3

Now I am trying to do the same thing but this time with my own version of ArrayLiteralConvertible:

protocol MyALC {
    typealias Element
    init(arrLit elements: Self.Element...)
}

struct NewStruct<T>: MyALC {

    init(arrLit elements: T...) {
        for element in elements {
            print(element)
        }
    }
}

let newStr: NewStruct<Int> = [1,2,3]

However it does not work!

error: cannot convert value of type '[Int]' to specified type 'NewStruct'
let newStr: NewStruct = [1,2,3]

Am I doing something wrong or is there a special handling for ArrayLiteralConvertible?

like image 571
adev Avatar asked Sep 19 '26 09:09

adev


1 Answers

Generally, literals are a purely compile-time artifact. They can be used to produce an object initialized from that literal, but once the compilation phase is over, nobody knows that something was a literal.

This suggests that any support for the protocols below needs to be built into the compiler itself:

  • ArrayLiteralConvertible
  • BooleanLiteralConvertible
  • DictionaryLiteralConvertible
  • ExtendedGraphemeClusterLiteralConvertible
  • FloatLiteralConvertible
  • NilLiteralConvertible
  • IntegerLiteralConvertible
  • StringLiteralConvertible
  • StringInterpolationConvertible
  • UnicodeScalarLiteralConvertible

The compiler would not take your own protocol as a replacement of any of the above.

like image 200
Sergey Kalinichenko Avatar answered Sep 21 '26 22:09

Sergey Kalinichenko