Golang传递多个参数类型的惯用法

huangapple go评论87阅读模式
英文:

Golang idiom for passing multiple argument types

问题

我是你的中文翻译助手,以下是你要翻译的内容:

我刚开始学习Go,并且有一个关于定义一个参数可以是两种类型的问题。
看一下这段代码:

type Thing struct {
  a int
  b int
  c string
  d string
}

type OtherThing struct {
  e int
  f int
  c string
  d string
}

func doSomething(t Thing/OtherThing) error {
  fmt.println(t.d)
  return nil
}

由于这些结构体没有函数,我目前无法为它们编写接口。
那么在Go中,应该怎么做呢?是将一个随机函数添加到结构体中并编写一个接口,还是其他方法?

谢谢帮助...

英文:

I am new to learning Go and have a question around defining an argument that could be one of two types.
Take the code:

type Thing struct {
  a int
  b int
  c string
  d string
}

type OtherThing struct {
  e int
  f int
  c string
  d string
}

func doSomething(t Thing/OtherThing) error {
  fmt.println(t.d)
  return nil
}

As the structs have no functions I cannot write an interface for them at present.
So what is the Go idiomatic thing to do here? Is it just to bolt on a random function to the structs and write an interface or something else?

Thanks for the help...

答案1

得分: 1

声明一个接口,用于定义这两种类型的共同功能。将接口类型作为参数类型。

// Der 获取d的值。
type Der interface {
D() string
}

type Thing struct {
a int
b int
c string
d string
}

func (t Thing) D() string { return t.d }

type OtherThing struct {
e int
f int
c string
d string
}

func (t OtherThing) D() string { return t.d }

func doSomething(t Der) error {
fmt.Println(t.D())
return nil
}

英文:

Declare a interface with the common functionality for the two types. Use the interface type as the argument type.

// Der gets d values.
type Der interface {
  D() string
}

type Thing struct {
  a int
  b int
  c string
  d string
}

func (t Thing) D() string { return t.d }

type OtherThing struct {
  e int
  f int
  c string
  d string
}

func (t OtherThing) D() string { return t.d }


func doSomething(t Der) error {
  fmt.Println(t.D())
  return nil
}

答案2

得分: 1

你可以通过将两个结构体都组合自一个基本结构体来为它们提供共享的功能:

package main

import (
	"fmt"
)

// Der 获取 d 的值。
type Der interface {
	D() string
}

type DBase struct {
	d string
}

func (t DBase) D() string { return t.d }

type Thing struct {
	DBase
	a int
	b int
	c string
}

type OtherThing struct {
	DBase
	e int
	f int
	c string
}

func doSomething(t Der) error {
	fmt.Println(t.D())
	return nil
}

func main() {
    doSomething(Thing{DBase: DBase{"hello"}})
    doSomething(OtherThing{DBase: DBase{"world"}})
}

DBase 提供了字段 d,并且以相同的方式满足了 Der 接口,对于 ThingOtherThing 都是如此。这确实使得结构体字面量的定义变得稍长。

英文:

You can give two structs some shared functionality by composing them both from a base struct:

package main

import (
	"fmt"
)

// Der gets d values.
type Der interface {
	D() string
}

type DBase struct {
	d string
}

func (t DBase) D() string { return t.d }

type Thing struct {
	DBase
	a int
	b int
	c string
}

type OtherThing struct {
	DBase
	e int
	f int
	c string
}

func doSomething(t Der) error {
	fmt.Println(t.D())
	return nil
}

func main() {
    doSomething(Thing{DBase: DBase{"hello"}})
    doSomething(OtherThing{DBase: DBase{"world"}})
}

DBase provides the field (d) and satisfies the Der interface the same way for both Thing and OtherThing. It does make the struct literal a little longer to define.

答案3

得分: 0

你可以使用interface{}参数和reflect包来访问公共字段。很多人会说这种方法不符合惯用方式。

func doSomething(t interface{}) error {
    d := reflect.ValueOf(t).FieldByName("d").String()
    fmt.Println(d)
    return nil
}

在 playground 上尝试一个示例

英文:

You can use an interface{} argument and the reflect package to access the common field. Many people will say that this approach is not idiomatic.

func doSomething(t interface{}) error {
	d := reflect.ValueOf(t).FieldByName("d").String()
	fmt.Println(d)
	return nil
}

Try an example on the playground.

huangapple
  • 本文由 发表于 2021年11月3日 03:11:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/69815791.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定