Sobes.tech
Junior

Swift жыйымдар менен башка программалоо тилдериндеги жыйымдардын айырмасы эмнеде?

sobes.tech AI

AIден жооп

Ключевыя адрозненні калекцый Swift (Array, Dictionary, Set) ад такіх у іншых мовах (напрыклад, Java, C#, Objective-C) наступныя:

  1. Бяспека тыпаў і вываду тыпаў: Калекцыі Swift з'яўляюцца тыпова бяспечнымі па сваёй сутнасці. Тып элемента вызначаецца пры ініцыялізацыі або даданні першага элемента. Праверка ў час кампіліравання прадухіляе памылкі тыпаў у час выканання.

    var numbers: [Int] = [1, 2, 3] // Яўнае вызначэнне тыпу
    var strings = ["a", "b", "c"] // Вывад тыпаў
    // numbers.append("hello") // Памылка кампіліравання: Cannot convert value of type 'String' to expected argument type 'Int'
    

    У мовах з менш строгай сістэмай тыпаў (напрыклад, Objective-C без анатацый) тыпы элементаў могуць быць @id, што патрабуе праверкі тыпаў у час выканання.

  2. Значэнневыя тыпы (Structs): Array, Dictionary і Set у Swift з'яўляюцца структурамі (значэнневымі тыпамі), а не класамі (спасылкавымі тыпамі). Пры прысваенні або перадачы ў функцыю ствараецца копія калекцыі.

    var arrayA = [1, 2, 3]
    var arrayB = arrayA // Копія калекцыі
    arrayB.append(4)
    
    print(arrayA) // Выхад: [1, 2, 3]
    print(arrayB) // Выхад: [1, 2, 3, 4]
    

    У большасці іншых моў калекцыі з'яўляюцца класамі, і прысваенне стварае спасылку на тую ж калекцыю. Гэта важная розніца для кіравання памяццю і прагназавання паводзін. Swift выкарыстоўвае аптымізацыю "copy-on-write" для структураў калекцый, што робіць капіраванне эфектыўным, калі калекцыя не змяняецца.

  3. Апцыянальнасць элементаў: Калекцыі Swift могуць утрымліваць апцыянальныя тыпы, што ясна паказвае на магчымасць адсутнасці элемента.

    var optionalNumbers: [Int?] = [1, nil, 3]
    

    Гэта адрозніваецца ад моў, дзе nil (ці эквівалент) можа быць прысвоены любому элементу калекцыі спасылкавага тыпу без выразнага паказання апцыянальнасці.

  4. Магутныя функцыянальныя метады: Swift прапануе багаты набор метадаў для працы з калекцыямі ў функцыянальным стылі: map, filter, reduce, forEach, compactMap і іншыя.

    let numbers = [1, 2, 3, 4, 5]
    let doubled = numbers.map { $0 * 2 } // [2, 4, 6, 8, 10]
    let even = numbers.filter { $0 % 2 == 0 } // [2, 4]
    let sum = numbers.reduce(0, +) // 15
    

    Хоць многія мовы маюць гэтыя магчымасці, у Swift яны інтэграваныя больш цесна і з'яўляюцца часткай стандартнай бібліятэкі.

  5. Протаколы і пашырэнні: Калекцыі Swift адпавядаюць шэрагу протаколаў (Collection, Sequence, MutableCollection, RandomAccessCollection і г.д.), што дазваляе ствараць агульныя функцыі і пашырэнні, якія працуюць з любымі тыпамі калекцый, рэалізуючымі гэтыя протаколы.

    extension Collection {
        func printElements() {
            for element in self {
                print(element)
            }
        }
    }
    
    let myArray = [10, 20, 30]
    myArray.printElements() // Працоўвае для Array
    
    let mySet: Set = [1, 2, 3]
    mySet.printElements() // Працоўвае для Set
    

    Гэты падыход на аснове протаколаў больш гнуткі, чым іерархіі класаў, якія выкарыстоўваюцца ў некаторых іншых мовах.

  6. Індэксаванне і доступ: Індэксаванне ў Swift бяспечнае. Паспрабуйце атрымаць доступ па невалідным індэксе выклікае памылку часу выканання (range out of bounds).

    Важна адзначыць, што хоць у Objective-C таксама ёсць калекцыі (NSArray, NSDictionary, NSSet), яны з'яўляюцца класамі, заснаванымі на NSObject, не з'яўляюцца тыпова бяспечнымі па змаўчанні (да з'яўлення Generics на ўзроўні кампілера) і не з'яўляюцца значэннявымі тыпамі. Калекцыі Swift прапануюць больш сучасны, бяспечны і прадукцыйны падыход.