showliuzp 2025-10-21 16:12 采纳率: 84.3%
浏览 7
已结题

golang封包函数参数较多的优化


func pack_msg(streamer_id,send_userid,rece_userid int64, streamer_name,send_username,rece_username,msg_content string,send_time int64, act int,client_id *string) []byte {
    msg := iapi.ChatMsg{
        StreamerId      : streamer_id,
        StreamerName    : streamer_name,
        SendUserId      : send_userid,
        SendUserName    : send_username,
        ReceUserId      : rece_userid,
        ReceUserName    : rece_username,
        MsgContent      : msg_content,
        SendTime        : send_time,
        ClientId        : *client_id,
        Act             : act,
    }

    bytes, _ := json.Marshal(msg)

    return bytes
}


我在做一个websocket,封包函数pack_msg传入的参数特别多,有优化空间么
  • 写回答

3条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-10-21 16:26
    关注

    让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。

    如果答案让您满意,请采纳、点赞、关注,非常感谢!
    .
    每日一句正能量,让它带给您好心情:把生活过得热气腾腾,就是最好的状态。
    .

    在 Go 语言中,当函数参数过多时,确实有几种优化方式可以让代码更清晰、更易维护。以下是几种常见的优化方案:

    1. 使用结构体封装参数

    这是最直接和推荐的优化方式:

    type PackMsgParams struct {
        StreamerID     int64
        StreamerName   string
        SendUserID     int64
        SendUserName   string
        ReceUserID     int64
        ReceUserName   string
        MsgContent     string
        SendTime       int64
        Act            int
        ClientID       string
    }
    
    
    func packMsg(params PackMsgParams) []byte {
        msg := iapi.ChatMsg{
            StreamerId:   params.StreamerID,
            StreamerName: params.StreamerName,
            SendUserId:   params.SendUserID,
            SendUserName: params.SendUserName,
            ReceUserId:   params.ReceUserID,
            ReceUserName: params.ReceUserName,
            MsgContent:   params.MsgContent,
            SendTime:     params.SendTime,
            ClientId:     params.ClientID,
            Act:          params.Act,
        }
    
    
        bytes, _ := json.Marshal(msg)
        return bytes
    }
    
    
    // 使用方式
    params := PackMsgParams{
        StreamerID:   123,
        StreamerName: "主播名称",
        SendUserID:   456,
        SendUserName: "发送者",
        ReceUserID:   789,
        ReceUserName: "接收者",
        MsgContent:   "消息内容",
        SendTime:     time.Now().Unix(),
        Act:          1,
        ClientID:     "client123",
    }
    packMsg(params)
    

    2. 使用函数选项模式(Functional Options)

    这种方式在需要可选参数时特别有用:

    type PackMsgOption func(*PackMsgParams)
    
    
    func WithStreamerInfo(id int64, name string) PackMsgOption {
        return func(p *PackMsgParams) {
            p.StreamerID = id
            p.StreamerName = name
        }
    }
    
    
    func WithSenderInfo(id int64, name string) PackMsgOption {
        return func(p *PackMsgParams) {
            p.SendUserID = id
            p.SendUserName = name
        }
    }
    
    
    func WithReceiverInfo(id int64, name string) PackMsgOption {
        return func(p *PackMsgParams) {
            p.ReceUserID = id
            p.ReceUserName = name
        }
    }
    
    
    func WithMessage(content string, sendTime int64) PackMsgOption {
        return func(p *PackMsgParams) {
            p.MsgContent = content
            p.SendTime = sendTime
        }
    }
    
    
    func WithAction(act int, clientID string) PackMsgOption {
        return func(p *PackMsgParams) {
            p.Act = act
            p.ClientID = clientID
        }
    }
    
    
    func packMsg(opts ...PackMsgOption) []byte {
        params := &PackMsgParams{}
        for _, opt := range opts {
            opt(params)
        }
        
        msg := iapi.ChatMsg{
            StreamerId:   params.StreamerID,
            StreamerName: params.StreamerName,
            SendUserId:   params.SendUserID,
            SendUserName: params.SendUserName,
            ReceUserId:   params.ReceUserID,
            ReceUserName: params.ReceUserName,
            MsgContent:   params.MsgContent,
            SendTime:     params.SendTime,
            ClientId:     params.ClientID,
            Act:          params.Act,
        }
    
    
        bytes, _ := json.Marshal(msg)
        return bytes
    }
    
    
    // 使用方式
    packMsg(
        WithStreamerInfo(123, "主播名称"),
        WithSenderInfo(456, "发送者"),
        WithReceiverInfo(789, "接收者"),
        WithMessage("消息内容", time.Now().Unix()),
        WithAction(1, "client123"),
    )
    

    3. 直接使用 iapi.ChatMsg 结构体

    如果 iapi.ChatMsg 结构体可以直接使用,最简单的方案是:

    func packMsg(msg iapi.ChatMsg) []byte {
        bytes, _ := json.Marshal(msg)
        return bytes
    }
    
    
    // 使用方式
    msg := iapi.ChatMsg{
        StreamerId:   123,
        StreamerName: "主播名称",
        SendUserId:   456,
        SendUserName: "发送者",
        ReceUserId:   789,
        ReceUserName: "接收者",
        MsgContent:   "消息内容",
        SendTime:     time.Now().Unix(),
        ClientId:     "client123",
        Act:          1,
    }
    packMsg(msg)
    

    4. Builder 模式

    对于复杂的构建过程,可以使用 Builder 模式:

    type MsgBuilder struct {
        msg iapi.ChatMsg
    }
    
    
    func NewMsgBuilder() *MsgBuilder {
        return &MsgBuilder{}
    }
    
    
    func (b *MsgBuilder) SetStreamer(id int64, name string) *MsgBuilder {
        b.msg.StreamerId = id
        b.msg.StreamerName = name
        return b
    }
    
    
    func (b *MsgBuilder) SetSender(id int64, name string) *MsgBuilder {
        b.msg.SendUserId = id
        b.msg.SendUserName = name
        return b
    }
    
    
    func (b *MsgBuilder) SetReceiver(id int64, name string) *MsgBuilder {
        b.msg.ReceUserId = id
        b.msg.ReceUserName = name
        return b
    }
    
    
    func (b *MsgBuilder) SetMessage(content string, sendTime int64) *MsgBuilder {
        b.msg.MsgContent = content
        b.msg.SendTime = sendTime
        return b
    }
    
    
    func (b *MsgBuilder) SetAction(act int, clientID string) *MsgBuilder {
        b.msg.Act = act
        b.msg.ClientId = clientID
        return b
    }
    
    
    func (b *MsgBuilder) Build() []byte {
        bytes, _ := json.Marshal(b.msg)
        return bytes
    }
    
    
    // 使用方式
    msgBytes := NewMsgBuilder().
        SetStreamer(123, "主播名称").
        SetSender(456, "发送者").
        SetReceiver(789, "接收者").
        SetMessage("消息内容", time.Now().Unix()).
        SetAction(1, "client123").
        Build()
    

    建议

    1. 推荐方案1:如果参数都是必需的,使用结构体封装是最简单直接的方式
    2. 推荐方案2:如果有很多可选参数,函数选项模式更灵活
    3. 推荐方案3:如果可以直接使用 iapi.ChatMsg,这是最简洁的方案

    另外,建议处理 json.Marshal 的错误,而不是忽略它:

    bytes, err := json.Marshal(msg)
    if err != nil {
        // 处理错误
        return nil
    }
    return bytes
    

    选择哪种方案主要取决于你的具体使用场景和团队编码规范。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 10月29日
  • 已采纳回答 10月21日
  • 创建了问题 10月21日