Go 1.22 sürümü
(go.dev)fordöngüsü değişkenleri artık her yinelemede yeniden oluşturuluyor; böylece istemeden paylaşımdan kaynaklanan hataların önüne geçiliyor, ayrıca tamsayılar üzerinderangede mümkün hale geliyor- Uyumluluk, Go 1 uyumluluk taahhüdünü koruyor ve neredeyse tüm Go programlarının eskisi gibi derlenip çalışması bekleniyor
- Çalışma alanlarında
go work vendorile oluşturulan vendor dizini kullanılabiliyor; çalışma alanındavendorvarsa-mod=vendorvarsayılan oluyor GO111MODULE=offolan legacyGOPATHmodunda, modül dışındakigo getdesteği kaldırıldı;go buildvego testgibi diğer derleme komutları legacyGOPATHprogramlarında çalışmaya devam ediyor- Runtime artık tür tabanlı GC meta verisini heap nesnelerine daha yakın konumlandırıyor; bu da Go programlarının CPU performansını %1–3 artırıyor ve birçok programda bellek ek yükünü yaklaşık %1 azaltıyor
- Bazı nesne adresi hizalamaları önceki 16 bayt ve üzeri yerine 8 bayt hizalamaya düşebilir; daha yüksek hizalama varsayan assembly kodunun güncellenmesi gerekir, geçici çözüm olarak
GOEXPERIMENT=noallocheaderskullanılabilir - PGO derlemeleri artık daha fazla çağrıyı devirtualize edebiliyor; temsili Go programları kümesinde PGO etkinleştirildiğinde çalışma zamanı performansı %2–14 iyileşiyor
- Standart kütüphaneye ilk
v2paketi olanmath/rand/v2eklendi;Readdevralınmıyor, global üretici her durumda rastgele seed alıyor,ChaCha8vePCGkaynakları ileNjenerik fonksiyonu sunuluyor net/http.ServeMuxyönlendirme desenleri artık method ve wildcard desteği sunuyor;{}içeren desenlerde ve escape edilmiş yol işlemede küçük alt uyumluluk kırılmaları var,GODEBUG=httpmuxgo121=1ile önceki davranış geri getirilebiliyorcrypto/tlssunucusunda varsayılan en düşük sürüm, belirtilmediğinde TLS 1.2 olarak değişti; TLS 1.3 öncesi handshake sürecinde ECDHE içermeyen cipher suite'ler artık varsayılan olarak sunulmuyor- Çalıştırma izleyicisi baştan aşağı yenilendi; çoğu platformda OS saatini kullanıyor, akış halinde işlenebilen bölünmüş trace desteği sağlıyor, toplam syscall süresini ve goroutine'in hangi OS thread üzerinde çalıştığını gösteriyor
tracearacı web arayüzü, yeni tracer desteği kapsamında güncellendi; Go 1.22 ve sonrası ile derlenen programların trace çıktılarında thread odaklı görünüm ve toplam syscall süresi gösterimi destekleniyorvet, Go 1.22 döngü değişkeni semantiğine uygun olacak şekilde loop closure uyarılarını güncelliyor; ayrıca değersizappend,deferiçindeki gecikmesiztime.Sincevelog/slogkey/value uyumsuzluğu için yeni uyarılar ekleniyor- Bootstrap için Go 1.20'nin son point release'i veya daha yenisi gerekiyor; Go 1.24'ün de Go 1.22'nin son point release'i veya daha yenisini gerektirmesi bekleniyor
darwin/amd64üzerinde Go toolchain artık varsayılan olarak PIE üretiyor; Go 1.22, macOS 10.15 Catalina'da çalışan son sürüm olacak ve Go 1.23 için macOS 11 Big Sur veya üzeri gerekecekgo/typespaketineAliastürü veUnaliasfonksiyonu eklendi;gotypesalias=1durumunda istemcilerinAliastürünü işlemesi gerekiyorslices.Delete,DeleteFunc,Compact,CompactFunc,Replaceartık küçültülen aralıktaki öğeleri zero'lıyor;Insertiseiaralık dışındaysa her zaman panic üretiyor- Windows dizin okuma işlevleri artık öğeleri toplu halde okuyarak sistem çağrısı sayısını azaltıyor ve performansı %30'a kadar artırıyor
1 yorum
Hacker News yorumları
Son 3 yıldır ağırlıklı olarak TypeScript kullanıyordum, yakın zamanda Go kullanmaya başladım; başta dizi fonksiyonlarının eksikliği ya da daha az esnek tip sistemi yüzünden biraz endişeliydim.
Ama 4-5 kişilik bir ekip için TypeScript projesini yeniden kurmayı deneyince, linting, sunucu yönlendirme kütüphanesi seçimi, sunucu seçimi, kodlama standartları, temel hata işleme, iç içe
try/catchcehenneminden kaçınmak için özel hata ya daResulttipi dayatmak, test ve mocking, Prisma ayarı gibi şeylere çok fazla zaman gitti.TypeScript’i seviyorum ama harika bir standart kütüphanesi, düzgün tip güvenliği ve yerleşik kodlama standartları olan bir dil kullanmak gerçekten rahat. Go’nun da kendine has tuhaflıkları var ama oldukça iyi; routing’in bile standart kütüphaneye girmesi, düşünülmesi gereken bir şeyi daha azalttığı için güzel. Şimdi sadece slice’lar için
map/filter/findfonksiyonlarını bekliyorum.TypeScript her sürümde power user’lar için giderek karmaşıklaşırken, Go tamsayılar üzerinde
rangegibi eksik kalan şeyleri ekleyerek kullanımı daha basit hale getiriyor.Bu, oyun devam yapımlarının ayarları ve mekanikleri sürekli artırıp sonra yeni kullanıcılar için reset gerektirmesine benziyor; programlama dillerinde bunu yapmak zor olduğundan Go’nun bunun farkında olması iyi.
go:embedvego:generateile yapılabilenler, başka projelerde her gördüğümde etkileyici geliyor.golang.org/xpaketlerinin de neredeyse tüm internet RFC’leriyle ilgili uygulamaları kullanıma hazır şekilde sunması güzel.map/filter/findgelene kadar lodash’tan ilham alan lo kütüphanesini kullanabilirsiniz.Go projelerinde severek kullandığım çok amaçlı araç: https://github.com/samber/lo
Bir şey yapmak için dokümantasyonu okuyordum, kısa süre sonra biri dokümanlarda olmayan işe yarar bir numarayı söylüyordu; bu sürekli tekrarlandı.
Resmî sürüm notları biraz kuru gelirse, interaktif bir sürüm hazırladım: https://antonz.org/go-1-22
fordöngüsü değişkeninin paylaşılması sorunu başta hemen anlaşılmamıştı; kendim çalıştırıp beklenmedik sonucu görmek yardımcı oldu.CompactveReplaceörnekleri kafa karıştırıcı; bunun doğru olup olmadığını bilmiyorum.Go’yu 9 yıldan uzun süredir kullanıyorum; son 4 yıldır Flutter yüzünden Dart’ı da çok kullandım ve bence iki dilin karmaşıklığa yaklaşımı taban tabana zıt. Dart mümkün olan her özelliği eklemeye çalışıyor, Go ise bunun tersi.
Birincisi, Dart’ta bir sınıf içinde değerleri başlatmanın o kadar çok yolu var ki buna çok zaman harcanıyor.
final/const/static/lateöneklerine göre constructor, factory, FlutterStatefulWidget’ınıninitState()’i gibi başlatma yerleri değişiyor; refactoring yapınca başlatmayı ciddi biçimde elden geçirmek gerekiyor. Fonksiyon gibi davranan getter’lar da yeni codebase’lerde kafa karışıklığını artırıyor.İkincisi, Dart’ta map, stream vb. tek satıra sıkıştırmaya uygun çok özellik var; bu da anlaşılması zor tek satırlık kodları hızla yazma isteği doğuruyor. Ama debug ederken ya da junior geliştiriciler
firstWhereOrNullgibi hack’lerle veorElse: () => nullgibi opsiyonel parametrelerle karşılaştığında çok karışıyor. Anlaşılması güç null safety ya da tip hataları da sık sık yolu kesiyor; bunları basit Go tarzı birfordöngüsüne çevirmek gerçekten rahatlatıyor.initStatekullanmamak iyi olur. Örneğin bir metin alanı ipucunu ayarlamak gibi bir şey değilse kaçınmayı tercih ederim.Çoğu Flutter sayfasının yapacak çok az işi olur; ya da parent bir
MyPageControllernesnesi oluşturur, istediği şekilde başlatır ve child sayfanın o controller’a göre davranmasını sağlar. Örneğin bir liste sayfasında kullanıcı bir öğeyi düzenlemek istediğinde controller oluşturup öğeyi içine koyarak child sayfaya gönderirseniz, geri dönüldükten sonra parent controller’daki öğeye veya değişkenlere/callback’lere bakıp UI değişikliğine karar verebilir.Böylece
InheritedWidgetgibi şeylere dokunmadan widget’lar arası etkileşimi ince ayrıntıda kontrol edebilirsiniz. Elbette bunu bir state management kütüphanesiyle kullanmak iyi olur, ama pratikte kullanılmadığı durumlar da çok.rangede aynı şekilde; sonuçta yazılan karakter sayısıforEach(f)gibi comprehension’lara benzer olsa da üç satıra yayıldığı için daha uzun görünür, ama açıp yazınca büyük bir mesele değildir.Yine de başlatma konusunda Go’da struct alanlarını belirli bir değere başlatmanın idiomatik bir yolu olmasını isterdim. Constructor olmaması sorun değil ama bazen bir
bool’un varsayılan olaraktruebaşlatılmasını istediğim oluyor.initState,StatefulWidget’ın override’ıdır ve diğer framework’lerdeki lifecycle event’lerinden farklı değildir; Flutter tarafına ait bir kavramdır, constructor ile karıştırılacak nitelikte değildir.Normal constructor ile factory’den hangisini kullanmak gerektiği kafa karıştırabilir ama
initStateyüzünden Go’nun üstün olduğunu söylemek zor.io.Copy,TCPConn’danUnixConn’a kopyalarken mümkünse Linux’unsplice(2)sistem çağrısını kullanıyor ve yeniTCPConn.WriteTometodundan yararlanıyor.Interface upgrade’iyle bir kez daha şeffaf biçimde zero-copy I/O artmış oluyor.
iopaketinde bu desenle elde edilen etki gerçekten büyük.Yine de beklenen sınırlar içinde.
Geliştirilmiş yönlendirme desenleri, Gorilla Mux’un geleceğinin belirsiz olduğu şu dönemde iyi bir iyileştirme
Ancak bu değişiklik küçük bir şekilde geriye dönük uyumluluğu bozuyor;
{ve}içeren desenlerin davranışının değişmesi gibi açık kısımlar da var, kaçışlanmış yolların işlenmesi gibi daha az belirgin kısımlar da.GODEBUGiçindekihttpmuxgo121alanıyla kontrol ediliyor;httpmuxgo121=1ayarlanırsa eski davranışa dönülebiliyorAma “Go 1 belirtimine göre yazılmış programlar, bu belirtimin ömrü boyunca değişiklik olmadan derlenmeye ve doğru çalışmaya devam eder” diyen Go 1 uyumluluk vaadi ile neden çelişmediğini merak ediyorum
go.modiçindekigoyönergesi değerine bağlamak1.22 veya üzeriyse yeni kütüphane davranışını alıyorsun, değilse eski davranışı. Pratikte ne kadar iyi işleyeceğini görmek gerekecek
{ve}kullanımının çok nadir olduğunu görmüşlerdirYeni davranışı kapatmanın bir yolunu da sunuyorlar, yani kod değişikliğini zorunlu kılmıyorlar; yine de yeni bir ortam değişkeni ayarlamak gerekiyor
Bu sürümdeki
fordöngüsü semantiği değişikliği de benzer bir örnek; fiilen bozucu bir değişiklik. Yine de tüm Go programları derlenmeye ve çalışmaya devam ediyor, yalnızca bazı davranışlar biraz değişiyor. Go’nun pragmatik bir yaklaşım seçtiğini düşünüyorum; bu da başarı nedenlerinden biriydigo.modkullanılacaksa, en azından daha iyi bir şekilde bozmalıgo.mod1.22’ye değiştirildiğinde incelikli çalışma zamanı sorunlarını bulmaya çalışmaktansa, kodun derlenememesi çok daha iyi olurduGo 1.22’de döngünün her yinelemesi yeni bir değişken oluşturuyor
Bu konu burada daha önce de tartışılmıştı: https://news.ycombinator.com/item?id=33160236 - Go: Redefining For Loop Variable Semantics (2022)
Eski kafalı olabilirim ama fonksiyonlar üzerinde
rangeeklenmesini sevmiyorum. Dile eklenen karmaşıklığı haklı çıkaracak kadar büyük bir kolaylık sağlamıyor; fonksiyonel tarz da Go’nun açık, imperatif, lafı uzun ama az özellikli tarzıyla uyumsuz görünüyor. Bence bu, Go’nun büyük avantajlarından biriydiAynı nedenle tamsayılar üzerinde
rangede yanlış yönde bir adım gibi geliyor. Go’nun ince özellik seti ve düşük bilişsel yükü her zaman başlıca güçlü yanı ve ayırt edici özelliğiydiYazılım geliştirmedeki büyük sorunlardan biri, geliştiricilerin karmaşıklık eklemesini veya yetenek gösterisi yapmasını engellemek. Özellikle kariyerinin başındaki geliştiriciler, sorunu doğrudan ama daha az zarif ve daha uzun bir şekilde çözüp geçmek yerine, çözümü aşırı karmaşıklaştırma eğiliminde oluyor
Go’nun mevcut generics desteği bunu taşıyacak kadar gelişmiş değil; bu yüzden tuhaf şekilde zorlanmış kısıtlar ortaya çıkıyor
sql.Null[T]eklenmesi iyi olmuş. Yeni projelerde muhtemelen kullanmaya başlarımŞu anki işimde API’si oldukça benzer olan sqlboiler’ın null [0] paketine bağımlıyım.
sql.Nullgibi davranıyor ama değerin açıkça hiç ayarlanıp ayarlanmadığını söyleyen ek birIsSet() boolmetodu var; bu da “bilerek null” ile “başlatılmadığı için null” ayrımına yardımcı oluyor. İyi görünüyor ama pratikte hiç kullanmadımStandart kütüphane mux’una yeniden bakıp chi’yi kaldırmanın da mümkün olup olmayacağını merak ediyorum. Böyle özelliklerin standart kütüphaneye girmesi gerçekten güzel
Bu tür özellikler standart kütüphaneye girince her zaman bakımı yapılmış oluyor ve birçok Go programında aynı yaklaşımın kullanılmasını sağlıyor
Go’yu production’da kullananlar en yeni sürüme hızlıca geçebiliyor mu, yoksa eski sürümlere mi bağlı kalıyor, merak ediyorum
Açık projelere bakınca nispeten yeni özelliklerden çoğu zaman kaçınılıyor gibi görünüyor. Generics kullanmasam bile eski
interface{}yerine Go 1.18’de gelenanykullanmak istiyorum; ikincisinin daha “idiomatic” olduğu da söyleniyorBu sefer biraz karıştı; biz varsayılanı 1.21’e yükseltmeden Go ekibi 1.22’yi çıkardı. Artık beklemek neredeyse bir teamül gibi; Go sürümlerinin bir şeyleri bozması nadirdir
Örneğin generics’i gerçekten kullanmadan önce yaklaşık 6 ay bekledik; kullanışlılığı, geliştirici deneyimini ve derleme/test hızı etkisinin büyük olmadığını kontrol ettik
Ama Go ile son kullanıcı uygulamaları da sunuyoruz; bu tarafta eski istemci işletim sistemleriyle uyumluluk nedeniyle 1.20’de kalmamız gerekiyor. 1.21’de önemli bir kesinti olduğu için muhtemelen birkaç yıl 1.20’de kalacağız
latestcontainer’ı ile build ve test yapıyor; test paketi de oldukça sağlam olduğu için fiilen otomatik güncelleniyoruz. Bir şey uymazsa pipeline kırılıyor; o noktada son çalışan sürüme sabitlemeye mi yoksa bozucu değişiklik düzeltilene kadar güncellemeyi ertelemeye mi karar veriyoruzBirkaç yılda bir yeni sürüm ile üçüncü taraf paketler arasında ince bir edge-case bug ortaya çıkabiliyor; ama böyle bir bug tanımı gereği test paketinden kaçmış olduğundan, manuel yükseltme yapsaydık da muhtemelen yakalayamazdık
Eski Go derleyicilerini desteklemekten endişeleniyorsan, eski sürümler için build koşulları koyup eksik olanları tanımlayabilirsin. Örneğin
// +build !go1.7altındatype any = interface{}koyabilirsin