-1

My go test can not be passed. What's wrong? What's the meaning of (Handle method has pointer receiver)

package ipc

import (
    "testing"
)

// import (
//  "encoding/json"
//  "fmt"
// )

type Request struct {
    Method string `json/"method"`
    Params string `json/"params"`
}

type Response struct {
    Code string `json/"code"`
    Body string `json/"body"`
}

type Server interface {
    Name() string
    Handle(method, params string) *Response
}

type IpcServer struct {
    Server
}

func NewIpcServer(server Server) *IpcServer {
    return &IpcServer{server}
}

type EchoServer struct {
}

func (server *EchoServer) Name() string {
    return "EchoServer"
}

func (server *EchoServer) Handle(method, params string) *Response {
    return &Response{"OK", "Echo " + method + " " + params}
}

func TestIpc(t *testing.T) {
    server := EchoServer{}

    ipcServer := NewIpcServer(server)
}

When I run go test ipc_test.go

/ipc_test.go:49: cannot use server (type EchoServer) as type Server in argument to NewIpcServer:
    EchoServer does not implement Server (Handle method has pointer receiver)
FAIL    command-line-arguments [build failed]
Sam
  • 964
  • 3
  • 11
  • 24

2 Answers2

1

1- You may use

server := &EchoServer{}

instead of

server := EchoServer{}

Method sets:

A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing anonymous fields, as described in the section on struct types. Any other type has an empty method set. In a method set, each method must have a unique non-blank method name.

And see: Pointer receiver and Value receiver difference in implementation with Iris framework


2- Or you may use

func (server EchoServer) Name() string {
    return "EchoServer"
}

func (server EchoServer) Handle(method, params string) *Response {
    return &Response{"OK", "Echo " + method + " " + params}
}

with

server := EchoServer{}
Community
  • 1
  • 1
0

NewIpcServer receives an interface which can be satisfied by a value-type or a pointer-type.

Since EchoServer implements the interface functions as pointer-type receiver (e.g func (server *EchoServer) ...) then you must pass a pointer to the NewIpcServer function.

In your TestIpc function change server to be a pointer as such

server := new(EchoServer)

and your test should compile just fine.

Leo Correa
  • 19,131
  • 2
  • 53
  • 71