Map Değeri Olarak Pointer'lar
Coddy'nin GO Journey'sinin Mantık ve Akış bölümünün bir parçası — ders 27 / 68.
Struct'ları doğrudan map'lerde saklamak yararlı olsa da, struct pointer'larını saklamak güçlü bir yeteneğin kapısını açar: orijinal struct verisini doğrudan map üzerinden değiştirme yeteneği. Bu yaklaşım, verilerinizi sakladıktan sonra güncellemeniz gerektiğinde gereklidir.
Bir struct işaretçisini (pointer) bir map değeri olarak sakladığınızda, struct'ın bir kopyasını değil, bellek adresini saklamış olursunuz. İşte böyle bir map'i nasıl tanımlayacağınız ve onunla nasıl çalışacağınız:
type Product struct {
Price float64
Quantity int
}
products := map[string]*Product{
"laptop": &Product{Price: 999.99, Quantity: 5},
"mouse": &Product{Price: 25.50, Quantity: 20},
}Veriyi değiştirmeniz gerektiğinde temel avantaj netleşir. İşaretçilerle (pointers) çalıştığınız için, map üzerinden yapılan değişiklikler orijinal yapıyı (struct) etkiler:
// Laptop'ın fiyatını doğrudan map üzerinden güncelleyin
products["laptop"].Price = 899.99
fmt.Println(products["laptop"].Price) // yazdırır: 899.99Bu desen; envanter sistemleri, kullanıcı profilleri gibi depolanan verileri sık sık güncellemeniz gereken uygulamalarda veya map yapısının birincil veri deponuz olarak hizmet ettiği ve değişikliklerin kalıcı olması gerektiği her türlü senaryoda özellikle değerlidir.
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Görev
KolayYapı (struct) işaretçilerini (pointers) map değerleri olarak kullanmanın gücünü gösteren basit bir envanter yönetim sistemi oluşturun. Bu meydan okuma, işaretçi tabanlı map'lerin depolanan verilerin doğrudan değiştirilmesine nasıl olanak tanıdığını, envanter sisteminizi verimli ve güncellemelere karşı duyarlı hale getirdiğini gösterir.
Üç girdi alacaksınız:
- Ürün sayısını temsil eden bir dize (örneğin,
"4") - Şu formatta ürün verilerini içeren bir dize:
"name1:price1:quantity1,name2:price2:quantity2,name3:price3:quantity3"(örneğin,"laptop:999.99:5,mouse:25.50:20,keyboard:75.00:15,monitor:299.99:8") - Şu formatta güncelleme işlemlerini içeren bir dize:
"operation1:product1:value1,operation2:product2:value2"; burada işlemler"price"veya"quantity"olabilir (örneğin,"price:laptop:899.99,quantity:mouse:25,price:keyboard:65.00")
Göreviniz şunları yapmaktır:
- Aşağıdaki alanlara sahip bir
Productyapısı (struct) tanımlayın:Price(float64) - ürünün fiyatıQuantity(int) - ürünün stok miktarı
- Anahtarların ürün adları (string) ve değerlerin
Productyapılarına yönelik işaretçiler (pointers) olduğu bir map oluşturun - İkinci girdiden ürün verilerini ayrıştırın:
- Bireysel ürün girişlerini almak için girdiyi virgüllere göre bölün
- Her giriş için ad, fiyat ve miktarı ayırmak üzere iki nokta üst üste işaretine göre bölün
- Fiyat dizesini float64'e ve miktar dizesini tam sayıya (integer) dönüştürün
- Bir
Productyapısı oluşturun ve map içinde ona bir işaretçi saklayın
"Initial Inventory:"başlığıyla başlangıç envanterini görüntüleyin- Her ürünü şu formatta gösterin:
"[name]: $[price] (Stock: [quantity])" - Üçüncü girdiden güncelleme işlemlerini ayrıştırın ve uygulayın:
- Bireysel işlemleri almak için girdiyi virgüllere göre bölün
- Her işlem için işlem türünü, ürün adını ve yeni değeri almak üzere iki nokta üst üste işaretine göre bölün
- İlgili alanı doğrudan map işaretçisi aracılığıyla güncelleyin
- Her güncellemeyi şu formatta yazdırın:
"Updated [product]: [field] changed to [new_value]"
"Updated Inventory:"başlığıyla güncellenmiş envanteri görüntüleyin- Her ürünü başlangıçtakiyle aynı formatta tekrar gösterin
- Toplam envanter değerini hesaplayın ve görüntüleyin:
"Total Inventory Value: $[total_value]"
Fiyat ve miktar dizelerini ilgili sayısal türlerine dönüştürmek için strconv paketini kullanın. Görüntülerken tüm fiyatları 2 ondalık basamak olacak şekilde formatlayın. Bu meydan okuma, map'lerde işaretçileri saklamanın orijinal yapı verilerini doğrudan değiştirmenize nasıl olanak tanıdığını, değerleri map'e yeniden atamaya gerek kalmadan envanter güncellemelerinizi anında ve kalıcı hale getirdiğini gösterir.
Kopya kağıdı
Map'ler, struct'lara (yapılara) işaret eden pointer'ları (işaretçileri) saklayabilir ve bu sayede orijinal struct verisinin map üzerinden doğrudan değiştirilmesine olanak tanır:
type Product struct {
Price float64
Quantity int
}
products := map[string]*Product{
"laptop": &Product{Price: 999.99, Quantity: 5},
"mouse": &Product{Price: 25.50, Quantity: 20},
}Map değerleri olarak pointer kullanıldığında, map üzerinden yapılan değişiklikler orijinal struct'ı etkiler:
// Laptop fiyatını doğrudan map üzerinden güncelleyin
products["laptop"].Price = 899.99
fmt.Println(products["laptop"].Price) // çıktı: 899.99Bu desen, map'in birincil veri deposu olarak hizmet ettiği envanter sistemleri veya kullanıcı profilleri gibi sık veri güncellemesi gerektiren uygulamalar için değerlidir.
Kendin dene
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
// Girdiyi oku
var numProductsStr string
var productDataStr string
var operationsStr string
fmt.Scanln(&numProductsStr)
fmt.Scanln(&productDataStr)
fmt.Scanln(&operationsStr)
// TODO: Burada Product struct'ını tanımlayın
// TODO: Ürün işaretçilerini (pointers) saklamak için bir map oluşturun
// TODO: Ürün sırasını korumak için bir slice oluşturun (tutarlı çıktı sağlamak için)
// TODO: Ürün verilerini ayrıştırın ve map'i doldurun
// Şunları unutmayın:
// - Münferit girişleri almak için productDataStr'yi virgüllere göre ayırın
// - Her giriş için isim, fiyat ve miktarı almak üzere iki nokta üst üste ile ayırın
// - Fiyat ve miktar dizelerini uygun türlere dönüştürün
// - Product struct işaretçisini map içinde saklayın
// - Ürün adını sıra (order) slice'ına ekleyin
// TODO: Başlangıç envanterini görüntüleyin
// Ürünler arasında tutarlı bir şekilde gezinmek için sıra slice'ını kullanın
// Format: "[name]: $[price] (Stock: [quantity])"
// TODO: Güncelleme işlemlerini ayrıştırın ve uygulayın
// Şunları unutmayın:
// - Münferit işlemleri almak için operationsStr'yi virgüllere göre ayırın
// - Her işlem için tür, isim ve değeri almak üzere iki nokta üst üste ile ayırın
// - İlgili alanı doğrudan map işaretçisi üzerinden güncelleyin
// - Her işlem için güncelleme mesajını yazdırın
// TODO: Güncellenmiş envanteri görüntüleyin
// Yine, tutarlı çıktı için sıra slice'ını kullanın
// Görüntülerken toplam değeri hesaplayın
// TODO: Toplam envanter değerini hesaplayın ve görüntüleyin
// Format: "Total Inventory Value: $[total_value]"
}Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Mantık ve Akış bölümündeki tüm dersler
1İleri Seviye Kontrol Akışı
`fallthrough` ile Switchİç İçe Döngülerden ÇıkmaBelirli Bir Döngüye Devam Etme`goto` İfadesiÖzet - İleri Seviye Döngü Kontrolü4Proje: Basit Görev Listesi
Proje KurulumuGörev Ekleme2Structlar ve Metotlar
Structlarda Metot TanımlamaValue Receiver'larPointer Receiver'larReceiver SeçimiMetotlar ve FonksiyonlarÖzet - Struct Davranışı5Derinlemesine Map'ler
Struct Map'leriMap Değeri Olarak Pointer'larNil Map KontrolüMap'leri KarşılaştırmaÖzet - Kelime Frekansı Sayacı3Arayüzler (Temeller)
Arayüz Nedir?Bir Arayüz TanımlamaBir Arayüzü UygulamaArayüz Tiplerini KullanmaBoş ArayüzTip OnaylamalarıTip SeçimiÖzet - Şekiller ve Davranışlar