GOLANG使用嵌入結構實現介面

winlin發表於2017-05-19

考慮一個Packet介面,一般會返回一個Header,例如:

type PacketHeader struct {
    ID uint32
    Timestamp uint64
}

type Packet interface {
    encoding.BinaryMarshaler
    encoding.BinaryUnmarshaler
    Header() *PacketHeader
}

如果是OO的語言,一般會有一個基類,裡面包含了Header和實現這個Header:

class BasePacket : public Packet {
protected: 
    PacketHeader h;
public: 
    virtual Header() *PacketHeader;
};

class HandshakePacket : public BasePacket {
};

在子類中就都實現了這個Header()方法了,在GOLANG同樣可以做到,通過在Header中定義方法,在Packet中包含Header就可以。

func (v *PacketHeader) Header() *PakcetHeader {
    return v
}

type HandshakePacket struct {
    PacketHeader
}

看起來還差不多的,都可以實現,golang只是程式碼少一點,清晰一點點而已。考慮要新增一些輔助函式,譬如給Packet新增是否是緊急型別的包,那OO語言得做一次代理:

type Packet interface {
    IsErgency() bool
}

class BasePacketHeader {
public:
    bool IsErgency() {
        return realtime < 3;
    }
}

class BasePacket {
public:
    bool IsErgency() {
        return h.IsErgency();
    }
}

而在GOLANG中,只需要在Header實現就好了:

func (v *PacketHeader) IsErgency() bool {
    return v.realtime < 3
}

更高階的可以直接嵌入介面。譬如context.Context的實現,cancelCtx直接嵌入了一個介面:

type cancelCtx struct {
    Context

通過指定型別,或者初始化的順序初始化struct

func newCancelCtx(parent Context) cancelCtx {
    return cancelCtx{
        Context: parent,
        done:    make(chan struct{}),
    }
}

結構巢狀的方式,讓組合實現起來非常便捷,避免頻繁的代理。

相關文章