代码之家  ›  专栏  ›  技术社区  ›  Naguib Ihab

对go中的结构返回nil

go
  •  4
  • Naguib Ihab  · 技术社区  · 7 年前

    我连接到一个数据库,获取一行,然后将其发送回用户。不过我想做的是 return 如果找不到该行或有错误,则返回语句。

    因为我返回的是一个结构,我不能返回nil并且我得到了这个错误 cannot use nil as type Item in return argument (项是我的结构)

    我在网上看到,如果我在return语句中使用指针并返回*item而不是item,那么当我试图创建 item := *Item{} 我得到以下错误 invalid indirect of Item literal (type Item)

    我想有一些解决办法,但我找不到,我真正想知道的是:

    • 如何返回指针*项而不是项
    • 有没有其他方法可以返回一个结构的nil?

    这是我的代码:

    package main
    
    import (
        "fmt"
        "github.com/aws/aws-lambda-go/lambda"
    
      "github.com/aws/aws-sdk-go/aws"
      "github.com/aws/aws-sdk-go/aws/session"
      "github.com/aws/aws-sdk-go/service/dynamodb"
      "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
    )
    
    type Request struct {
        Name string `json:"name"`
    }
    
    type Item struct {
      Name string `json:"name"`
      Stock int `json:"stock"`
      Price float64 `json:"price"`
    }
    
    func Handler(request Request) (Item, error) {
      sess, err := session.NewSession(&aws.Config{
        Region: aws.String("us-west-2")},
      )
    
      // Create DynamoDB client
      svc := dynamodb.New(sess)
    
      result, err := svc.GetItem(&dynamodb.GetItemInput{
        TableName: aws.String("Inventory"),
        Key: map[string]*dynamodb.AttributeValue{
          "name": {
              S: aws.String(request.Name),
          },
        },
      })
    
      if err != nil {
        fmt.Println(err.Error())
    //     return nil, err
      }
    
      item := Item{}
    
      err = dynamodbattribute.UnmarshalMap(result.Item, &item)
    
      if err != nil {
        panic(fmt.Sprintf("Failed to unmarshal Record, %v", err))
    //     return nil, err
      }
    
      if item.Name == "" {
          fmt.Println("Could not find item")
    //       return nil, nil
      }
    
      fmt.Println("Found item:")
      fmt.Println("Name:  ", item.Name)
      fmt.Println("Stock: ", item.Stock)
      fmt.Println("Price:  ", item.Price)
    
        return item, nil
    }
    
    func main() {
        lambda.Start(Handler)
    }
    
    1 回复  |  直到 5 年前
        1
  •  10
  •   Elias Van Ootegem    7 年前

    你正在分配 item 变量错误。你说你试过了 item := *Item{} ,而创建指针的方法是使用 new 内置,或创建一个文本和运算符的地址( & )。后一种方法是您在Golang最常见的方法。有些情况下,人们会使用 新的 ,但在这种情况下,我会选择第二种方法:

    所以:

    item := &Item{}
    // or
    item := new(Item)
    

    最后,您可以保持代码的原样,只需在末尾返回一个指针:

    item := Item{}
    // some code here
    return &item, nil
    

    如果您必须返回错误,您仍然可以 return nil, err

    所以把所有的东西放在一起:

    // return *Item instead of Item
    func Handler(request Request) (*Item, error) {
       // your code here, eg:
       item := Item{}
       if err := dynamodbattribute.UnmarshalMap(result.Item, &item); err != nil {
            return nil, err
        }
        return &item, nil
    }
    

    或者,指定 项目 从一开始就是一个指针

    func Handler(request Request) (*Item, error) {
       // your code here, eg:
       item := &Item{}
       if err := dynamodbattribute.UnmarshalMap(result.Item, item); err != nil {
            return nil, err
        }
        return item, nil
    }