Golang中如何为结构体填充值
Golang中如何为结构体填充值 各位, 我有以下结构体并想要填充值,运行时出现错误,可能是我的值设置不正确
package main
import (
"fmt"
"os"
"strings"
"bufio"
)
func main() {
// 创建可多次调用的单个读取器
reader := bufio.NewReader(os.Stdin)
// 提示并读取
fmt.Print("输入 BIG-IP 管理 IP: ")
bigip_mgmt, _ := reader.ReadString('\n')
fmt.Print("输入 BIG-IP 用户名: ")
user, _ := reader.ReadString('\n')
fmt.Print("输入 BIG-IP 密码: ")
pass, _ := reader.ReadString('\n')
fmt.Print("输入 BIG-IP IPFIX 池: ")
Ipfix_pool, _ := reader.ReadString('\n')
// 去除空白字符并打印
fmt.Printf("Bigip 管理 IP: \"%s\", Bigip 用户名: \"%s\", Bigip 密码: \"%s\", Bigip IPFIX 池 \"%s\"\n",
strings.TrimSpace(bigip_mgmt), strings.TrimSpace(user), strings.TrimSpace(pass), strings.TrimSpace(ipfix_pool))
fmt.Printf(bigip_mgmt)
create := createipfx()
fmt.Println(create)
}
func createipfx() string {
type Payload struct {
Name string `json:"name"`
Monitor string `json:"monitor"`
Members []struct {
Name string `json:"name"`
Address string `json:"address"`
} `json:"members"`
}
data := Payload{
// 填充结构体
Name: "FirstIPFIXPool",
Monitor: "gateway_icmp ",
Members: Members[]{
{
Name: Ipfix_pool:4739,
Address: Ipfix_pool,
},
},
}
fmt.Println(data)
payloadBytes, err := json.Marshal(data)
if err != nil {
// 处理错误
}
body := bytes.NewReader(payloadBytes)
req, err := http.NewRequest("POST", os.ExpandEnv("https://bigip_mgmt/mgmt/tm/ltm/pool"), body)
if err != nil {
// 处理错误
}
req.SetBasicAuth(user, pass)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
// 处理错误
}
defer resp.Body.Close()
return "创建了 ipfix 池"
}
运行时出现语法错误,可能是我的 Go 结构体值设置不正确
运行 ipfix_deploy.go
./ipfix_deploy.go:43:21: 语法错误:意外的 ],期望表达式
./ipfix_deploy.go:44:6: 语法错误:意外的 {,期望表达式
./ipfix_deploy.go:45:6: 语法错误:意外的 Name,期望 ]
./ipfix_deploy.go:48:4: 语法错误:意外的 },期望表达式
./ipfix_deploy.go:49:3: 语法错误:意外的 },期望表达式
更多关于Golang中如何为结构体填充值的实战教程也可以访问 https://www.itying.com/category-94-b0.html
在我看来,为那个字段提取一个合适的类型比使用匿名结构体更简单。
请使用论坛的代码格式化功能,或者更好的做法是将你的示例发布到 play.golang.org。
是的,这就是为什么我在将代码粘贴到 Playground 时,会仔细阅读错误信息。我已经这样做过很多次了,所以已经习惯了替换那些被弄乱的引号。
scshitole:
Ipfix_pool, _ := reader.ReadString('\n')
你应该使用双引号,但这可能只是其中一个错误。
Ipfix_pool, _ := reader.ReadString('\n')
能否请您帮个忙,用三个反引号将代码正确格式化,采用Markdown风格的围栏式代码块?
这样会使代码更易于阅读,尤其是便于复制,因为引号将保持正确的引号格式。
我拒绝再次修复这些问题……
已完成,我认为在以下代码处出现了复合字面量缺少类型的错误:
Members: {
{
Name: "Ipfix_pool:4739",
Address: "Ipfix_pool",
},
},
请仔细查看我是如何修复这个问题的。你需要从外围结构中复制匿名结构体的声明。
Members: []struct {
Name string `json:"name"`
Address string `json:"address"`
}{
{
Name: "Ipfix_pool:4739",
Address: "Ipfix_pool",
},
},
你还在运行playground上的相同代码吗?
那个只有// handle error here注释的代码?请用适当的错误处理替换这些注释,创建一个包含正确代码的playground或gist。但也许当你引入错误处理时,你就会发现问题,因为我猜你没有正确设置连接或无法连接到主机之类的情况。
// handle error here
NobbZ:
不,使用
\n没问题。ReadString 接收一个字节作为参数,虽然 rune 类型可以强制转换为字节,但字符串类型不行,所以这里需要使用单引号。
我将这段代码复制到 Playground 后报错了,但现在发现帖子中的普通单引号实际上被替换成了其他类型的引号(’ 和 ')😄 而且我完全没有查看函数签名。
@NobbZ 谢谢,但是在我输入所有值后现在出现了运行时panic错误
SJC-ML-SHITOLE:tetration shitole$ go run ipfix_deploy.go
Enter BIG-IP Management IP: 10.192.74.73
Enter username for BIG-IP: admin
Enter password for BIG-IP: admin
Enter IPFIX Pool for BIG-IP: 15.1.1.1
Bigip Management is: "10.192.74.73", Bigip username : "admin", Bigip pass : "admin", Bigip IPFIX Pool "15.1.1.1"
10.192.74.73
value of data {Name:FirstIPFIXPool Monitor:gateway_icmp Members:[{Name:Ipfix_pool:4739 Address:Ipfix_pool}]}panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x11fc67d]
goroutine 1 [running]:
main.createipfx(0x0, 0x0)
/Users/shitole/tetration/ipfix_deploy.go:75 +0x38d
main.main()
/Users/shitole/tetration/ipfix_deploy.go:30 +0x58e
exit status 2
不,'\n' 没问题。ReadString 接受一个 byte 作为参数,rune 可以强制转换为 byte,但字符串不行,所以这里使用单引号。
我猜这与第 42 行的 Members: Members[]{...} 有关。
- Members 不是一个已定义的结构体。
- Members(结构体字段)接受一个 []struct{…}
在我用以下代码修复之后:
Members: []struct {
Name string `json:"name"`
Address string `json:"address"`
}{
{
Name: "Ipfix_pool:4739",
Address: "Ipfix_pool",
},
},
由于第 24 行未定义 ipfix_pool,我确实遇到了另一个错误。通过简单地将 ipfix_pool 重命名为 Ipfix_pool 来修复它,然后导致了下一个错误:
prog.go:53:22: undefined: json
prog.go:57:9: undefined: bytes
prog.go:59:13: undefined: http
prog.go:63:18: undefined: user
prog.go:63:24: undefined: pass
prog.go:66:14: undefined: http
我可以通过添加到 import 语句 来修复大部分错误:
import (
...
"encoding/json"
"bytes"
"net/http"
)
但仍然剩下这两个错误:
prog.go:66:18: undefined: user
prog.go:66:24: undefined: pass
我不会深入探讨这个问题。我把这些留给原帖作者。
PS:这是我在 Playground 上的当前结果链接:https://play.golang.org/p/zSNoyD_DsGa
感谢您的建议,我已经进行了修改,但现在出现了这个错误:prog.go:46:12: 复合字面量中缺少类型
package main
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
"strings"
)
func main() {
// 创建一个可多次调用的读取器
reader := bufio.NewReader(os.Stdin)
// 提示并读取输入
fmt.Print("输入 BIG-IP 管理 IP: ")
bigip_mgmt, _ := reader.ReadString('\n')
fmt.Print("输入 BIG-IP 用户名: ")
user, _ := reader.ReadString('\n')
fmt.Print("输入 BIG-IP 密码: ")
pass, _ := reader.ReadString('\n')
fmt.Print("输入 BIG-IP IPFIX 池: ")
Ipfix_pool, _ := reader.ReadString('\n')
// 去除空白字符并打印
fmt.Printf("Bigip 管理 IP: \"%s\", Bigip 用户名: \"%s\", Bigip 密码: \"%s\", Bigip IPFIX 池 \"%s\"\n",
strings.TrimSpace(bigip_mgmt), strings.TrimSpace(user), strings.TrimSpace(pass), strings.TrimSpace(Ipfix_pool))
fmt.Printf(bigip_mgmt)
create := createipfx()
fmt.Println(create)
}
func createipfx() string {
type Payload struct {
Name string `json:"name"`
Monitor string `json:"monitor"`
Members []struct {
Name string `json:"name"`
Address string `json:"address"`
} `json:"members"`
}
data := Payload{
// 填充结构体
Name: "FirstIPFIXPool",
Monitor: "gateway_icmp ",
Members: {
{
Name: "Ipfix_pool:4739",
Address: "Ipfix_pool",
},
},
}
fmt.Println(data)
payloadBytes, err := json.Marshal(data)
if err != nil {
// 处理错误
}
body := bytes.NewReader(payloadBytes)
req, err := http.NewRequest("POST", os.ExpandEnv("https://bigip_mgmt/mgmt/tm/ltm/pool"), body)
if err != nil {
// 处理错误
}
req.SetBasicAuth("user", "pass")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
// 处理错误
}
defer resp.Body.Close()
return "已创建 ipfix 池"
}
在您的代码中,结构体填充存在几个语法错误。主要问题在于结构体成员初始化的写法不正确。以下是修正后的代码:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
"strings"
"bufio"
)
// 将变量声明为包级变量,以便在函数间共享
var (
bigip_mgmt string
user string
pass string
Ipfix_pool string
)
func main() {
// 创建可多次调用的单个读取器
reader := bufio.NewReader(os.Stdin)
// 提示并读取
fmt.Print("输入 BIG-IP 管理 IP: ")
bigip_mgmt, _ = reader.ReadString('\n')
fmt.Print("输入 BIG-IP 用户名: ")
user, _ = reader.ReadString('\n')
fmt.Print("输入 BIG-IP 密码: ")
pass, _ = reader.ReadString('\n')
fmt.Print("输入 BIG-IP IPFIX 池: ")
Ipfix_pool, _ = reader.ReadString('\n')
// 去除空白字符并打印
fmt.Printf("Bigip 管理 IP: \"%s\", Bigip 用户名: \"%s\", Bigip 密码: \"%s\", Bigip IPFIX 池 \"%s\"\n",
strings.TrimSpace(bigip_mgmt), strings.TrimSpace(user), strings.TrimSpace(pass), strings.TrimSpace(Ipfix_pool))
create := createipfx()
fmt.Println(create)
}
func createipfx() string {
type Payload struct {
Name string `json:"name"`
Monitor string `json:"monitor"`
Members []struct {
Name string `json:"name"`
Address string `json:"address"`
} `json:"members"`
}
// 修正结构体填充
data := Payload{
Name: "FirstIPFIXPool",
Monitor: "gateway_icmp",
Members: []struct {
Name string `json:"name"`
Address string `json:"address"`
}{
{
Name: fmt.Sprintf("%s:4739", strings.TrimSpace(Ipfix_pool)),
Address: strings.TrimSpace(Ipfix_pool),
},
},
}
fmt.Printf("%+v\n", data)
payloadBytes, err := json.Marshal(data)
if err != nil {
return fmt.Sprintf("JSON 序列化错误: %v", err)
}
body := bytes.NewReader(payloadBytes)
// 使用正确的 URL 构建
url := fmt.Sprintf("https://%s/mgmt/tm/ltm/pool", strings.TrimSpace(bigip_mgmt))
req, err := http.NewRequest("POST", url, body)
if err != nil {
return fmt.Sprintf("创建请求错误: %v", err)
}
req.SetBasicAuth(strings.TrimSpace(user), strings.TrimSpace(pass))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Sprintf("HTTP 请求错误: %v", err)
}
defer resp.Body.Close()
return "创建了 ipfix 池"
}
主要修正点:
-
结构体切片初始化:将
Members: Members[]{...}修正为Members: []struct{...}{...} -
成员字段赋值:修正了
Name: Ipfix_pool:4739的语法错误,使用fmt.Sprintf来构建字符串 -
变量作用域:将输入变量声明为包级变量,使其在
createipfx函数中可用 -
字符串处理:添加了
strings.TrimSpace()来清理输入字符串中的换行符 -
URL 构建:修正了 URL 构建方式,使用正确的字符串格式化
-
错误处理:为 JSON 序列化和 HTTP 请求添加了基本的错误处理
这些修正解决了您遇到的语法错误,并确保结构体能够正确填充和序列化。

