我想这样做:
R, _ := strconv.Atoi(reader.ReadString(" ")) // reader = bufio.NewReader()
问题是,strconv.Atoi需要一个参数,但reader.ReadString()不仅返回字符串,还返回" err"。有没有办法解决这个问题而不创建变量或一般只在一行?
答案 0 :(得分:0)
在Go中执行此操作的惯用方法是使用通常的if err != nil
优雅地处理错误。使用它。
reader := bufio.NewReader(strings.NewReader("93 31 11 11"))
numRaw, err := reader.ReadString(' ')
if err != nil {
log.Fatal(err)
}
// We need to substring numRaw because it contains also the trailing space (this is how ReadString works in bufio.Reader)
num, err := strconv.Atoi(numRaw[:len(numRaw)-1])
if err != nil {
log.Fatal(err)
}
log.Print(num)
如果您想使代码“更干净”,请将其拆分为函数。
func main() {
reader := bufio.NewReader(strings.NewReader("93 31 11 11"))
n, err := readInt(reader)
if err != nil {
log.Fatal(err)
}
log.Print(n)
}
func readInt(r *bufio.Reader) (int, error) {
numRaw, err := r.ReadString(' ')
if err != nil {
return 0, err
}
return strconv.Atoi(numRaw[:len(numRaw)-1])
}
为了完整起见,在某些情况下忽略错误是有用的,因为你知道不会有任何错误。这种情况包括始终给出相同输入的解析器,即。正则表达式和模板。这些提供了有用的习语“必须”:例如,regexp.MustCompile
是一个非常简单的regexp.Compile
包装器,如果它不是零,它会检查错误和恐慌。
func MustCompile(str string) *Regexp {
regexp, error := Compile(str)
if error != nil {
panic(`regexp: Compile(` + quote(str) + `): ` + error.Error())
}
return regexp
}
当有一个正则表达式用作单例并在全局范围内声明时,这在Go程序中最常见。
var usernameRegex = regexp.MustCompile("^[0-9A-Za-z-]+$")
func main() {
fmt.Println(usernameRegex.MatchString("Hello"))
fmt.Println(usernameRegex.MatchString(""))
}
为了帮助考虑何时使用或添加“必须”功能,我将其视为“如果Go中有一种方法可以添加编译时检查,那么这将是一个好用的地方它”。
正如我所说,Go标准库的模板包中也提供了这一点,例如html/template
。这些并不能为所有内容提供必需功能,但它们具有简单的template.Must
功能(更接近于您在OP中尝试的功能)。通过这种方式,您可以“链接”通常会返回模板和错误的函数,以便它们只返回模板(如果有任何错误,则会发生混乱)。
var t = template.Must(template.New("hi").Parse(`{{ if .Bool }}Hello{{ else }}Goodbye{{ end }} world!`))
func main() {
t.ExecuteTemplate(os.Stdout, "hi", struct{Bool bool}{Bool: false})
}
这很有效,因为template.Must
有一个签名func(*Template, error)
,而Parse
返回(*Template, error)
,所以返回值和函数参数匹配。例如,如果strconv.Atoi
具有签名func(string, error)
,那么您的示例可能有用。
答案 1 :(得分:0)
在Go中,编写一个readInt
函数以隐藏复杂性并始终检查错误。其他答案也有错误:Howl(删除最后一个数字)和Raduan Santos(未编译)。
例如,
package main
import (
"bufio"
"fmt"
"io"
"log"
"strconv"
"strings"
)
func readInt(r *bufio.Reader) (int, error) {
const delim = ' '
str, err := r.ReadString(delim)
if err != nil && len(str) == 0 {
return 0, err
}
str = strings.TrimSuffix(str, string(delim))
return strconv.Atoi(str)
}
func main() {
input := "93 31 11 11"
fmt.Println(input)
rdr := bufio.NewReader(strings.NewReader(input))
for {
n, err := readInt(rdr)
if err != nil {
if err == io.EOF {
break
}
log.Fatal(err)
}
fmt.Println(n)
}
}
输出:
93 31 11 11
93
31
11
11