Scope and Shadowing
Ko'lam (scope) va soyalash (shadowing)
Har bir o'zgaruvchi ma'lum bir ko'lam (scope)da yashaydi — odatda uni o'rab turgan { } bloki ichida. Muammo shundaki, ichki blokda := bilan tashqaridagi bilan bir xil nomli yangi o'zgaruvchi yaratish mumkin — bu tashqi o'zgaruvchini soyalaydi (shadow), uni o'zgartirmaydi.
func ProcessBroken() (int, error) {
value, err := FetchValue()
if err != nil {
return 0, err
}
if value > 0 {
value, err := FetchUpdatedValue() // XATO: yangi, soyalangan value!
if err != nil {
return 0, err
}
_ = value // bu faqat if bloki ichida ko'rinadi
}
return value, nil // tashqi value hali eski qiymatda
}Bu — Go'da eng ko'p uchraydigan nozik xatolardan biri, chunki := bilan yozilgan kod to'g'ri ko'rinadi va hatto kompilyatsiya bo'ladi. Muammo shu: if bloki ichidagi value, err := yangi value va errni e'lon qiladi (chunki chap tomonda kamida bitta yangi nom bo'lsa, := barcha nomlarni qayta e'lon qiladi), tashqaridagi value esa o'zgarishsiz qoladi.
if value > 0 {
v2, err := FetchUpdatedValue()
if err != nil {
return 0, err
}
value = v2 // TO'G'RI: = bilan tashqi value'ni o'zgartiradi
}To'g'ri yechim — yangi o'zgaruvchiga boshqa nom berish (v2), so'ngra uni tashqi valuega = (yangi e'londirmasdan, oddiy tayinlash) bilan yozish.
>_ Exercise
Berilgan FetchValue, FetchUpdatedValue va soyalash xatosi bo'lgan ProcessBrokendan foydalanib, ProcessFixed() (int, error) funksiyasini yozing — u xuddi shu mantiqni bajaradi, lekin soyalashsiz: ichki natijani v2 deb nomlab, tashqi valueni = bilan yangilang.
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
:= chap tomonidagi kamida bitta nom yangi bo'lsa, barcha nomlarni shu blok ko'lamida qayta e'lon qiladi — bu tashqi o'zgaruvchini soyalab, uni o'zgartirmasdan qoldirishi mumkin. Mavjud o'zgaruvchini haqiqatan yangilash uchun oddiy = (tayinlash) ishlatiladi, yangi nom bilan emas.
$ go run main.go
Kodingizni ishga tushiring