Meydan okuma 1 - Reflection
- Go kursu
- İleri seviye
- Ders 65/68
- 8 dk
reflect ile bir yapıdan JSON üreten bir araç yazarsın.
Meydan okuma: mini JSON kodlayıcı
Bu meydan okumada reflection ile struct alanlarını etiketlerine göre okuyan küçük bir kodlayıcı yazacaksın. Kurallar: alan adı json etiketinden alınır; etiket "-" ise alan atlanır; etiket yoksa alan adı kullanılır.
type User struct {
Ad string `json:"ad"`
Sifre string `json:"-"`
Yas int
}
// beklenen: ad=Ada Yas=36Plan
Adımlar: reflect.TypeOf ve reflect.ValueOf al → NumField döngüsü → her alan için etiketi oku → "-" ise continue → boşsa f.Name → ad=değer parçasını bir dilime ekle → strings.Join ile birleştir. Gizli alanlarda (küçük harf) Interface() panic üretir; onları da f.IsExported() ile atla.
Uygulama Kodlayıcıyı yaz
encode(v any) string fonksiyonunu yaz ve yukarıdaki User{"Ada", "1234", 36} değeri için sonucu yazdır. Çıktı ad=Ada Yas=36 olmalı.
Başlangıç kodu
package main
import (
"fmt"
"reflect"
"strings"
)
func main() {
// buraya yaz
}Örnek çözüm
package main
import (
"fmt"
"reflect"
"strings"
)
type User struct {
Ad string `json:"ad"`
Sifre string `json:"-"`
Yas int
}
func encode(v any) string {
t, val := reflect.TypeOf(v), reflect.ValueOf(v)
var parts []string
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
tag := f.Tag.Get("json")
if tag == "-" || !f.IsExported() {
continue
}
if tag == "" {
tag = f.Name
}
parts = append(parts, fmt.Sprintf("%s=%v", tag, val.Field(i).Interface()))
}
return strings.Join(parts, " ")
}
func main() {
fmt.Println(encode(User{"Ada", "1234", 36}))
}Beklenen çıktı
ad=Ada Yas=36
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Etiketi olmayan alanın adını nereden alırsın?
- Tag.Get("json")
- Value.String()
- Type.Name()
- StructField.Name Doğru cevap
Açıklama: Tag.Get boş döner; bu durumda StructField.Name (Go'daki alan adı) kullanılır. Type.Name() ise struct türünün adıdır.
2 Alanı atla
if tag == "-" || !f.IsExported() {
____
}
if tag == "-" || !f.IsExported() {
continue
}
Açıklama: continue yalnızca bu alanı atlayıp döngünün sonraki adımına geçer.
3 Kural ve kod
| Kavram | Anlamı |
|---|---|
Etiket "-" |
continue |
Etiket yok |
f.Name |
Gizli alan |
!f.IsExported() |
Birleştirme |
strings.Join |