【问题标题】:How to write several implementation of the same method that have a different signature如何编写具有不同签名的相同方法的多个实现
【发布时间】:2021-07-09 15:42:59
【问题描述】:

我有几个相同方法的实现SetRateForMeasure

package repartition

type Repartition interface {
    Name() string
    Compute(meters []models.Meter, totalsProd, totalsConso map[string]float64) []models.Meter
    SetRateForMeasure(meter models.Meter, measure models.Measure, total float64) float64
}

然后,在我的代码中(在 repartition.go 中),我称之为:

rate := repartition.SetRateForMeasure(meter, measure, total)

repartition 是之前定义的接口。

问题是,当我添加此方法的新实现时,我的函数的参数可能会有所不同。

例如,静态重新分区使用仅在这种情况下使用的静态百分比。

我最终添加了参数,以便我对所有方法都有一个通用接口,但结果是有很多未使用的参数,具体取决于实现。

如果我将它添加到通用接口,它将不会用于其他定义。

我试图从我的接口定义中删除这个方法,但是现在

rate := repartition.SetRateForMeasure()

不再定义。

我应该如何组织我的代码?

【问题讨论】:

    标签: go interface


    【解决方案1】:

    Go 中没有函数重载,所以你不能用不同的参数声明同一个函数。不过有几种方法可以实现:

    • 您可以添加多个具有不同名称和签名的函数
    • 您可以更改函数以接受结构而不是参数
    SetRateForMeasure(args SetRateOptions) float64
    
    type SetRateOptions struct {
     Meter models.Meter
     Measure models.Measure
     Total float64
     Percentage *float64 // If nil, use default percentage
     ... // more parameters as needed
    }
    

    【讨论】:

    • 哦,我明白了,我不会添加多个函数,因为所有这些函数都做同样的事情。我认为它们具有相同的名称是一致的。我将使用 struct param !谢谢!
    【解决方案2】:

    Go 不支持方法覆盖。您可以定义具有不同名称的方法,这些方法采用不同的参数 ​或者你可以声明方法接受一个参数结构。

    type SetRateParams struct {
        Meter    models.Meter
        Measure  models.Measure
        Total    float64
    }
    
    type Repartition interface {
        SetRateForMeasure(params SetRateParams) float64
    }
    

    您可以选择将结构中的参数声明为指针,这样您就可以使用nil 来表示“未提供”语义,而不是使用零值。这可能与 0 可能是有效值的数字参数有关。

    使用结构参数还有一个优点,即您不必更改所有调用站点,以防您决定在 6 个月后添加额外的参数(您只需将其添加到结构中)。

    为了说明什么是可能的,interface{} varargs 也有更糟糕的解决方案,但除非你讨厌类型安全,否则我不建议这样做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      • 2013-07-03
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多