Home > Backend Development > Golang > Idiomatic way to combine these two functions into one

Idiomatic way to combine these two functions into one

王林
Release: 2024-02-05 22:33:04
forward
742 people have browsed it

Idiomatic way to combine these two functions into one

Question content

I have these two very similar functions. They each parse a specific base/bit length integer from a named query parameter. There are two functions that can handle unsigned/signed integers, you need to call strconv.ParseUint or strconv.ParseInt.

What is a concise and idiomatic way to reduce these to a single function? I feel like using interfaces (and generics?) is the way to go, but I'm not sure how to proceed.

//////////////////////////////////////////////////////////////////////

func ParseQueryParamUnsigned(name string, base int, bits int, values *url.Values) (uint64, error) {

    param := (*values)[name]

    if len(param) < 1 {
        return 0, fmt.Errorf("missing parameter %s", name)
    }

    if len(param) > 1 {
        return 0, fmt.Errorf("duplicate parameter %s", name)
    }

    v, err := strconv.ParseUint(param[0], base, bits)

    if err != nil {
        return 0, fmt.Errorf("bad value for '%s' (%s)", name, err.Error())
    }
    return v, nil
}

//////////////////////////////////////////////////////////////////////

func ParseQueryParamSigned(name string, base int, bits int, values *url.Values) (int64, error) {

    param := (*values)[name]

    if len(param) < 1 {
        return 0, fmt.Errorf("missing parameter %s", name)
    }

    if len(param) > 1 {
        return 0, fmt.Errorf("duplicate parameter %s", name)
    }

    v, err := strconv.ParseInt(param[0], base, bits)

    if err != nil {
        return 0, fmt.Errorf("bad value for '%s' (%s)", name, err.Error())
    }
    return v, nil
}
Copy after login


Correct answer


You can make a universal parser like this:

func ParseQueryParam[T any](name string, values url.Values, parser func(string) (T,error)) (T, error) {

    param := values[name]

    if len(param) < 1 {
        return 0, fmt.Errorf("missing parameter %s", name)
    }

    if len(param) > 1 {
        return 0, fmt.Errorf("duplicate parameter %s", name)
    }

    v, err := parser(param[0])

    if err != nil {
        return 0, fmt.Errorf("bad value for '%s' (%s)", name, err.Error())
    }
    return v, nil
}
Copy after login

and use it as:

value, err:=ParseQueryParam[int64]("param",values, func(s string) (int64,error) {
  return strconv.ParseInt(s,10,64)
})
Copy after login

The above is the detailed content of Idiomatic way to combine these two functions into one. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template