如何将切片元素传递给函数?

huangapple go评论145阅读模式
英文:

How to pass a slice element to a function

问题

我正在整理一些代码,并尝试将一个作为结构体的切片值传递给一个函数。

我的结构体如下所示:

type GetRecipesPaginatedResponse struct {
    Total       int         `json:"total"`
    PerPage     int         `json:"per_page"`
    CurrentPage int         `json:"current_page"`
    LastPage    int         `json:"last_page"`
    NextPageURL string      `json:"next_page_url"`
    PrevPageURL interface{} `json:"prev_page_url"`
    From        int         `json:"from"`
    To          int         `json:"to"`
    Data        []struct {
        ID               int       `json:"id"`
        ParentRecipeID   int       `json:"parent_recipe_id"`
        UserID           int       `json:"user_id"`
        Name             string    `json:"name"`
        Description      string    `json:"description"`
        IsActive         bool      `json:"is_active"`
        IsPublic         bool      `json:"is_public"`
        CreatedAt        time.Time `json:"created_at"`
        UpdatedAt        time.Time `json:"updated_at"`    		
        BjcpStyle struct {
            SubCategoryID   string `json:"sub_category_id"`
            CategoryName    string `json:"category_name"`
            SubCategoryName string `json:"sub_category_name"`
        } `json:"bjcp_style"`
        UnitType struct {
            ID   int    `json:"id"`
            Name string `json:"name"`
        } `json:"unit_type"`
    } `json:"data"`
}

在我的代码中,我从一个API获取一些JSON数据,并得到一个包含约100个项的Data切片的响应。

然后,我遍历Data切片中的每个项并进行处理。

举个例子,代码大致如下:

for page := 1; page < 3; page++ {
    newRecipes := getFromRecipesEndpoint(page, latestTimeStamp) // 这将返回一个 GetRecipesPaginatedResponse 的实例

    for _, newRecipe := range newRecipes.Data {

        if rowExists(db, "SELECT id from community_recipes WHERE id=@id", sql.Named("id", newRecipe.ID)) {
            insertIntoRecipes(db, true, newRecipe)
        } else {
            insertIntoRecipes(db, false, newRecipe)
        }
    }
}

所以,我想将一个配方的实例传递给insertIntoRecipes函数,它的定义如下:

func insertIntoRecipes(db *sql.DB, exists bool, newRecipe GetRecipesPaginatedResponse.Data) {
    if exists {
        // 更新数据库中的现有记录
        // 使用这些信息执行其他更新操作
    } else {
        // 在数据库中插入新记录
        // 使用这些信息插入其他信息
    }
}

当我运行代码时,我遇到了以下错误:

GetRecipesPaginatedResponse.Data undefined (type GetRecipesPaginatedResponse has no method Data)

我可以看出问题出在我如何将newRecipe传递给insertIntoRecipes函数的地方,即newRecipe GetRecipesPaginatedResponse.Data,但是我不太确定如何正确地传递它并声明正确的变量类型。

在遍历Data切片的每个项时,如何将Data切片中的项传递给函数?

英文:

I'm in the process of cleaning some code up and am trying to pass a slice value which is a struct to a function.

My struct looks like this:

type GetRecipesPaginatedResponse struct {
	Total       int         `json:&quot;total&quot;`
	PerPage     int         `json:&quot;per_page&quot;`
	CurrentPage int         `json:&quot;current_page&quot;`
	LastPage    int         `json:&quot;last_page&quot;`
	NextPageURL string      `json:&quot;next_page_url&quot;`
	PrevPageURL interface{} `json:&quot;prev_page_url&quot;`
	From        int         `json:&quot;from&quot;`
	To          int         `json:&quot;to&quot;`
	Data        []struct {
		ID               int       `json:&quot;id&quot;`
		ParentRecipeID   int       `json:&quot;parent_recipe_id&quot;`
		UserID           int       `json:&quot;user_id&quot;`
		Name             string    `json:&quot;name&quot;`
		Description      string    `json:&quot;description&quot;`
		IsActive         bool      `json:&quot;is_active&quot;`
		IsPublic         bool      `json:&quot;is_public&quot;`
		CreatedAt        time.Time `json:&quot;created_at&quot;`
		UpdatedAt        time.Time `json:&quot;updated_at&quot;`    		
		BjcpStyle struct {
			SubCategoryID   string `json:&quot;sub_category_id&quot;`
			CategoryName    string `json:&quot;category_name&quot;`
			SubCategoryName string `json:&quot;sub_category_name&quot;`
		} `json:&quot;bjcp_style&quot;`
		UnitType struct {
			ID   int    `json:&quot;id&quot;`
			Name string `json:&quot;name&quot;`
		} `json:&quot;unit_type&quot;`
	} `json:&quot;data&quot;`
}

In my code, I fetch some JSON data from an API and get a response back that contains about 100 items in the Data slice.

I am then looping over each item in the Data slice and processing them.

As an example, it looks something like this:

for page := 1; page &lt; 3; page++ {
	newRecipes := getFromRecipesEndpoint(page, latestTimeStamp) //this returns an instance of GetRecipesPaginatedResponse

	for _, newRecipe := range newRecipes.Data {

		if rowExists(db, &quot;SELECT id from community_recipes WHERE id=@id&quot;, sql.Named(&quot;id&quot;, newRecipe.ID)) {
			insertIntoRecipes(db, true, newRecipe)
		} else {
			insertIntoRecipes(db, false, newRecipe)
		}
	}
}

So I am trying to pass the instance of a recipe to the insertIntoRecipes function, which looks like this:

func insertIntoRecipes(db *sql.DB, exists bool, newRecipe GetRecipesPaginatedResponse.Data) {
	if exists {
		//update the existing record in the DB
        //perform some other updates with the information
	} else {
		//insert a new record into the DB
        //insert some other information using this information
	}
}

When I run this, I get the error:

> GetRecipesPaginatedResponse.Data undefined (type GetRecipesPaginatedResponse has no method Data)

I can tell that the issue is to do with how I am trying to pass the newRecipe to the insertIntoRecipes function, newRecipe GetRecipesPaginatedResponse.Data, however I am not quite sure how to pass it in and declare the right variable type.

To pass an item inside the Data slice to a function, when I am looping over each item of the Data slice, how do I do that?

答案1

得分: 4

你不能使用字段选择器引用Data字段的匿名类型。修复方法是为Data字段声明一个命名类型:

type GetRecipesPaginatedResponse struct {
    ...
    Data        []DataItem
    ...
}

type DataItem struct {
    ID               int       `json:"id"`
    ParentRecipeID   int       `json:"parent_recipe_id"`
    UserID           int       `json:"user_id"`
    Name             string    `json:"name"`
    ...
}

使用方法如下:

func insertIntoRecipes(db *sql.DB, exists bool, newRecipe DataItem) {
    ...
}

DataItem可能有更好的命名方式。

英文:

You cannot reference the anonymous type of the Data field using a field selector. The fix is to declare a named type for the Data field:

type GetRecipesPaginatedResponse struct {
    ...
    Data        []DataItem
    ...
}

type DataItem struct {
    ID               int       `json:&quot;id&quot;`
    ParentRecipeID   int       `json:&quot;parent_recipe_id&quot;`
    UserID           int       `json:&quot;user_id&quot;`
    Name             string    `json:&quot;name&quot;`
    ...
}

Use it like this:

func insertIntoRecipes(db *sql.DB, exists bool, newRecipe DataItem) {
    ...
}

There's probably a better name for DataItem.

huangapple
  • 本文由 发表于 2017年8月25日 08:07:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/45872614.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定