ArrayLiteralConvertible: Hanya protokol biasa?

Mencoba memahami dan menghargai cara kerja ArrayLiteralConvertible...

struct Struct<T>: ArrayLiteralConvertible {

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

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

Keluaran:

1
2
3

Sekarang saya mencoba melakukan hal yang sama tetapi kali ini dengan ArrayLiteralConvertible versi saya sendiri:

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]

Namun itu tidak berhasil!

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

Apakah saya melakukan kesalahan atau ada penanganan khusus untuk ArrayLiteralConvertible?


person adev    schedule 10.09.2015    source sumber


Jawaban (1)


Secara umum, literal adalah artefak waktu kompilasi murni. Mereka dapat digunakan untuk menghasilkan objek yang diinisialisasi dari literal tersebut, tetapi setelah fase kompilasi selesai, tidak ada yang tahu bahwa sesuatu itu literal.

Hal ini menunjukkan bahwa dukungan apa pun untuk protokol di bawah ini perlu dimasukkan ke dalam kompiler itu sendiri:

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

Kompiler tidak akan menggunakan protokol Anda sendiri sebagai pengganti protokol di atas.

person Sergey Kalinichenko    schedule 10.09.2015
comment
Terima kasih atas jawabannya dasblinkenlight. Namun ada beberapa aspek dalam jawaban Anda - beberapa di antaranya ingin saya diskusikan: 1. Memahami dan menyetujui pernyataan Anda mengenai literal secara umum. 2. Juga dipahami bahwa seperti literal memerlukan dukungan kompiler, literal protokol ini juga memerlukan hal yang sama. 3. Yang sulit dicerna (tentang Swift - bukan jawaban Anda) adalah Swift akan memberikan perlakuan khusus pada protokol tertentu. Ini tampak tidak jujur ​​​​dari sudut pandang suatu bahasa. Akan lebih baik jika mengklasifikasikannya secara terbuka dengan konstruksi khusus. - person adev; 10.09.2015
comment
@adev Pendekatan ketika dukungan kompiler ditambahkan untuk kelas tertentu dari perpustakaan standar adalah hal yang lumrah saat ini. Saya tahu situasi ketika ini terjadi di Java, C#, Objective-C, dan Swift. Ngomong-ngomong, ada banyak tempat lain di mana Swift juga melakukannya: misalnya, kompiler memiliki dukungan bawaan untuk Optional<T>, dan juga untuk hal-hal yang dapat Anda masukkan ke dalam konstruksi if let something = ... {}. - person Sergey Kalinichenko; 10.09.2015
comment
Terima kasih dasblinkenlight. Saya kira kita hanya perlu mengetahui hal-hal ini ketika hal itu terjadi. Kelas esp wrt dll. - person adev; 10.09.2015