Yaylı enterpolasyon, Swift'in ilk günlerinden beri var, ancak Swift 5.0'da daha hızlı ve daha güçlü hale getirmek için büyük bir revizyona giriyor.

Bu makalede, neyin değiştiğini ve kendi kodunuza nasıl uygulayacağınızı gözden geçirmek istiyorum. Ayrıca bu makale için kodumu buradan indirebilirsiniz..

Temeller

Bunun gibi temel string enterpolasyonuna alışkınız:

yaş = 38
baskı ("Sen  (yaş)")

Bugünlerde kabul görüyoruz, ancak daha önce sahip olduğumuz sözdizimine göre çok büyük bir yaşam kalitesi iyileştirmesi vardı:

[NSString stringWithFormat:@"%ld", (long)unreadCount];

Ama aynı zamanda önemli performans gelişme, çünkü alternatif bunun gibi birleştirme kodunu yazmaktı:

hepsine izin ver = s1 + s2 + s3 + s4

Evet, aynı sonuca ulaşıyor, ancak Swift'in eklemesi gerekecek s1 için s2 yapmak s5, eklemek s5 için s3 yapmak s6, ve Ekle s6 için s4 yapmak s7, atamadan önce o için herşey.

Dize enterpolasyonu Swift 1.0'dan bu yana çok fazla değişmedi, Swift 2.1'de gerçekleşen tek gerçek değişiklik, dize değişmezlerini enterpolasyonlarda kullanma yeteneğimizi kazandık:

Yazdır ("Merhaba,  (kullanıcı ??" Anonim ")")

Şimdi, bildiğiniz gibi Swift Evolution, topluluktan fikirleri kullanarak Swift'i sürekli olarak ileri götürüyor. Tartışılır, gelişir ve kabul edilir veya reddedilir. Ve bu da sadece yılda bir kez bir şey değil. Yalnızca Swift 4.2'de bir ton özellik tanıtıldı – bu küçük bir sürüm değildi!

Swift 5.0'a gelince, ABI istikrarının şovun yıldızı olduğunu söylemek güzel – geliştiricilerin görmeyi en çok arzu ettiği şey. Ama çok daha fazlası var, en az olmayan karakter dizileri, Sonuç, ve isMultiple (arasında :).

Beş yıllık zorlu hizmetten sonra, Swift Evolution sonunda string enterpolasyonu için geldi: Swift 5.0'da bize nasıl çalıştığı üzerinde büyük ölçüde daha fazla kontrol sağlayan yeni süper güçler kazanıyor.

Denemek için, bazı kodlara dalalım.

Yeni bir şey yaparsak yaş böyle bir tam sayı:

yaş = 38

Sonra onu dize enterpolasyonu ile kullanabileceğim çok açık.

print ("Merhaba, ben  (yaş).")

Peki ya bunu farklı bir şekilde biçimlendirmek istediğimize karar verirsek?

Swift 5.0'daki yeni string enterpolasyon sistemini kullanarak uzatabiliriz String.StringInterpolation kendi özel enterpolasyonlarımızı eklemek için, şöyle:

uzatma String.StringInterpolation {
    mutasyona uğramış func appendInterpolation (_ değer: Int) {
        let formatter = NumberFormatter ()
        formatter.numberStyle = .spellOut

        Eğer let result = formatter.string (from: NSNumber olarak değer) {
            appendLiteral (sonuç)
        }
    }
}

Şimdi kod, tamsayıyı metin olarak yazdıracak: “Merhaba, otuz sekiz yaşındayım.”

Tarih biçimini ayarlamak için aynı tekniği kullanabiliriz, çünkü dizelerdeki varsayılan tarihler harika görünmez. Bunu yazmayı deneyin:

print ("Bugünün tarihi  (Tarih ()).")

Swift’in tarihi “2019-02-21 23:30:21 +0000” gibi bir şeyle bastırdığını göreceksiniz. Özel bir tarih enterpolasyonuyla daha akıllı olabiliriz:

mutasyona uğramış func appendInterpolation (_ değer: Tarih) {
    let formatter = DateFormatter ()
    formatter.dateStyle = .full

    dateString = formatter.string (from: değer)
    appendLiteral (dateString)
}

Bu çok daha iyi görünüyor – bunun yerine “21 Şubat 2019 23:30:21” gibi bir şey göreceksiniz.

Bu tür bir kişiselleştirme imkanı, bu yeni dizi enterpolasyon sisteminin kalbinde yer almaktadır – nasıl çalıştığı konusunda çok daha fazla kontrolümüz var.

Not: Meslektaşlarının kafasını karıştırmamak için, Swift’in varsayılanlarını geçersiz kılmamalısın. Bu nedenle, karışıklığı önlemek için parametrelerinizi gerektiği şekilde adlandırın:

