【问题标题】:Get Struct name without fetching package name or pointer在不获取包名称或指针的情况下获取结构名称
【发布时间】:2019-10-31 02:07:38
【问题描述】:

我有一个非常简单的代码:

package chain_of_responsibility

import (
    "fmt"
    "reflect"
)

type CustomerBalanceRequest struct{
    CustomerName string
    Balance int
}

type BalanceRequest interface {
    Handle(request CustomerBalanceRequest)
}

type HeadEditor struct{
    Next BalanceRequest
}

func (h *HeadEditor) Handle(b CustomerBalanceRequest){
    if b.Balance < 1000 {
        fmt.Printf("%T approved balance for %v request. Balance: %v\n", h, b.CustomerName, b.Balance)
        fmt.Printf("%v approved balance for %v request. Balance: %v\n", reflect.TypeOf(h), b.CustomerName, b.Balance)
        fmt.Printf("%v approved balance for %v request. Balance: %v\n", reflect.TypeOf(h).String(), b.CustomerName, b.Balance)
        fmt.Printf("%v approved balance for %v request. Balance: %v\n", reflect.TypeOf(h).Name(), b.CustomerName, b.Balance)

    } else{
        h.Next.Handle(b)
    }
}

在 fmt.Printf 行上,我想打印 HeadEditor 类型的名称。我使用各种方法来获得它,这就是我的结果:

*chain_of_responsibility.HeadEditor approved balance for John request. Balance: 500
*chain_of_responsibility.HeadEditor approved balance for John request. Balance: 500
*chain_of_responsibility.HeadEditor approved balance for John request. Balance: 500
 approved balance for John request. Balance: 500

问题出在前 3 次 Printf 调用中,我可以获得类型的名称,但它们包括指针和包名称。有没有什么方法可以让我只得到没有包名和指针的“HeadEditor”,当然除了字符串处理解决方案,比如从结果中删除 * 和包名。

【问题讨论】:

  • 你考虑过实现Stringer接口吗?
  • 你能解释更多吗?我提到寻找字符串处理以外的解决方案。我在问 Go 是否有内置的非字符串处理方式。
  • 实现stringer接口并不比使用fmt更多的字符串处理。您要做的是让 HeadEditor 实现 String() string 方法,该方法可以简单地返回所需的文本,然后在与 %s 动词一起使用时由 fmt 自动调用此方法(不确定 %v 动词)。跨度>
  • 似乎也可以与 %v 一起使用 play.golang.org/p/rERpIuKJVEy

标签: go


【解决方案1】:

你已经接近最后一个了。正如Name() 的文档所说:

// Name returns the type's name within its package for a defined type.
// For other (non-defined) types it returns the empty string.

你得到了空字符串,因为chain_of_responsibility.HeadEditor 是一个定义的类型,*chain_of_responsibility.HeadEditor 不是。您可以使用Elem()从指针类型中获取类型:

// Elem returns a type's element type.
// It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.

所以,如果它并不总是一个指针,那么在调用 Elem() 之前,您需要先检查它是否是一个指针。

或者您可以通过放弃反射并为您的类型提供一个方法来使您的代码更简单(并且可能更快),该方法返回您想为每种类型使用的任何字符串,例如Type() string。然后,您可以定义一个 Typer 接口来封装该方法。

【讨论】:

  • 是的,所以解决方案是这样的: fmt.Printf("%v 已批准余额为 %v 请求。余额:%v\n", reflect.TypeOf(h).Elem().Name (), b.CustomerName, b.Balance)
猜你喜欢
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-10
  • 1970-01-01
相关资源
最近更新 更多