Go语言中向无初始长度结构体切片赋值引发索引越界panic的解决方案咨询
[]TempGigs to ResponseGigs.Gigs Let's break down what's causing the panic and how to fix it properly.
The Root Cause
Your tempResp.Gigs slice starts out empty (length 0) when you initialize tempResp := ResponseGigs{}. When you try to access tempResp.Gigs[i] inside the loop, you're trying to reference an index that doesn't exist yet—this is exactly what triggers the "index out of range" panic.
Instead of trying to assign values directly to indices in an empty slice, you need to create new instances of the nested gig struct, populate their fields, and append them to tempResp.Gigs.
Correct Implementation
Here's how to rewrite your loop to avoid the panic and properly migrate the data:
import ( "fmt" "os" "net/http" // Ensure your utils package is imported ) // ... Your TempGigs and ResponseGigs struct definitions ... func yourHandler(w http.ResponseWriter, r *http.Request) { tempGigs := []TempGigs{} // Assume tempGigs is populated with database data here tempResp := ResponseGigs{ SectionName: "Best seller", Offset: 0, Limit: 10, TotalRows: len(tempGigs), // Set total rows to match tempGigs count } for _, gig := range tempGigs { // Create a fresh instance of the nested gig struct newGig := struct { SellerInfo struct { UserID int `json:"user_id"` Username string `json:"username"` Name string `json:"name"` ImageProfile string `json:"image_profile"` Level string `json:"level"` } `json:"seller_info"` ID int `json:"id" db:"id"` Title string `json:"title" db:"title"` Medias []struct { ID int `json:"id"` Name string `json:"name"` TypeFile string `json:"type_file"` ImageURL string `json:"image_url"` } `json:"medias"` Price int `json:"price"` Currency string `json:"currency"` Rating struct { AVGRating float64 `json:"avg_rating"` TotalReviews int `json:"total_reviews"` } `json:"rating"` Favorite bool `json:"favorite"` }{} // Populate seller info fields newGig.SellerInfo.UserID = gig.UserID newGig.SellerInfo.Name = gig.Username newGig.SellerInfo.ImageProfile = fmt.Sprintf("%s/%s", os.Getenv("STORAGE_URL"), gig.ImageProfile) newGig.SellerInfo.Level = gig.Level // Populate main gig fields newGig.ID = gig.Id newGig.Title = gig.Title newGig.Price = gig.Price newGig.Currency = gig.Currency // Populate rating fields newGig.Rating.AVGRating = gig.GigRating newGig.Rating.TotalReviews = gig.TotalReview // Set favorite status newGig.Favorite = gig.Favorite // Note: Medias remains empty here since TempGigs doesn't include media data // Add logic to populate Medias if you have that data available // Append the fully populated gig to the response slice tempResp.Gigs = append(tempResp.Gigs, newGig) } // Important: Fixed the response to return tempResp instead of tempGigs utils.HTTPJsonSuccess(w, http.StatusOK, tempResp) return }
Key Improvements
- Struct Initialization: We create a fresh instance of the nested gig struct for each item, avoiding attempts to access unallocated indices.
- Slice Appending: Using
appenddynamically growstempResp.Gigsas we add new items, eliminating index out-of-bounds issues. - Metadata Accuracy: Set
TotalRowsto the length oftempGigsto provide correct response metadata. - Response Fix: Changed the return value from
tempGigstotempResp—this was likely a typo in your original code, astempRespis the intended response structure.
Alternative: Use a Named Struct for Cleaner Code
To avoid repeating the anonymous struct definition, extract the nested gig structure into a named type. This makes your code more maintainable:
type Gig struct { SellerInfo struct { UserID int `json:"user_id"` Username string `json:"username"` Name string `json:"name"` ImageProfile string `json:"image_profile"` Level string `json:"level"` } `json:"seller_info"` ID int `json:"id" db:"id"` Title string `json:"title" db:"title"` Medias []struct { ID int `json:"id"` Name string `json:"name"` TypeFile string `json:"type_file"` ImageURL string `json:"image_url"` } `json:"medias"` Price int `json:"price"` Currency string `json:"currency"` Rating struct { AVGRating float64 `json:"avg_rating"` TotalReviews int `json:"total_reviews"` } `json:"rating"` Favorite bool `json:"favorite"` } type ResponseGigs struct { SectionName string `json:"section_name"` Offset int `json:"offset"` Limit int `json:"limit"` TotalRows int `json:"total_rows"` Gigs []Gig `json:"gigs"` // Use the named Gig type here }
Now in the loop, you can initialize newGig := Gig{} instead of repeating the full struct definition.
内容的提问来源于stack exchange,提问作者Faisal Budiman

