简体   繁体   English

在 Go 程序中返回的参数太多

[英]Too many arguments to return in Go program

I have made this simple software to connect to AWS and generate a presigned put url:我制作了这个简单的软件来连接到 AWS 并生成一个预先签名的 put url:

package main

import (
    "fmt"
    "log"
    "time"

    "github.com/minio/minio-go"
    "github.com/kelseyhightower/envconfig"
)

// AWS contains the configuration to connect and create a presigned url on AWS.
type AWS struct {
  Endpoint        string
  AccessKeyId     string
  SecretAccessKey string
  SSL             bool
  BucketHost      string
  BucketKey       string
}

func main() {
    url, err = generatePresignedPutUrl()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(url)
}

func generatePresignedPutUrl() {
    var aws AWS
    if err := envconfig.Process("aws", &aws); err != nil {
        return err
    }

    svc, err := minio.New(aws.Endpoint, aws.AccessKeyId, aws.SecretAccessKey, aws.SSL)
    if err != nil {
        return err
    }

    url, err := svc.PresignedPutObject(aws.BucketHost, aws.BucketKey, time.Second * 24 * 60 * 60)
    if err != nil {
        return url, err
    }
}

But when I try to run go run main.go , the following errors show in my terminal:但是当我尝试运行go run main.go ,我的终端中会显示以下错误:

# command-line-arguments
./main.go:23:5: undefined: url
./main.go:23:10: undefined: err
./main.go:23:39: generatePresignedPutUrl() used as value
./main.go:24:8: undefined: err
./main.go:25:19: undefined: err
./main.go:27:17: undefined: url
./main.go:33:9: too many arguments to return
    have (error)
    want ()
./main.go:38:9: too many arguments to return
    have (error)
    want ()
./main.go:43:9: too many arguments to return
    have (*url.URL, error)
    want ()

What exactly am I doing wrong here?我到底做错了什么? I started to learn go a few days ago.几天前我开始学习围棋。 I'm sorry if this is to much obvious.如果这太明显了,我很抱歉。


Update:更新:

I was able to figure it out that I should declare what I'm returning from generatePresignedPutUrl , but still:我能够弄清楚我应该声明我从generatePresignedPutUrl返回的内容,但仍然:

package main

import (
    "fmt"
    "log"
    "time"

    "github.com/minio/minio-go"
    "github.com/kelseyhightower/envconfig"
)

// AWS contains the configuration to connect and create a pre-signed url on AWS.
type AWS struct {
  Endpoint        string
  AccessKeyId     string
  SecretAccessKey string
  SSL             bool
  BucketHost      string
  BucketKey       string
}

func main() {
    url, err := generatePresignedPutUrl()
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(url)
}

// generatePresignedPutUrl connects to S3 and generates a pre-signed put url
// using configurations from environemnt variables.
func generatePresignedPutUrl() (url string, err error) {
    var aws AWS
    if err := envconfig.Process("aws", &aws); err != nil {
        return err
    }

    svc, err := minio.New(aws.Endpoint, aws.AccessKeyId, aws.SecretAccessKey, aws.SSL)
    if err != nil {
        return err
    }

    url, err := svc.PresignedPutObject(aws.BucketHost, aws.BucketKey, time.Second * 24 * 60 * 60)
    if err != nil {
        return url, err
    }

    return url
}

Errors:错误:

# command-line-arguments
./main.go:36:9: not enough arguments to return
    have (error)
    want (string, error)
./main.go:41:9: not enough arguments to return
    have (error)
    want (string, error)
./main.go:44:14: no new variables on left side of :=
./main.go:44:14: cannot assign *url.URL to url (type string) in multiple assignment
./main.go:49:5: not enough arguments to return
    have (string)
    want (string, error)

First things first, you should really do the tour of go as JimB said.首先,你真的应该像 JimB 所说的那样进行围棋之 It takes less than an hour and you would know the answer to this questions.不到一个小时,您就会知道这些问题的答案。

Notice that you are declaring url and err on the return declaration of generatePresignedPutUrl() and it doesn't look like that was what you wanted to do.请注意,您在generatePresignedPutUrl()的返回声明中声明了urlerr并且看起来这不是您想要做的。 You should change the function declaration from:您应该将函数声明从:

