Golang动态可变函数参数 参数默认值

作者:matrix 发布时间:2024-08-17 分类:Golang

Golang是不支持函数参数默认值的,但是也有很多办法可以解决

动态可变参数

func main() {
    addItem("11", "a1")
    addItem("2", "a2", "222")
}

func addItem(name, value string, opts ...string) {
    fmt.Println("add item-->", name, value)
    for _, opt := range opts {
        fmt.Println("opt:", opt)
    }
}

其中opts ...string 表示可变参数,类型为string,如果需要不同类型传入 看下面

可变参数 + 动态类型

type AlfredItem struct {
    Title    string
    Subtitle string
    Arg      int
}

type AlfredWorkflow struct {
    Items []AlfredItem
}

func (aw *AlfredWorkflow) AddItem(name, value string, opts ...func(*AlfredItem)) {
    item := AlfredItem{
        Title:    value,
        Subtitle: name,
        Arg:      111,
    }
    for _, opt := range opts {
        opt(&item)
    }
    aw.Items = append(aw.Items, item)
}

func main() {
    aw := AlfredWorkflow{}
    aw.AddItem("A", "a")
    aw.AddItem("B", "b", func(ai *AlfredItem) {
        ai.Arg = 22222
    }, func(ai *AlfredItem) {
        ai.Arg = 3333
    })

    fmt.Printf("%+v", aw)
}

高阶用法 封装为选项模式(Option Pattern)

采用Functional Options Patter方法来解决

核心点:定义 type func(*AlfredItem),且每个参数定义with函数

type AlfredItem struct {
    Title    string
    Subtitle string
    Arg      int
}

type AlfredWorkflow struct {
    Items []AlfredItem
}

type Option func(*AlfredItem)

func WithTitle(title string) Option {
    return func(ai *AlfredItem) {
        ai.Title = title
    }
}
func WithSubtitle(subtitle string) Option {
    return func(ai *AlfredItem) {
        ai.Subtitle = subtitle
    }
}

func WithArg(arg int) Option {
    return func(ai *AlfredItem) {
        ai.Arg = arg
    }
}

func (aw *AlfredWorkflow) AddItem(name, value string, opts ...Option) {
    item := AlfredItem{
        Title:    value,
        Subtitle: name,
        Arg:      111,
    }
    for _, opt := range opts {
        opt(&item)
    }
    aw.Items = append(aw.Items, item)
}

func main() {
    aw := AlfredWorkflow{}
    aw.AddItem("DefaultName", "DefaultVlaue")
    aw.AddItem("DefaultName-B", "DefaultVlaue-b", WithArg(222), WithSubtitle("0000"))
    aw.AddItem("C", "c", WithTitle("hahah"))

    fmt.Printf("%+v", aw)
}

参考:

https://www.cnblogs.com/smartrui/p/10324320.html

php函数用数组传递多位参数

作者:matrix 发布时间:2015-05-17 分类:兼容并蓄

我之前不会编写函数,都是用的别人做的。后来慢慢学会就逐步添加想要的功能,但是问题出现了。
我修改的函数(用于curl抓取页面)的相关设置太多,导致函数的形参多的冒泡,使用起来很麻烦

function curl_get($url, $re=0,$ua=0,$ip=1,$post=0,$followLocation=0......){}//像这样
curl_get($url, 0,0,0,$post,0,1,0......)//每次调用的时候很蛋疼

最近难以忍受调用这种形式的函数,遂修改下

function curl_get($url, $array=array('re'=>0,'ua'=>0,'ip'=>1,'post'=>0,followLocation=>0,......)){}

刚开始没发现使用上有问题,但是后来真闯到鬼了,明明默认的形参是ip=1,但是打死都没反应
curl_get($url, $array=array('post'=>0))后来知道是怎么回事:调用函数时的array('post'=>0)参数覆盖了形参$array=array('re'=>0,'ua'=>0,'ip'=>1...),等于是这样的话除了设置的post数组,其他的数组都没有设置(包括形参)。。。好吧,看下面解决办法

解决方案1

function curl_get($url, $array=array())
{
$defaultOptions = array(
're'=>0,
'ua'=>0,
'ip'=>1,
'post'=>0,
'followLocation'=>0,
//......
);
$array = array_merge($defaultOptions, $array);
//do......
}

解决方案2

function curl_get($url,$str='') {
$str_deaful='re=0&ua=0&ip=1&post=0&followLocation=0...';
parse_str($str_deaful,$arr);
parse_str($str,$arr2);
$array = array_merge($arr,$arr2);
//do......
}

参考:http://segmentfault.com/q/1010000000192291