用于传递多个参数类型的 Golang 习语

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 惯用的做法是什么?是否只是将一个随机函数附加到结构上并编写一个接口或其他东西?

感谢您的帮助...

为这两种类型声明一个具有通用功能的接口。使用接口类型作为参数类型。

// 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
}

您可以将两个结构从一个基本结构组合起来,从而为它们提供一些共享功能:

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 提供字段 (d) 并以相同的方式满足 Der 接口 ThingOtherThing。它确实使结构文字的定义时间更长一些。

您可以使用 interface{} 参数和 reflect 包来访问公共字段。很多人会说这种做法不地道。

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

Try an example on the playground.