Go中可选参数的等价物

qojgxg4l  于 2023-04-27  发布在  Go
关注(0)|答案(1)|浏览(148)

我正在将一个客户端从python移植到一个API。

def createIntAttribute(attr_name, default_value=None, is_array=False)

它在数据库上创建一个具有或不具有默认值的整数属性,如下所示:

createIntAttribute("numUsers")             # No default attribute
createIntAttribute("numUsers", 0)          # Default attribute of 0

如何在Go中实现这一点?
我考虑的一些方法是:

  • 使用int作为类型

没有办法知道用户是想避免创建默认值还是想创建默认值

  • 使用指针defaultValue *int

每次使用都需要&,并且不支持文字

  • 将结构用于参数

int的默认值是0,所以问题和第一种方法一样

  • 使用具有value和isSet属性的结构来括起可选参数

每种类型的变量都需要一个结构体。这可能会使用泛型,但增加了go版本〉1.18的要求
用法为mypackage.NewOptionalStringArray([]string{"hello", "world"})

  • 使用可变参数函数func createIntAttribute(name string, optionals ...interface{})

默认情况下没有类型检查
自动完成不显示变量的名称和类型;使用单独的参数与vs代码显示参数的名称和类型,因为我键入它们
实现这一点的最佳方式是什么?

yks3o0rb

yks3o0rb1#

一种方法是使用Functional Options Pattern。请参阅下面的演示:

package main

import (
    "log"
)

type options struct {
    hasDefault   bool
    defaultValue int
}

type option func(*options)

func withDefault(value int) option {
    return func(o *options) {
        o.hasDefault = true
        o.defaultValue = value
    }
}

func createIntAttribute(name string, setters ...option) {
    o := &options{}

    for _, setter := range setters {
        setter(o)
    }

    log.Println(name, o)
}

func main() {
    createIntAttribute("test1")
    createIntAttribute("test1", withDefault(10))
}

当实现为方法链时,这种方法可以更用户友好(可能):

package main

import (
    "log"
)

type createIntAttributeParams struct {
    name         string
    hasDefault   bool
    defaultValue int
}

// mandatory parameters here
func createIntAttribute(name string) *createIntAttributeParams {
    return &createIntAttributeParams{
        name: name,
    }
}

// optional parameter
func (p *createIntAttributeParams) withDefault(value int) *createIntAttributeParams {
    p.hasDefault = true
    p.defaultValue = value
    return p
}

// other with* functions to set more optional parameters

// execute
func (p *createIntAttributeParams) do() {
    log.Println(*p)
}

func main() {
    createIntAttribute("test1").do()
    createIntAttribute("test1").withDefault(10).do()
}

相关问题