2

I'm a complete Go newbie, so sorry for the question in advance.

I'm trying to work with a so-defined interface to connect to a message broker:

// Broker is an interface used for asynchronous messaging.
type Broker interface {
    Options() Options
    Address() string
    Connect() error
    Disconnect() error
    Init(...Option) error
    Publish(string, *Message, ...PublishOption) error
    Subscribe(string, Handler, ...SubscribeOption) (Subscriber, error)
    String() string
}

// Handler is used to process messages via a subscription of a topic.
// The handler is passed a publication interface which contains the
// message and optional Ack method to acknowledge receipt of the message.
type Handler func(Publication) error

// Publication is given to a subscription handler for processing
type Publication interface {
    Topic() string
    Message() *Message
    Ack() error
}

I'm trying to use the Subscribe-function to subscribe to a channel and thats the point where I'm struggeling right now. My current approach is the following one:

natsBroker.Subscribe(
        "QueueName",
        func(p broker.Publication) {
            fmt.Printf(p.Message)
        },
    )

The error output is cannot use func literal (type func(broker.Publication)) as type broker.Handler in argument to natsBroker.Subscribe.
But how do I ensure that the function type actually is a broker.Handler?

Thx for your time in advance!

Update

In case anybody is interested, the error return type was missing which caused the error, so it should look similar to that:

natsBroker.Subscribe( "QueueName", broker.Handler(func(p broker.Publication) error { fmt.Printf(p.Topic()) return nil }), )

patreu22
  • 2,988
  • 4
  • 22
  • 31

2 Answers2

4

As the error indicates, the parameter and what you're passing don't match:

type Handler func(Publication) error

             func(p broker.Publication)

You have no return value. If you add a return value (even if you always return nil), it will work fine.

Adrian
  • 42,911
  • 6
  • 107
  • 99
  • Thanks Adrian, as you can see I already updated my question, because that was the critical point :) – patreu22 Nov 14 '18 at 19:49
1

If your signature of your anonymous function matched that of the handler type declaration (Adrian correctly points out you're missing the error return), you should be able to just do a type conversion:

package main

import "fmt"

type Handler func(int) error

var a Handler

func main() {
    a = Handler(func(i int) error {
        return nil
    })

    fmt.Println(isHandler(a))
}

func isHandler(h Handler) bool {
    return true
}

Since the the compiler knows at compiler-time that the types match, there's no need to do additional checking, like you might in the case of, say, a type assertion.

kpcraig
  • 54
  • 1
  • 5
  • Thanks Keith, I was able to make it work :) I updated my answer for anyone interested in the concrete use-case – patreu22 Nov 14 '18 at 19:46
  • 1
    "the signature of your anonymous function matches that of the handler type declaration" No it doesn't. The anonymous function has no return, the parameter takes a function that returns `error`. – Adrian Nov 14 '18 at 19:47
  • Oh you're right @Adrian, I missed that. I have updated the answer, thanks. – kpcraig Nov 14 '18 at 20:44
  • A compilable answer +1 –  Sep 11 '20 at 07:43