函數的不定參數你會用嗎?

若是一個方法中須要傳遞多個參數且某些參數又是非必傳,應該如何處理?學習

案例

// NewFriend 尋找志同道合朋友
func NewFriend(sex int, age int, hobby string) (string, error) {
    
    // 邏輯處理 ...

    return "", nil
}

NewFriend(),方法中參數 sexage 爲非必傳參數,這時方法如何怎麼寫?code

傳參使用不定參數!rpc

想想怎麼去實現它?get

看一下這樣寫能夠嗎?string

// Sex 性別
type Sex int

// Age 年齡
type Age int

// NewFriend 尋找志同道合的朋友
func NewFriend(hobby string, args ...interface{}) (string, error) {
    for _, arg := range args {
        switch arg.(type) {
        case Sex:
            fmt.Println(arg, "is sex")
        case Age:
            fmt.Println(arg, "is age")
        default:
            fmt.Println("未知的類型")
        }
    }
    return "", nil
}

有沒有更好的方案呢?it

傳遞結構體... 恩,這也是一個辦法。io

我們看看別人的開源代碼怎麼寫的呢,我學習的是 grpc.Dial(target string, opts …DialOption) 方法,它都是經過 WithXX 方法進行傳遞的參數,例如:配置

conn, err := grpc.Dial("127.0.0.1:8000",
    grpc.WithChainStreamInterceptor(),
    grpc.WithInsecure(),
    grpc.WithBlock(),
    grpc.WithDisableRetry(),
)

比着葫蘆畫瓢,我實現的是這樣的,你們能夠看看:grpc

// Option custom setup config
type Option func(*option)

// option 參數配置項
type option struct {
    sex int
    age int
}

// NewFriend 尋找志同道合的朋友
func NewFriend(hobby string, opts ...Option) (string, error) {
    opt := new(option)
    for _, f := range opts {
        f(opt)
    }

    fmt.Println(opt.sex, "is sex")
    fmt.Println(opt.age, "is age")

    return "", nil
}

// WithSex sex 1=female 2=male
func WithSex(sex int) Option {
    return func(opt *option) {
        opt.sex = sex
    }
}

// WithAge age
func WithAge(age int) Option {
    return func(opt *option) {
        opt.age = age
    }
}

使用的時候這樣調用:方法

friends, err := friend.NewFriend(
    "看書",
    friend.WithAge(30),
    friend.WithSex(1),
)

if err != nil {
    fmt.Println(friends)
}

這樣寫若是新增其餘參數,是否是也很好配置呀。

以上。

對以上有疑問,快來個人星球交流吧 ~ https://t.zsxq.com/iIUVVnA