You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言灯光控制函数中闪烁模式可选参数的最优实现方案

灯光控制函数的可选参数实现方案

原实现代码

func (p *Printer) Light(light _light.Light, mode _light.Mode) error {
    // This light_mode is currently believed to be deprecated, leaving here commented in case it ends up being useful later.
    //command, err := mqtt.NewCommand(mqtt.System).AddCommandField("light_mode").AddParamField("on").JSON()
    //if err != nil {
    //  return err
    //}

    // https://github.com/Doridian/OpenBambuAPI/blob/main/mqtt.md#systemledctrl
    command := mqtt.NewCommand(mqtt.System).AddCommandField("ledctrl").AddField("led_node", light).AddField("led_mode", mode)
    // Add fields only used for mode "flashing" but required nonetheless
    command.AddField("led_on_time", 500)
    command.AddField("led_off_time", 500)
    command.AddField("loop_times", 1)
    command.AddField("interval_time", 1000)

    if err := p.mqttClient.Publish(command); err != nil {
        return fmt.Errorf("error setting light %s: %w", light, err)
    }

    return nil
}

需求描述

当输入模式为闪烁(flashing)时,希望允许调用者传入仅针对闪烁灯光所需的间隔时间、点亮时间、熄灭时间等参数。曾考虑使用可变参数,但担忧参数顺序带来的歧义,寻求最优实现方式。

最优实现方案:配置结构体+默认值填充

这种方式既解决参数歧义问题,又能灵活支持可选参数,完全符合Go语言的惯用写法。

1. 定义闪烁配置结构体并设置默认值

// LightFlashConfig 闪烁灯光的配置参数
type LightFlashConfig struct {
    OnTime     int // 点亮时长(毫秒)
    OffTime    int // 熄灭时长(毫秒)
    LoopTimes  int // 循环次数
    Interval   int // 间隔时长(毫秒)
}

// DefaultLightFlashConfig 返回默认的闪烁配置
func DefaultLightFlashConfig() LightFlashConfig {
    return LightFlashConfig{
        OnTime:    500,
        OffTime:   500,
        LoopTimes: 1,
        Interval:  1000,
    }
}

2. 修改原函数支持可选配置

func (p *Printer) Light(light _light.Light, mode _light.Mode, flashConfig ...*LightFlashConfig) error {
    // 初始化配置为默认值
    config := DefaultLightFlashConfig()
    
    // 如果调用者传入了配置,覆盖对应字段
    if len(flashConfig) > 0 && flashConfig[0] != nil {
        cfg := flashConfig[0]
        if cfg.OnTime != 0 {
            config.OnTime = cfg.OnTime
        }
        if cfg.OffTime != 0 {
            config.OffTime = cfg.OffTime
        }
        if cfg.LoopTimes != 0 {
            config.LoopTimes = cfg.LoopTimes
        }
        if cfg.Interval != 0 {
            config.Interval = cfg.Interval
        }
    }

    command := mqtt.NewCommand(mqtt.System).AddCommandField("ledctrl").AddField("led_node", light).AddField("led_mode", mode)
    // 使用配置值填充命令字段
    command.AddField("led_on_time", config.OnTime)
    command.AddField("led_off_time", config.OffTime)
    command.AddField("loop_times", config.LoopTimes)
    command.AddField("interval_time", config.Interval)

    if err := p.mqttClient.Publish(command); err != nil {
        return fmt.Errorf("error setting light %s: %w", light, err)
    }

    return nil
}

3. 调用示例

  • 使用默认闪烁参数(兼容原调用方式):
err := printer.Light(_light.FrontLight, _light.Flashing)
  • 自定义部分闪烁参数:
err := printer.Light(_light.FrontLight, _light.Flashing, &LightFlashConfig{
    OnTime:  300,
    OffTime: 700,
})
  • 自定义所有闪烁参数:
err := printer.Light(_light.FrontLight, _light.Flashing, &LightFlashConfig{
    OnTime:    200,
    OffTime:   800,
    LoopTimes: 3,
    Interval:  1500,
})

方案优势

  • 无歧义:每个参数都有明确字段名,调用者无需记忆参数顺序
  • 灵活性强:支持只修改需要调整的参数,无需传递所有可选值
  • 兼容性好:原函数调用方式完全保留,无需修改旧代码
  • 符合Go风格:这种配置结构体+默认值的模式在Go生态中广泛应用,可读性和可维护性高

注:如果需要更复杂的参数校验或动态配置,也可以考虑函数选项模式,但对于当前场景,配置结构体已经足够简洁高效,无需过度设计。

内容的提问来源于stack exchange,提问作者Torben Conto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:17:12