drsqpko5286 2019-08-13 18:30 采纳率: 0%
浏览 70
已采纳

返回具有数据成员的多态类型

I'm trying to write a function getTargetServer() to return a polymorphic type that has both a data member URL and a method Close(). This would be a generalization of the *Server returned from httptest.NewServer() but I want to alternatively be able to return a custom type for which Close() is a NOP.

type externalTestServer struct {
    URL string
}

func (externalTestServer) Close() {}

func getTargetServer() *externalTestServer {
    if urlbase, ok := optionals["urlbase"].(string); ok {
        return &externalTestServer{URL: urlbase}
    } else {
        testServer := httptest.NewServer(newMyServerHandler())
        // return testServer // ### Error ###
        return &externalTestServer{URL: testServer.URL}
    }
}

func Test_health_check(t *testing.T) {
    testServer := getTargetServer()
    defer testServer.Close()
    response, err := http.Get(testServer.URL + "/health")
    assert.NilError(t, err)
    assert.Assert(t, cmp.Equal(response.StatusCode, http.StatusOK))
}

This works like a charm except that Close() is always a NOP. When I uncomment the indicated ### Error ### line in order to return a closable *Server, I get the following error message:

cannot use testServer (type *httptest.Server) as type *externalTestServer in return argument

I understand the error, but haven't discovered a solution that lets me return a polymorphic type that generalizes *Server


Note: "A Tour of Go" defines an interface type as follows:

An interface type is defined as a set of method signatures.

Therefore, returning a simple interface will not allow for directly-accessible data members.

  • 写回答

3条回答 默认 最新

  • douguyi3903 2019-08-13 19:23
    关注

    You could create a struct that has a field which is a string URL and a field that is a Close func. The Close func can be implemented by either externalTestServer or httptest.Server:

    type server struct {
        URL   string
        Close func()
    }
    
        if urlbase, ok := optionals["urlbase"].(string); ok {
            extServer := &externalTestServer{URL: urlbase}
            return &server{
                URL:   urlbase,
                Close: extServer.Close,
            }
        }
        testServer := httptest.NewServer(newMyServerHandler())
        return &server{
            URL:   testServer.URL,
            Close: testServer.Close,
        }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 luckysheet
  • ¥15 ZABBIX6.0L连接数据库报错,如何解决?(操作系统-centos)
  • ¥15 找一位技术过硬的游戏pj程序员
  • ¥15 matlab生成电测深三层曲线模型代码
  • ¥50 随机森林与房贷信用风险模型
  • ¥50 buildozer打包kivy app失败
  • ¥30 在vs2022里运行python代码
  • ¥15 不同尺寸货物如何寻找合适的包装箱型谱
  • ¥15 求解 yolo算法问题
  • ¥15 虚拟机打包apk出现错误