Hai, nama saya Ilya. Saya seorang pengembang iOS di Tinkoff.ru. Pada artikel ini, saya akan memberikan tinjauan singkat tentang perubahan utama pada Swift 5. Perubahan ini dijelaskan dalam
catatan rilis . Bagi mereka yang belum membiasakan diri, selamat datang kucing!

Ukuran aplikasi akan berkurang!
Aplikasi yang ditulis dalam Swift 5 dan dikompilasi untuk iOS 12.2, watchOS 5.2, tvOS 12.2 tidak akan menyertakan pustaka dinamis untuk pustaka standar Swift dan Swift SDK. Dan ini berarti bahwa ukuran aplikasi akan berkurang, bagaimanapun, tidak banyak. Jika Anda percaya
tweet ini , ukuran proyek kosong berkurang dari 2,4 Mb hingga 24 Kb. Hasil yang bagus untuk aplikasi kecil, tetapi untuk aplikasi besar tidak akan ada banyak perbedaan.
@dynamicCallable ( SE-0216 )
Atribut
@dynamicCallable memungkinkan
Anda untuk bekerja dengan objek sebagai fungsi. Objek tersebut disebut objek fungsional atau functors (lebih detail dapat ditemukan di
sini ). Objek fungsional adalah dalam C ++, Python, JavaScript dan dalam bahasa lain, dan dalam Swift mereka ditambahkan untuk kompatibilitas dengan bahasa-bahasa ini. Faktanya adalah bahwa Swift sekarang berinteraksi dengan baik dengan API C dan Objective-C, dan pengembang bahasa ingin menambahkan interaksi dengan bahasa dinamis - Python, JavaScript, Ruby, dan lainnya.
Untuk membuat tipe functor, Anda harus menambahkan atribut
@dynamicCallable ke deklarasi. Pertimbangkan contoh struktur
Peredam yang dapat digunakan untuk menambahkan angka dalam array:
@dynamicCallable struct Reducer { ... }
Maka Anda perlu menerapkan satu atau kedua metode berikut:
func dynamicallyCall(withArguments: ExpressibleByArrayLiteral) func dynamicallyCall(withKeywordArguments: ExpressibleByDictionaryLiteral)
Fungsi pertama memungkinkan Anda untuk mengakses objek dengan mengirimkan array sebagai argumen. Fungsi kedua memungkinkan Anda untuk mengakses objek, melewati array yang sama dengan argumen, tetapi menggunakan nama-nama argumen.
Misalnya, implementasi fungsi pertama untuk struktur
Reducer akan terlihat seperti ini:
func dynamicallyCall(withArguments arguments: [Int]) -> Int { return arguments.reduce(0, +) }
Kemudian terapkan struktur seperti berikut:
let reducer = Reducer() let sum = reducer(1, 2, 3)
Kami akan mempertimbangkan implementasi metode kedua menggunakan contoh struktur
Pembanding , yang dengannya kami dapat membandingkan dua angka:
@dynamicCallable struct Comparator { func dynamicallyCall(withKeywordArguments arguments: KeValuePairs<String, Int>) -> ComparisonResult { guard let lhs = arguments["lhs"], let rhs = arguments["rhs"], lhs != rhs else { return .orderedSame } return lhs > rhs ? .orderedDescending : .orderedAscending } }
Anda dapat menggunakan struktur ini sebagai berikut:
let comparator = Comparator() let comparisionResult = comparator(lhs: 1, rhs: 2)
Banyak orang tahu bahwa saat memproses nilai enumerasi, perlu untuk menggambarkan semua kasus dan mencoba untuk tidak menggunakan default. Meskipun persyaratan ini menambahkan sedikit keamanan, ia juga memiliki kelemahan, karena ketika mengubah nilai dalam enumerasi, Anda perlu menambahkan pemrosesan mereka. Masih ada kemungkinan bahwa kerangka kerja sistem akan mengubah salah satu enumerasi, tetapi ini belum diproses dalam aplikasi Anda (Jadi, misalnya, dengan
LABiometryType ).
Swift 5 akan menambahkan atribut yang
tidak dikenal , yang akan memungkinkan Anda untuk memisahkan 2 skenario yang berbeda saat memproses enumerasi:
- Kode secara default harus dijalankan untuk semua kasus yang tidak diproses secara bergantian
- Semua case diproses secara bergantian, dan jika yang baru ditambahkan, maka Anda perlu menggunakan kode secara default
Mari kita lihat sebuah contoh:
enum HTTPMethod { case post, get, put }
Menyingkirkan dobel Opsional sebagai hasil memanggil fungsi dengan coba? ( SE-0230 )
Tentunya banyak yang menemukan fakta bahwa ketika memanggil fungsi yang bisa dibuang, yang mengembalikan
Opsional , menggunakan
coba? , hasilnya adalah tipe terbungkus dua
Opsional . Ini tidak nyaman, dan di Swift 5, panggil
coba? dalam hal ini akan mengembalikan jenis yang dibungkus hanya dalam satu
Opsional .
Beginilah sebelum Swift 5:
let result = try? optionalObject?.foo()
Dan itu akan ada di Swift 5:
let result = try? optionalObject?.foo()
Multiplicity Check ( SE-0225 )
Untuk memeriksa multiplisitas dari satu angka ke yang lain, Anda dapat menggunakan fungsi
isMultiple (of :) , alih-alih sisa pembagian (%):
Perubahan kecil, tetapi membuat kode sedikit lebih jelas dan menyederhanakan pencarian berdasarkan kode.
Menghitung jumlah elemen secara berurutan dengan suatu kondisi ( SE-0220 )
Dalam Swift 5, tipe Sequence akan menambahkan
hitungan (di mana: (Elemen) -> Bool) -> metode
Int , yang akan memungkinkan Anda untuk menghitung jumlah elemen dalam urutan yang memenuhi kondisi tertentu dalam satu pass. Sebelum itu, saya harus menggunakan
filter bersamaan dengan
hitungan . Metode ini akan menghemat memori yang dialokasikan saat membuat array baru dalam metode
filter .
Contoh:
let countOfZeroes = [0, 1, 2, 0, 4].count(where: { $0 == 0 })
Metode CompactMapValues โโdalam Kamus ( SE-0218 )
Metode ini menggabungkan
compactMap dari
Array dan
mapValues dari
Kamus . Sebagai hasil dari memanggil metode ini, kamus dengan nilai yang diubah dibuat di mana tidak ada nilai yang sama dengan
nol .
Contoh:
let dictionary = ["a": "1", "b": "2", "c": "Number"] let resultDictionary = dictionary.compactMapValues { Int($0) }
String mentah ( SE-0200 )
Menambahkan kemampuan untuk menulis baris di mana tanda kutip dan garis miring terbalik digunakan sebagai karakter biasa, dan bukan sebagai yang khusus. Untuk melakukan ini, tambahkan karakter # di awal dan di akhir baris.
Contoh:
let string1 = #" " ""# let string2 = #" \ "#
Jika Anda memasukkan variabel saat membuat garis, maka setelah garis miring terbalik Anda perlu menambahkan tanda #:
let string = #" \#(variable)"#
Jika baris memiliki tanda #, maka di awal dan di akhir baris Anda perlu menambahkan dua tanda ##:
let string = ##" #"##
Sequence Protocol tidak lagi berisi tipe SubSequence terkait ( SE-0234 )
Tipe asosiatif dari
SubSequence telah dipindahkan dari protokol
Sequence ke
Collection. Sekarang semua metode dalam
Sequence yang mengembalikan
SubSequence mengembalikan tipe tertentu. Misalnya, metode
suffix sekarang mengembalikan
Array . Berikut adalah daftar lengkap metode yang dipengaruhi oleh perubahan ini:
extension Sequence { public func dropFirst(_ k: Int = 1) -> DropFirstSequence<Self> public func dropLast(_ k: Int = 1) -> [Element] public func suffix(_ maxLength: Int) -> [Element] public func prefix(_ maxLength: Int) -> PrefixSequence<Self> public func drop(while predicate: (Element) throws -> Bool) rethrows -> DropWhileSequence<Self> public func prefix(while predicate: (Element) throws -> Bool) rethrows -> [Element] public func split( maxSplits: Int = Int.max, omittingEmptySubsequences: Bool = true, whereSeparator isSeparator: (Element) throws -> Bool ) rethrows -> [ArraySlice<Element>] }
Sekarang bekerja dengan metode ini akan menjadi lebih mudah.
Pembatasan Protokol
Protokol sekarang mendukung pembatasan dalam bentuk kelas yang mengimplementasikan protokol ini. Dengan kata lain, Anda sekarang dapat menunjukkan bahwa protokol hanya dapat diimplementasikan oleh kelas tertentu. Sebagai contoh:
protocol Viewable: UIView {} protocol Viewable where Self: UIView {}
Opsi perekaman kedua didukung dalam Swift 4.2, tetapi dapat menyebabkan kesalahan kompilasi atau runtime. Di Swift 5, kesalahan ini tidak akan terjadi.
Kesimpulan
Ini bukan daftar lengkap perubahan di Swift 5, hanya perubahan utama yang dikumpulkan di sini. Secara umum, perubahan yang disajikan positif dan membuat bahasa lebih dimengerti dan fleksibel. Hal utama adalah bahwa "Konversi ke sintaks Swift saat ini" harus tidak menyakitkan.
Itu saja, terima kasih sudah membaca.