无效的间接类型:func (int) string

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

Invalid indirect of type func (int) string

问题

我遇到了以下错误:

./main.go:76: Fizzbuzz的间接无效(类型为func(int) string)

我理解Fizzbuzz函数不满足writeString的要求。我的直觉告诉我,这可能是因为我应该使用一个接口来处理Fizzbuzz函数?有人可以给我一些关于如何执行这个任务的指导吗?我该如何使这段代码符合Go的惯用方式?

// -------------------------------输入--------------------------------------

// 你的程序应该读取一个输入文件(在命令行中提供),
// 文件中包含多个以换行符分隔的行。
// 每行包含3个以空格分隔的数字。
// 第一个数字是要被'A'整除的数字(在这个例子中),
// 第二个数字是要被'B'整除的数字(在这个例子中),
// 第三个数字是计数的上限(在这个例子中)。
// 你可以假设输入文件格式正确,数字都是有效的正整数。例如:

// 3 5 10
// 2 7 15

// -------------------------------输出------------------------------------

// 打印出从1到N的序列,将能被'A'整除的数字替换为F,
// 能被'B'整除的数字替换为B,同时能被两者整除的数字替换为'FB'。
// 由于输入文件包含多组值,你的输出将每组值打印为一行。
// 确保每行打印时没有多余的空格。例如:

// 1 2 F 4 B F 7 8 F B
// 1 F 3 F 5 F B F 9 F 11 F 13 FB 15

// ---------------------------提议的解决方案-----------------------------

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
)

func Fizzbuzz(N int) (output string) {
	var (
		A = N%3 == 0
		B = N%5 == 0
	)

	switch {
	case A && B:
		output = "FB"

	case A:
		output = "F"

	case B:
		output = "B"

	default:
		output = fmt.Sprintf("%v", N)

	}
	return
}

func openFile(name string) *os.File {
	file, err := os.Open(name)
	if err != nil {
		log.Fatalf("打开文件%s失败:%s", name, err)
	}
	return file
}

func Readln(r *bufio.Reader) {
	line, prefix, err := r.ReadLine()
	if err != nil {
		log.Fatalf("读取行失败:%v", err)
	}
	if prefix {
		log.Printf("行太长,只返回前%d个字节", len(line))
	}
}

func WriteString(w *bufio.Writer) {
	if n, err := w.WriteString(*Fizzbuzz); err != nil {
		log.Fatalf("写入字符串失败:%s", err)
	} else {
		log.Printf("写入%d个字节的字符串", n)
	}
}

func main() {
	file := openFile(os.Args[1])
	defer file.Close()

	fi := bufio.NewReader(file)
	Readln(fi)

	fo := bufio.NewWriter(file)
	defer fo.Flush()

	WriteString(fo)
}

Go-Playground

英文:

I'm getting stucked with the following error:

./main.go:76: invalid indirect of Fizzbuzz (type func(int) string)

I understand that the Fizzbuzz function does not satisfy the writeString. My intuition is telling me that this is probably because I should be using an interface to Fizzbuzz? Can someone please give me some direction on how to execute this? What can I do to make this code Go idiomatic?

// -------------------------------INPUT--------------------------------------
// Your program should read an input file (provided on the command line),
// which contains multiple newline separated lines.
// Each line will contain 3 numbers which are space delimited.
// The first number is first number to divide by ('A' in this example),
// the second number is the second number to divide by ('B' in this example)
// and the third number is where you should count till ('N' in this example).
// You may assume that the input file is formatted correctly and the
// numbers are valid positive integers. E.g.
// 3 5 10
// 2 7 15
// -------------------------------OUTPUT------------------------------------
// Print out the series 1 through N replacing numbers divisible by 'A' by F,
// numbers divisible by 'B' by B and numbers divisible by both as 'FB'.
// Since the input file contains multiple sets of values, your output will
// print out one line per set. Ensure that there are no trailing empty spaces
// on each line you print. E.g.
// 1 2 F 4 B F 7 8 F B
// 1 F 3 F 5 F B F 9 F 11 F 13 FB 15
// ---------------------------PROPOSED SOLUTION-----------------------------
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func Fizzbuzz(N int) (output string) {
var (
A = N%3 == 0
B = N%5 == 0
)
switch {
case A && B:
output = "FB"
case A:
output = "F"
case B:
output = "B"
default:
output = fmt.Sprintf("%v", N)
}
return
}
func openFile(name string) *os.File {
file, err := os.Open(name)
if err != nil {
log.Fatalf("failed opening %s for writing: %s", name, err)
}
return file
}
func Readln(r *bufio.Reader) {
line, prefix, err := r.ReadLine()
if err != nil {
log.Fatalf("failed reading a line: %v", err)
}
if prefix {
log.Printf("Line is too big for buffer, only first %d bytes returned", len(line))
}
}
func WriteString(w *bufio.Writer) {
if n, err := w.WriteString(*Fizzbuzz); err != nil {
log.Fatalf("failed writing string: %s", err)
} else {
log.Printf("Wrote string in %d bytes", n)
}
}
func main() {
file := openFile(os.Args[1])
defer file.Close()
fi := bufio.NewReader(file)
Readln(fi)
fo := bufio.NewWriter(file)
defer fo.Flush()
WriteString(fo)
}

Go-Playground

答案1

得分: 9

* 作为一元运算符用于解引用(或称为“间接引用”)指针。Fizzbuzz 是一个函数,不是一个指针。这就是编译器报错的原因:

>Invalid indirect of type func (int) string

你真正想做的是调用这个函数:Fizzbuzz()

所以这一行代码:

if fizzbuzz, err := w.WriteString(*Fizzbuzz); err != nil {

应该改为:

if fizzbuzz, err := w.WriteString(Fizzbuzz()); err != nil{

将 writestring 的第一个返回值命名为 fizzbuzz 并不是很符合惯用法。通常我们会将其命名为 "n"。

if n, err := w.WriteString(Fizzbuzz()); err != nil{
英文:

* as a unary operator is used to dereference (or "indirect") a pointer. Fizzbuzz is a function, not a pointer. That is why the compiler says:

>Invalid indirect of type func (int) string

What you really want to do is call the function: Fizzbuzz()

So line:

if fizzbuzz, err := w.WriteString(*Fizzbuzz); err != nil {

should be:

if fizzbuzz, err := w.WriteString(Fizzbuzz()); err != nil{

It is not very idiomatic to call the first return of writestring something like fizzbuzz. Normally we name it "n".

if n, err := w.WriteString(Fizzbuzz()); err != nil{

huangapple
  • 本文由 发表于 2013年12月16日 12:35:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/20603563.html
匿名

发表评论

匿名网友

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

确定