func generatePresignedPutUrl() (url string, err error) {

To:到:

func generatePresignedPutUrl() (string, error) { // Without the variable names

Now lets address your errors in order:现在让我们按顺序解决您的错误:

Error 1: not enough arguments to return错误 1:没有足够的参数返回

Error is Go are not really cryptic.错误是 Go 并不神秘。 not enough arguments to return means literally what it says. not enough arguments to return意味着它所说的字面意思。 You are trying to return less arguments than the ones you should.您试图返回的参数比您应该返回的参数少。

In Go you can return more than one value from a function but no matter how much values you return, you always need to return all the values.在 Go 中,您可以从一个函数中返回多个值,但无论您返回多少个值,您始终需要返回所有值。 Your function func generatePresignedPutUrl() (url string, err error) expects a string and an error but in return err you are just returning err which is of type error so you are missing a string , in this case because there was an error in the function return an empty string.您的函数func generatePresignedPutUrl() (url string, err error)需要一个string和一个error但在return err您只是返回类型为error err ,因此您缺少一个string ,在这种情况下,因为在函数返回一个空字符串。 To fix it just do: return "", err instead.要修复它,只需执行以下操作: return "", err改为return "", err

Error 2: no new variables on left side of :=错误 2: := 左侧没有新变量

Again not really cryptic.再次不是很神秘。 It means none of the variables on the left of := are new.这意味着:=左边的变量都不是新的。 The := declares a new variable and then assigns the value to that variable, so if the variable isn't new you get an error when trying to declare it. :=声明一个新变量,然后将值分配给该变量,因此如果该变量不是新变量,则在尝试声明它时会出现错误。 In this case you declared url on the function declaration and err on the second line of the function.在这种情况下,您在函数声明中声明了url ,在函数的第二行声明了err To fix it replace:要修复它,请替换:

url, err := svc.PresignedPutObject(aws.BucketHost, aws.BucketKey, time.Second * 24 * 60 * 60)

For:为了:

url, err = svc.PresignedPutObject(aws.BucketHost, aws.BucketKey, time.Second * 24 * 60 * 60)

Error 3: cannot assign *url.URL to url (type string) in multiple assignment错误 3:无法在多重赋值中将 *url.URL 分配给 url(类型字符串)

You are trying to assign a type *url.URL to the variable url which is a string .您正在尝试将类型*url.URL分配给变量url ,它是一个string In Go you can only assign something to a variable if they are from the same type.在 Go 中,如果变量来自相同类型,则只能为变量赋值。 Here are the docs for the url.URL type.是 url.URL 类型的文档。 To fix it do:要修复它,请执行以下操作:

rawUrl, err := svc.PresignedPutObject(aws.BucketHost, aws.BucketKey, time.Second * 24 * 60 * 60)
if err != nil {
    return "", err
}

return rawUrl.String() // rawUrl is of type *url.URL, so get it's string representation

From the godoc of github.com/minio-go , Client.PresignedPutObject .来自 github.com/minio-go 的godocClient.PresignedPutObject returns a *url.URL and an error返回一个*url.URL和一个error

(ie url, err := svc.PresignedPutObject(aws.BucketHost, aws.BucketKey, time.Second * 24 * 60 * 60) ) (即url, err := svc.PresignedPutObject(aws.BucketHost, aws.BucketKey, time.Second * 24 * 60 * 60)

From your code, you probably want the url string right?从您的代码中,您可能想要 url 字符串,对吗?

If that's what you want, you can refer to this example from the godoc of *url.URL :如果这就是你想要的,你可以从*url.URL的 godoc 中参考这个例子:

Also, you can't just return an error from your function, you have to return a string and an error .此外,你不能只从你的函数返回一个错误, you have to return a string and an error

Modifying your code to return a url string, you can probably do something like this:修改您的代码以返回一个 url 字符串,您可能可以执行以下操作:

func generatePresignedPutUrl() (url string, err error) {
    var aws AWS
    if err := envconfig.Process("aws", &aws); err != nil {
        return "", err
    }

    svc, err := minio.New(aws.Endpoint, aws.AccessKeyId, aws.SecretAccessKey, aws.SSL)
    if err != nil {
        return "", err
    }

    u, err := svc.PresignedPutObject(aws.BucketHost, aws.BucketKey, time.Second * 24 * 60 * 60)
    if err != nil {
        return "", err
    }
    url = u.String()
    return url, err
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM