Golang函数指针作为结构体的一部分

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

Golang function pointer as a part of a struct

问题

我有以下代码:

type FWriter struct {
    WriteF func(p []byte) (n int, err error)
}

func (self *FWriter) Write(p []byte) (n int, err error) {
    return self.WriteF(p)
}

func MyWriteFunction(p []byte) (n int, err error) {
    // 这个函数实现了Writer接口,但不是命名为"Write"
    fmt.Print("%v", p)
    return len(p), nil
}

MyFWriter := new(FWriter)
MyFWriter.WriteF = MyWriteFunction
// 我想要使用MyWriteFunction和io.Copy
io.Copy(MyFWriter, os.Stdin)

我想要创建一个Writer接口来包装MyWriteFunction,因为它的名称不是"Write",所以无法在需要"Writer"接口的地方使用它。

这段代码无法工作,因为它报错:

方法MyWriterFunction不是一个表达式,必须被调用

我在这里做错了什么?如何将WriteF设置为MyWriteFunction

注意:我尽量简化了这个问题,实际上我有一个结构体,其中包含MyWriteFunction和一个普通的Write函数,所以会变得有点复杂...(如果有更好的解决方法,我会很高兴听到!)

谢谢!!


**编辑:**我注意到了我的拼写错误并进行了修正(MyWriterFunction -> MyWriteFunction)。

我认为我过于简化了问题,以至于让你误解了我的原意。根据匿名评论和peterSO的友好评论,我重新创建了错误以更好地演示我的问题:

package main

import (
    "fmt"
    "io"
    "strings"
)

type ProxyWrite interface {
    Write(p []byte) (n int, err error)
    SpecialWrite(p []byte) (n int, err error)
}

type Implementer struct {
    counter int
}

func (self Implementer) Write(p []byte) (n int, err error) {
    fmt.Print("Normal write: %v", p)
    return len(p), nil
}

func (self Implementer) SpecialWrite(p []byte) (n int, err error) {
    fmt.Print("Normal write: %v\n", p)
    fmt.Println("And something else")
    self.counter += 1
    return len(p), nil
}

type WriteFunc func(p []byte) (n int, err error)

func (wf WriteFunc) Write(p []byte) (n int, err error) {
    return wf(p)
}

func main() {
    Proxies := make(map[int]ProxyWrite, 2)
    Proxies[1] = new(Implementer)
    Proxies[2] = new(Implementer)

    /* 正常运行并使用Write方法 */
    io.Copy(Proxies[1], strings.NewReader("Hello world"))
    /* 报错:./main.go:45: method Proxies[1].SpecialWrite is not an expression, must be called */
    io.Copy(WriteFunc(Proxies[1].SpecialWrite), strings.NewReader("Hello world"))
}

希望这样能更清楚地说明我第一次尝试时的意图。

有什么想法吗?

英文:

I have the following code:

type FWriter struct {
	WriteF func(p []byte) (n int,err error)
}

func (self *FWriter) Write(p []byte) (n int, err error) {
	return self.WriteF(p)
}

func MyWriteFunction(p []byte) (n int, err error) { 
	// this function implements the Writer interface but is not named "Write"
	fmt.Print("%v",p)
	return len(p),nil
}

MyFWriter := new(FWriter)
MyFWriter.WriteF = MyWriteFunction
// I want to use MyWriteFunction with io.Copy
io.Copy(MyFWriter,os.Stdin)

What I am trying to do is to create a Writer interface to wrap MyWriteFunction because it is not named "Write" and I can't use it with anything that requires a "Writer" interface.

This code won't work as it complains:

>method MyWriterFunction is not an expression, must be called

What am I doing wrong here? How can I set WriteF to be MyWriteFunction?

