Посмотрел предлагаемую здесь на форуме статейку насчёт дженериков для новой версии Go (по второй ссылке -- подробнее):
https://go.googlesource.com/proposal/+/master/design/go2draft-generics-overview.md
https://go.googlesource.com/proposal/+/master/design/go2draft-contracts.md

Удивило предлагаемое решение для variadic-параметризации (о чём выше отмечено здесь в теме). Как-то уж несерьёзно, что ли, сегодня действовать "в лоб" по-классически, создавая тупые заготовки-типы в стиле "тип1 для оного параметра, тип2 для двух и т.д.":
https://go.googlesource.com/proposal/+/ ... md#metrics
## Код:
```
package metrics

import "sync"

contract comparable(v T)  {
    v == v
}

contract cmp1(T) {
    comparable(T) // contract embedding
}

type Metric1(type T cmp1) struct {
    mu sync.Mutex
    m  map[T]int
}

func (m *Metric1(T)) Add(v T) {
    m.mu.Lock()
    defer m.mu.Unlock()
    if m.m == nil {
        m.m = make(map[T]int)
    }
    m[v]++
}

contract cmp2(T1, T2) {
    comparable(T1)
    comparable(T2)
}

type key2(type T1, T2 cmp2) struct {
    f1 T1
    f2 T2
}

type Metric2(type T1, T2 cmp2) struct {
    mu sync.Mutex
    m  map[key2(T1, T2)]int
}

func (m *Metric2(T1, T2)) Add(v1 T1, v2 T2) {
    m.mu.Lock()
    defer m.mu.Unlock()
    if m.m == nil {
        m.m = make(map[key2(T1, T2)]int)
    }
    m[key(T1, T2){v1, v2}]++
}

contract cmp3(T1, T2, T3) {
    comparable(T1)
    comparable(T2)
    comparable(T3)
}

type key3(type T1, T2, T3 cmp3) struct {
    f1 T1
    f2 T2
    f3 T3
}

type Metric3(type T1, T2, T3 cmp3) struct {
    mu sync.Mutex
    m  map[key3(T1, T2, T3)]int
}

func (m *Metric3(T1, T2, T3)) Add(v1 T1, v2 T2, v3 T3) {
    m.mu.Lock()
    defer m.mu.Unlock()
    if m.m == nil {
        m.m = make(map[key3]int)
    }
    m[key(T1, T2, T3){v1, v2, v3}]++
}

// Repeat for the maximum number of permitted arguments.

[...]

// Using this package looks like this:

import "metrics"

var m = metrics.Metric2(string, int){}

func F(s string, i int) {
    m.Add(s, i) // this call is type checked at compile time
}
```
