【问题标题】:Print a type without using reflrect and create new object在不使用 reflrect 的情况下打印类型并创建新对象
【发布时间】:2018-10-26 18:48:00
【问题描述】:

在下面的代码中,为了显示预期的类型,我必须创建一个新对象并在其上调用reflect.TypeOf

package main

import (
    "fmt"
    "reflect"
)

type X struct {
    name string
}

func check(something interface{}) {
    if _, ok := something.(*X); !ok {
        fmt.Printf("Expecting type %v, got %v\n", 
            reflect.TypeOf(X{}), reflect.TypeOf(something))
    }
}

func main() 
    check(struct{}{})
}

也许创建对象不是开销,但我仍然很想知道更好的方法。 java中有X.getName()X.getSimpleName()之类的东西吗?

【问题讨论】:

  • 使用reflect.TypeOf((*X)(nil)).Elem() 避免创建X 的值。要打印值的类型,您可以使用fmt.Printf("%T", something)
  • 感谢%T。您能否将其发布为答案?

标签: pointers go struct reflection types


【解决方案1】:

要获取一个类型的reflect.Type描述符,可以使用

reflect.TypeOf((*X)(nil)).Elem()

为了避免创建X 类型的值。有关详细信息,请参阅以下问题:

How to get the string representation of a type?

Golang TypeOf without an instance and passing result to a func

要打印一些值的类型,你可以使用fmt.Printf("%T, something)

而实际上,对于你想做的事情,你可以完全把反思放在一边,简单地做:

fmt.Printf("Expecting type %T, got %T\n", (*X)(nil), something)

输出将是(在Go Playground 上尝试):

Expecting type *main.X, got struct {}

【讨论】:

    【解决方案2】:

    使用反射几乎总是一个糟糕的选择。您可以考虑使用以下方式之一

    使用开关

    如果您想根据类型控制流量,可以使用switch 构造

    func do(i interface{}) {
        switch v := i.(type) {
        case int:
            fmt.Printf("Twice %v is %v\n", v, v*2)
        case string:
            fmt.Printf("%q is %v bytes long\n", v, len(v))
        default:
            fmt.Printf("I don't know about type %T!\n", v)
        }
    }
    

    使用fmt

    如果您只想显示其类型,您可以随时使用 fmt

    i := 1000
    fmt.Printf("The type is %T", i)
    

    【讨论】:

    • “使用反射几乎总是一个糟糕的选择。” 我不同意这一点。 fmt 包也使用反射来实现同样的效果。
    • 是的,但在这种情况下您不能直接使用它。 ->jerf.org/iri/post/2945。从官方博客你可以发现“一旦你理解了这些规律,Go 中的反射就会变得更容易使用,尽管它仍然很微妙。它是一个强大的工具,应该小心使用,除非绝对必要,否则应避免使用。”
    猜你喜欢
    • 1970-01-01
    • 2021-11-19
    • 2014-06-09
    • 1970-01-01
    • 2012-04-14
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    相关资源
    最近更新 更多