我可以通过同一个结果返回一个字符串或一个`error`值吗?

huangapple go评论67阅读模式
英文:

Can I return either a string or an `error` value via the same result?

问题

我想执行函数并将输出结果返回到变量中,这是我的实际代码:

package main

import (
    "os"
    "net/http"
    "io"
    "fmt"
    "strings"
)


func downloadFile(url string) (string, error) {

  resp, err := http.Get(url)
  if err != nil {
    return "", err
  }

  // 从重定向的链接中提取文件名。
  finalURL := resp.Request.URL.String()
  parts    := strings.Split(finalURL, "/")
  filename := parts[len(parts)-1]

  out, errr := os.Create(filename)
  if errr != nil  {
    return "", errr
  }

  _, err = io.Copy(out, resp.Body)
  if err != nil  {
    return "", err
  }

  defer out.Close()
  defer resp.Body.Close()

  return filename, nil
}

func main() {

  var url1 string = "https://transfer.sh/5e2iH/test.txt"
  var filename2 string = "test test test"

  filename2, err := downloadFile(url1)

  if err != nil {
    fmt.Println(err)
    return
  }

  fmt.Println(filename2)

}

你在代码中有几个错误:

  1. downloadFile函数的返回类型中,你需要同时返回stringerror类型。将函数签名修改为func downloadFile(url string) (string, error)

  2. main函数中,你需要使用:=来声明并赋值filename2变量,而不是使用=。修改为filename2, err := downloadFile(url1)

  3. main函数中,你需要检查downloadFile函数的返回错误。如果有错误发生,你可以打印错误并返回。添加以下代码:

if err != nil {
  fmt.Println(err)
  return
}

这些修改应该能够解决你遇到的问题。希望对你有帮助!

英文:

i want execute function and return output results on variable, this is my actual code :

package main

import (
    "os"
    "net/http"
    "io"
    "fmt"
    "strings"
)


func downloadFile(url string) (err error) {

  resp, err := http.Get(url)
  if err != nil {
    return err
  }

  // extrage numele fisierului din linkul redirectionat.
  finalURL := resp.Request.URL.String()
  parts    := strings.Split(finalURL, "/")
  filename := parts[len(parts)-1]

  out, errr := os.Create(filename)
  if errr != nil  {
    return errr
  }

  _, err = io.Copy(out, resp.Body)
  if err != nil  {
    return err
  }

  defer out.Close()
  defer resp.Body.Close()

  return filename
}

func main() {

  var url1 string = "https://transfer.sh/5e2iH/test.txt"
  var filename2 string = "test test test"

  filename2 := downloadFile(url1)

  fmt.Println( filename2 )

}

i want execute function downloadFile and return variable filename in variable filename2, return me this error, where im wrong ? im python developer, im sure to make stupid error 我可以通过同一个结果返回一个字符串或一个`error`值吗?

F:\dev\GoLang\gitlab\check>go run download.go
# command-line-arguments
.\download.go:37:3: cannot use filename (type string) as type error in return ar
gument:
        string does not implement error (missing Error method)
.\download.go:45:13: no new variables on left side of :=
.\download.go:45:13: cannot use downloadFile(url1) (type error) as type string i
n assignment

答案1

得分: 1

Go是一种强类型语言,所以一个函数不能根据情况返回错误或字符串。

幸运的是,Go可以从函数中返回两个变量,这是实现你想要的功能的首选方式。返回一个字符串和一个错误,并且如果没有错误,则返回nil作为错误。

函数签名应该是:

func downloadFile(url string) (filename string, err error) {
    ......
   // 由于在函数签名中命名了变量,所以在最后你可以直接写:
   return
}

调用函数应该同时检查错误和返回的字符串,就像你的代码在调用os.Create(filename)时所做的那样。

英文:

Go is strongly typed, so a function cannot return either an error or a string, depending on the case.

Luckily Go can return two variables from a function, and this is the preferred way to achieve what you want. Return a string AND an error, and return nil as the error if there isn't one.

The function signature should be

func downloadFile(url string) (filename string, err error) {
    .....
   // and since the variables are named in the signature, at the end you can just do:
   return
}

The caller function should check both the error and the returned string, just like your code is doing for example when calling os.Create(filename)

答案2

得分: 1

downloadFile()函数中,你不能像字符串一样使用error,你应该同时处理这两个变量。Golang是强类型的,不能改变变量的类型。你可以使用接口来实现多态性,但在这种情况下,你只需要像这样一起返回errfilename

package main

import (
	"os"
	"net/http"
	"io"
	"fmt"
	"strings"
)


func downloadFile(url string) (err error, filename string) {

	resp, err := http.Get(url)
	defer resp.Body.Close()

	if err != nil {
		return
	}

	// 从重定向的链接中提取文件名。
	finalURL := resp.Request.URL.String()
	parts    := strings.Split(finalURL, "/")
	filename = parts[len(parts)-1]

	out, err := os.Create(filename)
	defer out.Close()
	if err != nil  {
		return
	}

	_, err = io.Copy(out, resp.Body)
	if err != nil  {
		return
	}

	return
}

func main() {

	var url1 string = "https://transfer.sh/5e2iH/test.txt"
	err, file := downloadFile(url1)
	if err != nil {
		panic(err.Error())
	}
	fmt.Println( file )

}
英文:

You can't use error like a string in the downloadFile() function, you should work with both variables. Golang is strongly typed and couldn't change the type of variable. You can use interfaces for polymorphism but in this case, you need just return err and filename together like this:

package main

import (
	"os"
	"net/http"
	"io"
	"fmt"
	"strings"
)


func downloadFile(url string) (err error, filename string) {

	resp, err := http.Get(url)
	defer resp.Body.Close()

	if err != nil {
		return
	}

	// extrage numele fisierului din linkul redirectionat.
	finalURL := resp.Request.URL.String()
	parts    := strings.Split(finalURL, "/")
	filename = parts[len(parts)-1]

	out, err := os.Create(filename)
	defer out.Close()
	if err != nil  {
		return
	}

	_, err = io.Copy(out, resp.Body)
	if err != nil  {
		return
	}

	return
}

func main() {

	var url1 string = "https://transfer.sh/5e2iH/test.txt"
	err, file := downloadFile(url1)
	if err != nil {
		panic(err.Error())
	}
	fmt.Println( file )

}

huangapple
  • 本文由 发表于 2017年9月8日 05:21:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/46105281.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定