web-dev-qa-db-fra.com

Pointeur de fonction de Golang en tant que partie d'une structure

J'ai le code suivant:

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)

Ce que j'essaie de faire, c'est de créer une interface Writer pour envelopper MyWriteFunction car elle n'est pas nommée "Write" et je ne peux pas l'utiliser avec tout ce qui nécessite une interface "Writer".

Ce code ne fonctionnera pas car il se plaint:

la méthode MyWriterFunction n'est pas une expression, doit être appelée

Qu'est-ce que je fais mal ici? Comment puis-je définir WriteF sur MyWriteFunction?

Remarque: J'ai simplifié ce problème autant que possible et en réalité j'ai une structure qui a MyWriteFunction ET une fonction d'écriture normale donc ça devient un peu compliqué ... (Aussi s'il y a une meilleure façon de résoudre mon problème alors je serai heureux de l'entendre!)

Merci!!


EDIT: J'ai remarqué ma faute de frappe et l'ai corrigé (MyWriterFunction -> MyWriteFunction).

Je pense que j'ai trop simplifié la question d'une manière qui vous induit en erreur dans mon intention initiale. Après le commentaire anonyme et les commentaires aimables de peterSO, j'ai recréé l'erreur pour mieux démontrer mon problème:

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"))
}

J'espère que cela clarifie ce que je voulais présenter lors de la première tentative.

Des pensées?

17
user340495

Il y a une faute de frappe dans votre code, mais encapsuler la fonction dans une structure n'est de toute façon pas nécessaire. Au lieu de cela, vous pouvez simplement définir un type WriteFunc qui encapsule une fonction et sur lequel vous pouvez définir une méthode Write. Voici un exemple complet.

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"))
}
19
Paul Hankin

Correction de la faute de frappe MyWriterFunction/MyWriteFunction. Par exemple,

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)
}
6
peterSO