Note: I simplified this problem as much as I can and in reality I have a struct which has MyWriteFunction AND a normal Write function so it gets a little bit complicated... (Also if there is a better way to solve this problem of mine then I'll be glad to hear it!)

Thanks!!


EDIT: I have notice my typo and fixed it (MyWriterFunction --> MyWriteFunction).

I think I over-simplified the question in a manner that mislead you of my original intent. Following the Anonymous comment and peterSO kind comments I have re-created the error to better demonstrate my problem:

package main

import (
    "fmt"
    "io"
    "strings"
)

type ProxyWrite interface {
	Write(p []byte) (n int, err error)
	SpecialWrite(p []byte) (n int, err error)
}

type Implementer struct {
	counter int
}

func (self Implementer) Write(p []byte) (n int, err error) {
	fmt.Print("Normal write: %v", p)
	return len(p),nil
}

func (self Implementer) SpecialWrite(p []byte) (n int, err error) {
	fmt.Print("Normal write: %v\n", p)
	fmt.Println("And something else")
	self.counter += 1
	return len(p),nil
}


type WriteFunc func(p []byte) (n int, err error)

func (wf WriteFunc) Write(p []byte) (n int, err error) {
    return wf(p)
}

func main() {
	Proxies := make(map[int]ProxyWrite,2)
	Proxies[1] = new(Implementer)
	Proxies[2] = new(Implementer)

	/* runs and uses the Write method normally */
	io.Copy(Proxies[1], strings.NewReader("Hello world"))
    /* gets ./main.go:45: method Proxies[1].SpecialWrite is not an expression, must be called */
	io.Copy(WriteFunc(Proxies[1].SpecialWrite), strings.NewReader("Hello world"))
}

I hope it clarifies what I meant to present on the first attempt.

Any thoughts?

答案1

得分: 19

你的代码中有一个拼写错误,但是将函数包装到结构体中是不必要的。相反,你可以定义一个包装函数的 WriteFunc 类型,并在其上定义一个 Write 方法。以下是一个完整的示例代码:

package main

import (
	"fmt"
	"io"
	"strings"
)

type WriteFunc func(p []byte) (n int, err error)

func (wf WriteFunc) Write(p []byte) (n int, err error) {
	return wf(p)
}

func myWrite(p []byte) (n int, err error) {
	fmt.Print("%v", p)
	return len(p), nil
}

func main() {
	io.Copy(WriteFunc(myWrite), strings.NewReader("Hello world"))
}

希望对你有帮助!

英文:

There's a typo in your code, but wrapping the func into a struct is unnecessary anyway. Instead, you can just define a WriteFunc type that wraps a function, and that you can define a Write method on. Here's a full example.

package main

import (
	"fmt"
	"io"
	"strings"
)

type WriteFunc func(p []byte) (n int, err error)

func (wf WriteFunc) Write(p []byte) (n int, err error) {
	return wf(p)
}

func myWrite(p []byte) (n int, err error) {
	fmt.Print("%v", p)
	return len(p), nil
}

func main() {
	io.Copy(WriteFunc(myWrite), strings.NewReader("Hello world"))
}

答案2

得分: 7

修复MyWriterFunction/MyWriteFunction的拼写错误。例如,

package main

import (
    "fmt"
    "io"
    "os"
)

type FWriter struct {
    WriteF func(p []byte) (n int, err error)
}

func (self *FWriter) Write(p []byte) (n int, err error) {
    return self.WriteF(p)
}

func MyWriteFunction(p []byte) (n int, err error) {
    // 此函数实现了Writer接口,但名称不是"Write"
    fmt.Print("%v", p)
    return len(p), nil
}

func main() {
    MyFWriter := new(FWriter)
    MyFWriter.WriteF = MyWriteFunction
    // 我想使用MyWriteFunction与io.Copy一起使用
    io.Copy(MyFWriter, os.Stdin)
}
英文:

Fix MyWriterFunction/MyWriteFunction typo. For example,

package main

import (
	"fmt"
	"io"
	"os"
)

type FWriter struct {
	WriteF func(p []byte) (n int, err error)
}

func (self *FWriter) Write(p []byte) (n int, err error) {
	return self.WriteF(p)
}

func MyWriteFunction(p []byte) (n int, err error) {
	// this function implements the Writer interface but is not named "Write"
	fmt.Print("%v", p)
	return len(p), nil
}

func main() {
	MyFWriter := new(FWriter)
	MyFWriter.WriteF = MyWriteFunction
	// I want to use MyWriteFunction with io.Copy
	io.Copy(MyFWriter, os.Stdin)
}

huangapple
  • 本文由 发表于 2013年12月22日 19:36:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/20728965.html
匿名

发表评论

匿名网友

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

确定