Как написать что-то эквивалентное анонимному классу в Java? - PullRequest
0 голосов
/ 15 сентября 2018

Это более общий вопрос Go, связанный с интерфейсами / функциями / замыканиями / типами / ..., но с конкретным вариантом использования при выполнении операций ввода-вывода.

Учитывая переменную io.Reader, я хочу создать io.ReadCloser с пользовательской реализацией Close().

var file os.File
file = ... // some File which needs to be closed

var reader io.Reader
reader = ... // get Reader from somewhere

var readCloser io.ReadCloser
readCloser = ... // how to create a ReadCloser here?

На Java я бы написал что-то вроде:

readCloser = new io.ReadCloser() {
    Read(p []byte) {
        reader.Read(p);
    }

    Close() {
        // my custom close implementation
        file.Close()
    }    
}

// now pass readCloser around as needed

Как это сделать с Go?

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

принимая подсказку от http.HandlerFunc, я мог бы подумать о следующем

package main

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

// ReadData reads data from an io.Reader
func ReadData(r io.Reader) {
    buf := new(bytes.Buffer)
    buf.ReadFrom(r)
    s := buf.String()
    fmt.Printf("read : %s \n", s)
}

// ReaderFunc takes a function and returns io.Reader
type ReaderFunc func([]byte) (int, error)

func (r ReaderFunc) Read(b []byte) (int, error) {
    return r(b)
}

func main() {
    // invoking ReadData with a regular io.Reader
    r := strings.NewReader("data 123")
    ReadData(r)

    // invoking ReadData with an anonymous io.Reader
    r = strings.NewReader("data 456")
    ReadData(ReaderFunc(func(b []byte) (int, error) {
        return r.Read(b)
    }))
}
0 голосов
/ 15 сентября 2018

Одним из способов может быть создание собственного типа, который сочетает io.Reader и io.Closer и реализует интерфейс io.ReadCloser.Примерно так:

type ReadCloseCombiner struct {
    io.Reader
    io.Closer
}

func (rcc ReadCloseCombiner) Read(p []byte) (n int, err error) {
    return rcc.Reader.Read(p)
}

func (rcc ReadCloseCombiner) Close() error {
    return rcc.Closer.Close()
}

И использовать это так:

var file *os.File
file = ... // some File which needs to be closed

var reader io.Reader
reader = ... // get Reader from somewhere

var readCloser io.ReadCloser
readCloser = ReadCloseCombiner{reader, file}

// now pass readCloser around as needed
readCloser.Read(...)
readCloser.Close()

Если вы хотите что-то более гибкое, я бы предпочел иметь тип, который вместо этого принимает функцию чтения и закрытия, а затемВы можете передать ему анонимные функции (или даже reader.Read / file.Close в вашем случае).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...