簡體   English   中英

為切片沒有長度的結構切片賦值

[英]Assign value to slice of struct which the slice have no length

我有一塊結構來容納來自數據庫的數據。 我的結構如下所示:

type TempGigs struct {
    Id           int     `json:"id" db:"id"`
    Title        string  `json:"title" db:"title"`
    UserID       int     `json:"user_id" db:"user_id"`
    Price        int     `json:"price" db:"price"`
    Currency     string  `json:"currency" db:"currency"`
    Username     string  `json:"username" db:"username"`
    ImageProfile string  `json:"image_profile" db:"image_profile"`
    Level        string  `json:"level" db:"level"`
    GigRating    float64 `json:"gig_rating" db:"gig_rating"`
    TotalReview  int     `json:"total_review" db:"total_review"`
    CreatedAt    int     `json:"created_at" db:"created_at"`
    Favorite     bool    `json:"favorite" db:"favorite"`
}

我想將數據從[]TempGigs[]Gigs Gigs結構定義為:

type ResponseGigs struct {
    SectionName string `json:"section_name"`
    Offset      int    `json:"offset"`
    Limit       int    `json:"limit"`
    TotalRows   int    `json:"total_rows"`
    Gigs        []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"`
    } `json:"gigs"`
}

當我用for迭代TempGigs以復制到[]Gigs時,編譯時沒有錯誤。 但是,當提交請求時,程序會出現panic: runtime error: index out of range [0] with length 0 我曾嘗試使用append但我不明白如何正確使用append

這是我的迭代代碼:

tempGigs := []TempGigs{}
tempResp := ResponseGigs{}
tempResp.SectionName = "Best seller"
tempResp.Offset = 0
tempResp.Limit = 10
for i := range tempGigs {
    tempResp.Gigs[i].SellerInfo.UserID = tempGigs[i].UserID
    tempResp.Gigs[i].SellerInfo.Name = tempGigs[i].Username
    tempResp.Gigs[i].SellerInfo.ImageProfile = fmt.Sprintf("%s/%s", os.Getenv("STORAGE_URL"), tempGigs[i].ImageProfile)
    tempResp.Gigs[i].SellerInfo.Level = tempGigs[i].Level
    tempResp.Gigs[i].ID = tempGigs[i].Id
    tempResp.Gigs[i].Title = tempGigs[i].Title
    tempResp.Gigs[i].Price = tempGigs[i].Price
    tempResp.Gigs[i].Currency = tempGigs[i].Currency
    tempResp.Gigs[i].Rating.AVGRating = tempGigs[i].GigRating
    tempResp.Gigs[i].Rating.TotalReviews = tempGigs[i].TotalReview
    tempResp.Gigs[i].Favorite = tempGigs[i].Favorite
}
utils.HTTPJsonSuccess(w, http.StatusOK, tempGigs)
return

您的問題已在評論中得到正確回答,但也許它可以幫助您獲得有關代碼的更多反饋。

從結構中提取子類型

ResponseGigs是一個具有多個子結構的大型結構,因此很難使用。 將子結構提取為額外類型會使事情變得更容易。

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"`
}

type Gig struct {
    SellerInfo SellerInfo `json:"seller_info"`
    ID         int        `json:"id" db:"id"`
    Title      string     `json:"title" db:"title"`
    Medias     []Media    `json:"medias"`
    Price      int        `json:"price"`
    Currency   string     `json:"currency"`
    Rating     Rating     `json:"rating"`
    Favorite   bool       `json:"favorite"`
}

type SellerInfo struct {
    UserID       int    `json:"user_id"`
    Username     string `json:"username"`
    Name         string `json:"name"`
    ImageProfile string `json:"image_profile"`
    Level        string `json:"level"`
}

type Media struct {
    ID       int    `json:"id"`
    Name     string `json:"name"`
    TypeFile string `json:"type_file"`
    ImageURL string `json:"image_url"`
}

type Rating struct {
    AVGRating    float64 `json:"avg_rating"`
    TotalReviews int     `json:"total_reviews"`
}

type TempGig struct {
    Id           int     `json:"id" db:"id"`
    Title        string  `json:"title" db:"title"`
    UserID       int     `json:"user_id" db:"user_id"`
    Price        int     `json:"price" db:"price"`
    Currency     string  `json:"currency" db:"currency"`
    Username     string  `json:"username" db:"username"`
    ImageProfile string  `json:"image_profile" db:"image_profile"`
    Level        string  `json:"level" db:"level"`
    GigRating    float64 `json:"gig_rating" db:"gig_rating"`
    TotalReview  int     `json:"total_review" db:"total_review"`
    CreatedAt    int     `json:"created_at" db:"created_at"`
    Favorite     bool    `json:"favorite" db:"favorite"`
}

創建一個額外的 function 以將TempGig轉換為Gig

接下來我要做的是創建一個 function 將TempGig轉換為Gig (我將TempGigs TempGig因為該結構僅包含一個 gig,而不是多個):

func toGig(in TempGig) Gig {
    return Gig{
        SellerInfo: SellerInfo{
            UserID:       in.UserID,
            Name:         in.Username,
            ImageProfile: in.ImageProfile,
            Level:        in.Level,
        },
        ID:       in.Id,
        Title:    in.Title,
        // ...
    }
}

填充響應slice

為了盡量減少處理程序代碼,我還將創建一個額外的 function 來構建ResponseGigs結構。 例如:

func toResponse(section string, in []TempGig) ResponseGigs {
    var gigs []Gig
    // or to preallocate the memory space / capacity (not the length!)
    // gigs := make([]Gig, 0, len(in))

    for _, tempGig := range in {
        gigs = append(gigs, toGig(tempGig))
    }
    
    return ResponseGigs{
        SectionName: section,
        Gigs:        gigs,
    }
}

或者,您可以預先分配切片的長度並使用索引。 我更喜歡append方法,因為它不易出錯。

    // preallocate the length of the slice (not only the capacity)
    gigs := make([]Gig, len(in))
    for i, tempGig := range in {
        gigs[i] = toGig(tempGig)
    }

處理程序代碼

最后,處理程序代碼將歸結為如下內容:

    tempResp := toReponse("Best seller", tempGigs)
    tempResp.Offset = 0
    tempResp.Limit = 10
    utils.HTTPJsonSuccess(w, http.StatusOK, tempResp)
    return

希望這有助於下一步。 有很多東西可以根據自己的喜好進行調整。 快樂編碼!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM