英文:
Alternative for function overloading in Go?
问题
在Golang中是否有可能像C#中的函数重载或可选参数一样工作?或者是否有其他替代方法?
英文:
Is it possible to work similar way like the function overloading or optional parameter in C# using Golang? Or maybe an alternative way?
答案1
得分: 13
在Go语言中,对于可选参数的惯用解决方案是使用包装函数:
func do(a, b, c int) {
// ...
}
func doSimply(a, b) {
do(a, b, 42)
}
故意不包含函数重载,因为它会使代码变得难以阅读。
英文:
The idiomatic answer to optional parameters in Go is wrapper functions:
func do(a, b, c int) {
// ...
}
func doSimply(a, b) {
do(a, b, 42)
}
Function overloading was intentionally left out, because it makes code hard(er) to read.
答案2
得分: 10
不支持函数重载和可选参数。您可以通过构建自己的参数结构来解决这个问题。我的意思是像这样(未经测试,可能不起作用...)编辑:现在已经测试过了...
package main
import "fmt"
func main() {
args := NewMyArgs("a", "b") // 默认情况下,文件名为"c"
args.SetFileName("k")
ret := Compresser(args)
fmt.Println(ret)
}
func Compresser(args *MyArgs) string {
return args.dstFilePath + args.srcFilePath + args.fileName
}
// 一个带有参数的结构体
type MyArgs struct {
dstFilePath, srcFilePath, fileName string
}
// 一个“构造函数”函数,为args提供默认值
func NewMyArgs(dstFilePath string, srcFilePath string) *MyArgs {
return &MyArgs{
dstFilePath: dstFilePath,
srcFilePath: srcFilePath,
fileName: "c",
}
}
func (a *MyArgs) SetFileName(value string) {
a.fileName = value
}
英文:
Neither function overloading nor optional arguments are directly supported. You could work around them building your own arguments struct. I mean like this (untested, may not work...) EDIT: now tested...
package main
import "fmt"
func main() {
args:=NewMyArgs("a","b") // filename is by default "c"
args.SetFileName("k")
ret := Compresser(args)
fmt.Println(ret)
}
func Compresser(args *MyArgs) string {
return args.dstFilePath + args.srcFilePath + args.fileName
}
// a struct with your arguments
type MyArgs struct
{
dstFilePath, srcFilePath, fileName string
}
// a "constructor" func that gives default values to args
func NewMyArgs(dstFilePath string, srcFilePath string) *MyArgs {
return &MyArgs{
dstFilePath: dstFilePath,
srcFilePath:srcFilePath,
fileName :"c"}
}
func (a *MyArgs) SetFileName(value string){
a.fileName=value;
}
答案3
得分: 3
有一些提示在这里使用可变参数,例如:
sm1 := Sum(1, 2, 3, 4) // = 1 + 2 + 3 + 4 = 10
sm2 := Sum(1, 2) // = 1 + 2 = 3
sm3 := Sum(7, 1, -2, 0, 18) // = 7 + 1 + -2 + 0 + 18 = 24
sm4 := Sum() // = 0
func Sum(numbers ...int) int {
n := 0
for _,number := range numbers {
n += number
}
return n
}
或者对于任何类型使用...interface{}
:
Ul("apple", 7.2, "BANANA", 5, "cHeRy")
func Ul(things ...interface{}) {
fmt.Println("<ul>")
for _,it := range things {
fmt.Printf(" <li>%v</li>\n", it)
}
fmt.Println("</ul>")
}
英文:
There are some hints here using variadic arguments, for example:
sm1 := Sum(1, 2, 3, 4) // = 1 + 2 + 3 + 4 = 10
sm2 := Sum(1, 2) // = 1 + 2 = 3
sm3 := Sum(7, 1, -2, 0, 18) // = 7 + 1 + -2 + 0 + 18 = 24
sm4 := Sum() // = 0
func Sum(numbers ...int) int {
n := 0
for _,number := range numbers {
n += number
}
return n
}
Or ...interface{}
for any types:
Ul("apple", 7.2, "BANANA", 5, "cHeRy")
func Ul(things ...interface{}) {
fmt.Println("<ul>")
for _,it := range things {
fmt.Printf(" <li>%v</li>\n", it)
}
fmt.Println("</ul>")
}
答案4
得分: 0
package main
import "fmt"
type flavorA struct{}
type flavorB struct{}
var FlavorA = flavorA{}
var FlavorB = flavorB{}
type Something struct {
i int
f float64
}
func (flavor flavorA) NewSomething(i int) *Something {
return &Something{i:i, f:0.0}
}
func (flavor flavorB) NewSomething(f float64) *Something {
return &Something{i:0, f:f}
}
func main() {
fmt.Println(FlavorA.NewSomething(1), FlavorB.NewSomething(2))
}
英文:
An approach I use sometime for constructing an object using New methods having different arguments is to have a "flavor" pseudo type. You can try it on the Go Playground https://play.golang.org/p/5To5AcY-MRe
package main
import "fmt"
type flavorA struct{}
type flavorB struct{}
var FlavorA = flavorA{}
var FlavorB = flavorB{}
type Something struct {
i int
f float64
}
func (flavor flavorA) NewSomething(i int) *Something {
return &Something{i:i, f:0.0}
}
func (flavor flavorB) NewSomething(f float64) *Something {
return &Something{i:0, f:f}
}
func main() {
fmt.Println(FlavorA.NewSomething(1), FlavorB.NewSomething(2))
}
答案5
得分: 0
当你有很多参数时,使用一个新的结构体或定义一个新的MyOptionBuilder类型来构建和存储所有参数,并构造出漂亮的默认值可能是有意义的。
这里有一个简单的例子,其中Go的类型默认值是可以的。
package main
import "fmt"
type FancyFuncOptions struct {
I int64
S string
F float64
//...更多...
}
func FancyFunc(opts *FancyFuncOptions) {
fmt.Println("%v", opts)
}
func main() {
// 简单的方式
options := &FancyFuncOptions{S: "happy"}
FancyFunc(options)
在Go中,如果选项具有复杂的逻辑,你会看到人们使用方法链。
package main
import "fmt"
type FancyFuncOptions struct {
I int64
S string
F float64
//...更多...
}
// 链式风格
func NewFancyFuncOptions() *FancyFuncOptions {
return &FancyFuncOptions{I: 100, S: "empty", F: 0.1}
}
func (o *FancyFuncOptions) SetI(i int64) *FancyFuncOptions {
o.I = i
return o
}
func (o *FancyFuncOptions) SetS(s string) *FancyFuncOptions {
o.S = s
return o
}
func FancyFunc(opts *FancyFuncOptions) {
fmt.Println("%v", opts)
}
func main() {
// 更加复杂
options = NewFancyFuncOptions().SetI(234).SetS("happy")
FancyFunc(options)
(https://go.dev/play/p/Ae_6Y6kZa97)
明白了吗?
英文:
When you have many arguments it may make sense to use a new struct for them or to define a new MyOptionBuilder type to build and store all the arguments and to construct nice defaults.
Here's a simple example where the go defaults for types are okay.
package main
import "fmt"
type FancyFuncOptions struct {
I int64
S string
F float64
//...many more...
}
func FancyFunc(opts *FancyFuncOptions) {
fmt.Println("%v", opts)
}
func main() {
// simple way
options := &FancyFuncOptions{S: "happy"}
FancyFunc(options)
In golang you'll see people using method-chaining for this, if the options have complex logic.
package main
import "fmt"
type FancyFuncOptions struct {
I int64
S string
F float64
//...many more...
}
// chaining style
func NewFancyFuncOptions() *FancyFuncOptions {
return &FancyFuncOptions{I: 100, S: "empty", F: 0.1}
}
func (o *FancyFuncOptions) SetI(i int64) *FancyFuncOptions {
o.I = i
return o
}
func (o *FancyFuncOptions) SetS(s string) *FancyFuncOptions {
o.S = s
return o
}
func FancyFunc(opts *FancyFuncOptions) {
fmt.Println("%v", opts)
}
func main() {
// fancier
options = NewFancyFuncOptions().SetI(234).SetS("happy")
FancyFunc(options)
(https://go.dev/play/p/Ae_6Y6kZa97)
Make sense?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论