为什么未定义:将自定义结构作为指针传递时抛出错误?
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
函数可能应该接受 []Product
(Product
的切片),而不是 *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 的容量为零,因此不能在此处使用其现有数组。
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
函数可能应该接受 []Product
(Product
的切片),而不是 *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 的容量为零,因此不能在此处使用其现有数组。