mutasyona uğramış func appendInterpolation (format değeri: Int) {

Şimdi şöyle bir format parametresi adı kullanarak diyoruz:

print ("Merhaba, ben  (biçim: yaş).")

Bu değişiklikle birlikte şu anda özel davranışları tetiklediğimiz açık.

Parametrelerle enterpolasyon

Bu küçük değişiklik, dize enterpolasyonunun parametreleri işleme şekli üzerinde tam kontrolümüz olduğunu gösteriyor. Anlıyorsun, appendInterpolation () Böylece çeşitli farklı veri türlerini benzersiz yollarla ele alabiliriz.

Örneğin, Twitter tanıtıcılarını işlemek için özel bir kod yazıp bazı kodlar yazabiliriz. heyecan Bunun gibi parametre adı:

mutasyona uğramış func appendInterpolation (twitter: String) {
    appendLiteral ("@  (Heyecan)")
}

Şimdi bunu string enterpolasyonunda kullanabiliriz:

print ("Beni Twitter'da takip etmelisin:  (twitter:" twostraws ").")

Ama neden bir parametrede durmak? Sayı formatlama örneğimizde, insanları heceleme stilini kullanmaya zorlamak için hiçbir neden yoktur – ikinci bir parametre eklemek için yöntemi değiştirebiliriz:

functing func appendInterpolation (biçim değeri: Int, stil kullanarak: NumberFormatter.Style) {

Bunu, yazım tarzını zorlamak yerine, yöntemin içinde kullanabiliriz:

functing func appendInterpolation (biçim değeri: Int, stil kullanarak: NumberFormatter.Style) {
    let formatter = NumberFormatter ()
    formatter.numberStyle = stil

    Eğer let result = formatter.string (from: NSNumber olarak değer) {
        appendLiteral (sonuç)
    }
}

Ve çağrı sitemizde kullanın:

print ("Merhaba, Ben  (format: yaş, kullanma: .spellOut).")

İstediğiniz sayıda bu parametreye sahip olabilirsiniz ve onlar da istediğiniz her şeyi olabilir.

Millet vermek istiyorum bir örnek, şöyle bir varsayılan değere sahip otomatik kapanmalar kullanıyor:

uzatma String.StringInterpolation {
    mutasyona uğramış func appendInterpolation (_ değerler: [String], boş defaultValue: @autoclosure () -> Dize) {
        eğer değerler.count == 0 {
            appendLiteral (defaultValue ())
        } Başka {
            appendLiteral (values.joined (separator: ","))
        }
    }
}

izin isimleri = ["Malcolm", "Jayne", "Kaylee"]
print ("Ekip:  (adlar boş:" Hiç kimse ").")

kullanma @autoclosure varsayılan değerleri kullanmak için basit değerler kullanabilir veya karmaşık işlevleri arayabiliriz.

Şimdi, muhtemelen dize enterpolasyon sistemini kullanmadan bu kodu tekrar yazabileceğimizi düşünüyorsunuz:

extension Array where Element == String {
    func formatlı (boş defaultValue: @autoclosure () -> String) -> String {
        eğer say == 0 {
            defaultValue () döndür
        } Başka {
            self.joined dönüş (ayırıcı: ",")
        }
    }
}

print ("Ekip:  (names.format (boş:" Hiç kimse ")).")

Ancak şimdi sadece arama sitemizi karıştırıyoruz – bir şeyi biçimlendirmeye çalışıyoruz, çünkü bu dize enterpolasyonunun noktası. Swift tarzı rehberi hatırlayın: gereksiz kelimeleri atlayın.

Erica Sadun bunun kodunuzu temizlemeye nasıl yardımcı olabileceğine dair gerçekten kısa ve tatlı bir örnek verdi:

uzatma String.StringInterpolation {
    mutasyona uğramış func appendInterpolation (eğer durum: @autoclosure () -> Bool, _ değişmez: StringLiteralType) {
        koruma koşulu () else {return}
        appendLiteral (hazır)
    }
}

doesSwiftRock = true olsun
print ("Swift rocks:  (eğer: doesSwiftRock," (*) ")")
Yazdır ("Swift kayalar  (doesSwiftRock?" (*) ":" ")")

Özel türler için enterpolasyon ekleme

Siz de kendi özel tipleriniz için enterpolasyonlar ekleyebilirsiniz:

yapı Kişi {
    var tipi: Dize
    var eylem: Dize
}

uzatma String.StringInterpolation {
    mutasyona uğramış func appendInterpolation (_ kişi: Kişi) {
        appendLiteral ("Ben bir  (person.type) ve ben yapacağım  (person.action).")
    }
}

let hater = Person (tür: "hater", eylem: "nefret")
Yazdır ("Durum kontrolü:  (hater)")

Burada dize enterpolasyonu kullanmanın güzel tarafı, nesnenin hata ayıklama açıklamasına dokunmamamızdır. Dolayısıyla, bu şeyi bir hata ayıklayıcıda görürsek veya doğrudan yazdırmayı denersek, daha önce aldığımız orijinal, el değmemiş verileri alırız:

Baskı (düşmanı)

Bu özel türü daha öncekilerden birden fazla parametreyle bile birleştirebiliriz:

uzatma String.StringInterpolation {
    mutasyona uğramış func appendInterpolation (_ kişi: Kişi, sayısı: Int) {
        let action = String (yinelenen: " (person.action)", count: count)
        appendLiteral (" n  (person.type.capitalized) olacak " (eylem) ")
    }
}

let player = Person (tür: "player", eylem: "play")
let heartBreaker = Kişi (tür: "kalp kırıcı", eylem: "ara")
let faker = Kişi (tür: "faker", eylem: "sahte")

print ("Şarkı söyleyelim:  (oyuncu, sayı: 5)  (hater, sayı: 5)  (heartBreaker, sayı: 5)  (faker, sayı: 5)")

Daha önce tahmin edemediyseniz, bu Taylor Swift’in String Enterpolation kullanarak Shake Off’ın sözleri – özür dilerim.

Elbette özel enterpolasyonlarınızı geliştirmek için Swift’in tüm dil özelliklerini kullanabilirsiniz. Örneğin, herhangi bir Encodable nesnesini kabul eden ve onu JSON olarak basan basit bir hata ayıklama enterpolasyonu yazabiliriz:

mutasyona uğramış func appendIpolasyon(hata ayıklama değeri: T) {
    let encoder = JSONEncoder ()
    encoder.outputFormatting = .prettyPrinted

    izin verirseniz sonuç = deneyin? encoder.encode (değer) {
        let str = String (kod çözme: sonuç: UTF8.self)
        appendLiteral (str)
    }
}

O zaman yaparsak Kişi uygun encodable şöyle yazdırabiliriz:

print ("İşte bazı veriler:  (hata ayıklama: faker)")

Varyadik parametreler gibi şeyleri de kullanabilir ve hatta enterpolasyonlarınızı atma olarak işaretleyebilirsiniz. Örneğin, bizim encodable genel enterpolasyon, bir kodlama hatası meydana gelirse hiçbir şey yapmaz, ancak istersek, yukarı doğru kabarcıklandırmak için hata yayılımını kullanabiliriz:

mutasyona uğramış func appendInterpolasyon(hata ayıklama değeri: T) {
    let encoder = JSONEncoder ()
    encoder.outputFormatting = .prettyPrinted

    letder = encoder.encode (value) komutunu deneyin
    let str = String (kod çözme: sonuç: UTF8.self)
    appendLiteral (str)
}

print ("Durum kontrolü:  (hata ayıklama: hater)") deneyin

Şu ana kadar baktığımız her şey, yalnızca dizelerin enterpolasyon yapma şeklini değiştiriyor.

İnterpolasyonlu yapı tipleri

Gördüğünüz gibi, bu gerçekten bizim verilerimiz uygulamalarımızda biçimlendirilme biçimini gerçekten temiz bir şekilde kontrol etmekle ilgilidir, ancak enterpolasyon kullanarak kendi türlerimizi oluşturmak için de bunu kullanabiliriz.

Bunu göstermek için enterpolasyon kullanarak bir dizgeden başlatılabilecek yeni bir tür tasarlayacağız. Bu nedenle, tümü dize enterpolasyonu kullanarak çeşitli renklerde atfedilen dizeler oluşturan bir tür yapacağız:

struct ColoredString: ExpressibleByStringInterpolation {
    // bu iç içe geçmiş yapı, çeşitli enterpolasyonlardan atfedilen bir dizgiyi birleştiren not defterimizdir
    struct StringInterpolation: StringInterpolationProtocol {
        // bu atıfta bulunularak atfedilen dizeyi sakladığımız yer
        var output = NSMutableAttributedString ()

        // metin için kullanılacak bazı varsayılan özellikler
        var baseAttribu ”tes: [NSAttributedString.Key: Any] = [.font: UIFont(name: "Georgia-Italic", size: 64) ?? .systemFont(ofSize: 64), .foregroundColor: UIColor.black]

        // bu başlatıcı gerekli ve performans optimizasyonu olarak kullanılabilir
        init (literalCapacity: Int, interpolationCount: Int) {}

        // ham metin eklememiz gerektiğinde çağrıldı
        mutasyona uğramış func appendLiteral (_ literal: String) {
            // yazdırın böylece çalışma zamanında nasıl adlandırıldığını görebilirsiniz
            print ("Ekliyor  (değişmez)")

            // temel stilimizi ver
            let attributedString = NSAttributedString (string: literal, attributes: baseAttributes)

            // bizim scratchpad dizimize ekle
            output.append (attributedString)
        }

        // dizemize renkli bir mesaj eklememiz gerektiğinde çağrıldı
        mutasyona uğramış func appendInterpolation (mesaj: Dize, renk: UIColor) {
            // tekrar yazdır
            Yazdır ("Ekleniyor  (mesaj)")

            // temel özelliklerimizin bir kopyasını alın ve rengi uygulayın
            var coloredAttributes = baseAttributes
            coloredAttributes[.foregroundColor] = renk

            // atfedilen yeni bir dizgiye sarın ve not defterimize ekleyin
            let attributedString = NSAttributedString (string: message, nitelikleri: coloredAttributes)
            output.append (attributedString)
        }
    }

    // tüm enterpolasyonlar bittiğinde, son atfedilen dizge
    izin verilen değer: NSAttributedString

    // değişmez dizgeden bir örnek oluşturun
    init (stringLiteral value: String) {
        self.value = NSAttributedString (string: value)
    }

    // enterpolasyonlu bir dizeden bir örnek oluşturun
    init (stringInterpolation: StringInterpolation) {
        self.value = stringInterpolation.output
    }
}

// şimdi dene!
let str: ColoredString = " (mesaj:" Kırmızı ", renk: .red),  (mesaj:" Beyaz ", renk: .beyaz),  (mesaj:" Mavi ", renk: .blue)"

Perdenin arkasında, bu gerçekten sadece büyük miktarlarda sözdizimsel şeker. İsteseydik, bu son kısmı tamamen elle yapabilirdik:

var enterpolasyon = ColoredString.StringInterpolation (literalCapacity: 10, interpolationCount: 1)

interpolation.appendLiteral ( "Merhaba")
interpolation.appendInterpolation (message: "Merhaba", renk: .red)
interpolation.appendLiteral ( "Merhaba")

let valentine = ColoredString (stringInterpolation: interpolation)

Sarmak

Gördüğünüz gibi, özel dize enterpolasyonu, biçimlendirme kodunu tek bir yere koymamıza izin veriyor, böylece arama sitelerimizi temiz tutabiliyoruz. Aynı zamanda, gerçekten doğal bir şekilde türler oluşturmamız için olağanüstü bir esneklik sunar.

Unutmayın, bu araç kutumuzda sadece bir araç – bizim değil sadece aracı. Bu bazen enterpolasyonu, diğer zaman fonksiyonlarını ve diğer zamanları başka bir şeyi kullanacağınız anlamına gelir. Programlamadaki birçok şey gibi, anahtar pragmatik olmaktır: duruma göre seçimler yapmak.

Aynı zamanda, bu özellik de son derece yeni, bu yüzden Swift 5.0'ın nihai olarak bir kez daha piyasaya çıkmasını sağlayanları görmek için can atıyorum.

Swift 5.0'dan bahsetmişken, string interpolasyonu Swift 5.0'daki yeni harika özelliklerden sadece biri – siteme göz atın Swift'deki Yenilikler.

Daha fazla okuma:

<! –

Sponsor Swift 4.2 ve iOS 12 için uygulamanızı güncellemekle zaten meşguldünüz, neden Instabug'un hataları bulmanıza ve düzeltmenize yardımcı olmasına izin vermiyorsunuz? Yalnızca iki kod satırı ekleyin Projenize ve dünya standartlarında bir uygulama göndermek için gereken tüm geri bildirimlerle kapsamlı raporlar alın – Daha fazlasını öğrenmek için buraya tıklayın!

->





Source link

Kategoriler: Genel

10 yorum

Ahmet · 21 Mart 2019 12:50 tarihinde

Teşekkürler

Sercan · 21 Mart 2019 13:28 tarihinde

Teşekkürler

Beste · 21 Mart 2019 13:39 tarihinde

Teşekkürler

Savaş · 21 Mart 2019 13:43 tarihinde

Teşekkürler

Basri · 21 Mart 2019 16:43 tarihinde

Teşekkürler

Berrin · 21 Mart 2019 16:43 tarihinde

Teşekkürler

Mehmet Ali · 21 Mart 2019 17:10 tarihinde

Teşekkürler

Ahmet · 21 Mart 2019 17:43 tarihinde

Teşekkürler

Mehmet Ali · 21 Mart 2019 17:44 tarihinde

Teşekkürler

Mehmet Ali · 24 Mart 2019 14:25 tarihinde

Teşekkürler

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir