为什么未定义:将自定义结构作为指针传递时抛出错误?

Why is undefined: error thrown while passing custom struct as pointers?

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    type CustomInfo struct {
        Name string
        Size int
    }

    type Error struct {
        ErrorCode int
        ErrorMsg  string
    }
    type Product struct {
        Fruit string
        CInfo CustomInfo
        Err   Error
    }

    var pr1 = Product{
        Fruit: "Orange",
        CInfo: CustomInfo{
            Name: "orango botanica",
            Size: 3,
        },
        Err: Error{
            ErrorMsg:  "",
        },
    }

    var pr2 = Product{
        Fruit: "Apple",
        CInfo: CustomInfo{
            Name: "appleo botanica",
            Size: 4,
        },
        Err: Error{
            ErrorMsg:  "",
        },
    }

    var products []Product
    products = append(products, pr1, pr2)
    mrshl, _ := json.Marshal(products)

    var productsRes []Product
    err := json.Unmarshal([]byte(mrshl), &productsRes)
    if err != nil {
        fmt.Println(err)
    }
    //fmt.Println(productsRes[0].Fruit)
    //fmt.Println(productsRes[1])
    //fmt.Println(unmrshl)
    validate(&productsRes)
}

func validate(bRes *Product){
    fmt.Println(bRes[0].Fruit)
    fmt.Println(bRes[1])
}

为什么我得到 ./prog.go:61:22: undefined: Product

您的结构定义在 main 中,因此超出了 validate 的范围,它只能在您的主函数内部使用。当您将结构定义移出 main

时,它应该可以工作

此外,您的 validate 函数可能应该接受 []ProductProduct 的切片),而不是 *Product(指向单个 Product 的指针)

我稍微修改了您更新的 playground 示例 here

您不需要指向 切片的指针,您只想传递切片本身。传递指针本身并不是错误的,只是在这里没有必要。切片意味着:"I (main) give you (validate) access to an array I have made." 切片 header 提供 user-of-the-slice:

  • 访问数组(通过索引:bRes[i] 是数组的第 i 个元素);
  • 数组的长度:len(bRes)for 循环隐含地使用它;和
  • 数组的容量(本例中未使用)。

通过写入 bRes[i],我们可以更新基础数组中 Product 之一的任何或所有字段。这就是我添加到 validate 的第二个循环所做的。

注:第 47-48 行,内容为:

var products []Product
products = append(products, pr1, pr2)

使用 append 有点奇怪:因为我们只有两个产品,我们可以直接构建切片:

products := []Product{pr1, pr2}

products 的值最初将是 nil。 nil 切片 header 实际上表示长度和容量均为零,毕竟没有底层数组。附加到 nil 切片总是会导致 append 分配一个新的底层数组。 append 函数 returns 新切片,它使用新数组。1 所以在设置这个 nil 切片时有一点点浪费,只是为了扔掉它。再一次,这不是错误,只是没有必要。

(与此同时,检查 json.Unmarshal 的错误得到 +1 分,但 不检查 则得到 -1 分,或者减半分来自 json.Marshal 的错误。)


1append 总是构造一个新切片header。在某些情况下,新 header 可能 re-use 旧数组。或者它可能使用一个新数组。 append 操作将 re-use 旧的 already-existing 数组,当且仅当追加的元素根据原始切片 header 指示的容量适合现有数组。由于nil header 的容量为零,因此不能在此处使用其现有数组。