Golang中如何处理GraphQL的可选字段

Golang中如何处理GraphQL的可选字段 在我的 GraphQL 模式中有几个可选字段

cityId: Int!
amount: Int!
loanTerm: Int!
schemeId: Int
historyId: Int
earlyRepayment: Boolean
earningsConfirmation: Boolean

而在我的 Go 语言中有这个结构体

   CityID               int   `json:"cityId"`
Amount               int   `json:"amount"`
LoanTerm             int   `json:"loanTerm"`
SchemeID             *int  `json:"schemeId"`
HistoryID            *int  `json:"historyId"`
EarlyRepayment       *bool `json:"earlyRepayment"`
EarningsConfirmation *bool `json:"earningsConfirmation"`

如你所见,可选字段有指向 int 的指针(*int),在使用前我应该检查它们是否为 nil 值吗?


更多关于Golang中如何处理GraphQL的可选字段的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

是的,你必须这样做。因为如果你尝试使用指针变量指向的值,而该指针为 nil,程序将会出现 panic。所以

var p *int
...
if p != nil {
    a := *p + 32
}

更多关于Golang中如何处理GraphQL的可选字段的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中处理GraphQL的可选字段时,使用指针类型是正确的做法。对于可选字段,确实需要在访问前检查是否为nil,否则可能会导致运行时panic。

以下是一个完整的示例,展示如何处理这些可选字段:

package main

import (
    "encoding/json"
    "fmt"
)

type LoanApplication struct {
    CityID               int   `json:"cityId"`
    Amount               int   `json:"amount"`
    LoanTerm             int   `json:"loanTerm"`
    SchemeID             *int  `json:"schemeId"`
    HistoryID            *int  `json:"historyId"`
    EarlyRepayment       *bool `json:"earlyRepayment"`
    EarningsConfirmation *bool `json:"earningsConfirmation"`
}

func main() {
    // 示例1: 部分可选字段为nil
    app1 := LoanApplication{
        CityID:   1,
        Amount:   100000,
        LoanTerm: 12,
        SchemeID: nil,
        HistoryID: func() *int {
            id := 5
            return &id
        }(),
        EarlyRepayment:       nil,
        EarningsConfirmation: func() *bool {
            b := true
            return &b
        }(),
    }

    // 安全访问可选字段
    processApplication(app1)

    // 示例2: JSON序列化和反序列化
    jsonData := `{
        "cityId": 1,
        "amount": 100000,
        "loanTerm": 12,
        "historyId": 5,
        "earningsConfirmation": true
    }`

    var app2 LoanApplication
    if err := json.Unmarshal([]byte(jsonData), &app2); err != nil {
        panic(err)
    }

    processApplication(app2)
}

func processApplication(app LoanApplication) {
    fmt.Printf("必需字段 - CityID: %d, Amount: %d, LoanTerm: %d\n", 
        app.CityID, app.Amount, app.LoanTerm)

    // 检查并处理可选字段
    if app.SchemeID != nil {
        fmt.Printf("SchemeID: %d\n", *app.SchemeID)
    } else {
        fmt.Println("SchemeID: 未提供")
    }

    if app.HistoryID != nil {
        fmt.Printf("HistoryID: %d\n", *app.HistoryID)
    } else {
        fmt.Println("HistoryID: 未提供")
    }

    if app.EarlyRepayment != nil {
        fmt.Printf("EarlyRepayment: %t\n", *app.EarlyRepayment)
    } else {
        fmt.Println("EarlyRepayment: 未提供")
    }

    if app.EarningsConfirmation != nil {
        fmt.Printf("EarningsConfirmation: %t\n", *app.EarningsConfirmation)
    } else {
        fmt.Println("EarningsConfirmation: 未提供")
    }
    fmt.Println("---")
}

// 辅助函数:安全获取字段值
func getIntValue(ptr *int, defaultValue int) int {
    if ptr != nil {
        return *ptr
    }
    return defaultValue
}

func getBoolValue(ptr *bool, defaultValue bool) bool {
    if ptr != nil {
        return *ptr
    }
    return defaultValue
}

对于数据库操作,也需要进行nil检查:

func saveToDatabase(app LoanApplication) error {
    // 处理必需字段
    query := fmt.Sprintf("INSERT INTO loans (city_id, amount, loan_term) VALUES (%d, %d, %d)", 
        app.CityID, app.Amount, app.LoanTerm)

    // 处理可选字段
    if app.SchemeID != nil {
        query += fmt.Sprintf(", scheme_id = %d", *app.SchemeID)
    }

    if app.HistoryID != nil {
        query += fmt.Sprintf(", history_id = %d", *app.HistoryID)
    }

    if app.EarlyRepayment != nil {
        query += fmt.Sprintf(", early_repayment = %t", *app.EarlyRepayment)
    }

    if app.EarningsConfirmation != nil {
        query += fmt.Sprintf(", earnings_confirmation = %t", *app.EarningsConfirmation)
    }

    // 执行数据库操作
    fmt.Println("SQL:", query)
    return nil
}

在GraphQL解析器中,也需要类似的nil检查:

func (r *Resolver) CreateLoanApplication(args struct {
    CityID               int
    Amount               int
    LoanTerm             int
    SchemeID             *int
    HistoryID            *int
    EarlyRepayment       *bool
    EarningsConfirmation *bool
}) (*LoanApplication, error) {
    
    app := &LoanApplication{
        CityID:               args.CityID,
        Amount:               args.Amount,
        LoanTerm:             args.LoanTerm,
        SchemeID:             args.SchemeID,
        HistoryID:            args.HistoryID,
        EarlyRepayment:       args.EarlyRepayment,
        EarningsConfirmation: args.EarningsConfirmation,
    }

    // 业务逻辑处理
    if app.EarlyRepayment != nil && *app.EarlyRepayment {
        // 处理提前还款逻辑
    }

    return app, nil
}

是的,在使用可选字段前必须检查是否为nil,这是处理GraphQL可选字段的标准做法。

回到顶部