【问题标题】:Golang idiom for passing multiple argument types传递多种参数类型的 Golang 习语
【发布时间】:2021-12-17 07:09:02
【问题描述】:

我是学习 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 惯用的事情是什么?是否只是将随机函数附加到结构并编写接口或其他内容?

感谢您的帮助...

【问题讨论】:

  • 可以键入空界面。 type Thingie interface{}
  • 另外,如果domeSomething() 真的只对t.d 感兴趣,您可以嵌入(查找)一个通用类型到ThingOtherThing 中只有字段d string

标签: go types idioms


【解决方案1】:

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

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"}})
}

DBaseThingOtherThing 提供字段(d)并满足Der 接口。它确实使结构字面量的定义时间更长。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 王牌谢谢。这就是我的假设,但我只是想我会检查是否存在一种仍然是“Go 方式”的不那么死的代码方式
    【解决方案3】:

    您可以使用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.

    【讨论】:

      猜你喜欢
      • 2018-01-22
      • 2020-09-17
      • 1970-01-01
      • 2016-09-13
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      相关资源
      最近更新 更多