Получить имя структуры без выборки имени пакета или указателя - PullRequest
1 голос
/ 30 октября 2019

У меня очень простой код, подобный этому:

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» без имени пакета и указателя и, конечно, кроме решения для обработки строк, как удаление * и имя пакета из результата.

1 Ответ

4 голосов
/ 30 октября 2019

Вы близки с последним. Как сказано в документации 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 интерфейс для инкапсуляции этого метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...