Get the type name of a generic struct without type parameters

王林
Release: 2024-02-13 12:27:07
forward
1150 people have browsed it

Get the type name of a generic struct without type parameters

In this article, php editor Strawberry will introduce to you how to get the type name of a generic structure without type parameters. Generics are a powerful programming technique that allows you to write generic code without specifying specific types. However, sometimes we may need to obtain the type name of a generic structure without containing specific type parameters. This article will answer this question in detail for you and help you better understand and apply generic programming.

Question content

Suppose I have a generic structure called foo from which I create two objects. I can determine the specific type of each using reflect.typeof() like this:

package main

import (
    "fmt"
    "reflect"
)

type foo[t any] struct {
    data t
}

func main() {
    a := foo[string]{"cheese"}
    b := foo[int]{42}

    fmt.println(reflect.typeof(a))
    fmt.println(reflect.typeof(b))
}

// main.foo[string]
// main.foo[int]
Copy after login

I'm interested in determining the general type of these objects (i.e. foo), rather than the specific types (i.e. foo[string] and foo[int]). Is this possible or do I need to manually extract the generic type from these strings (e.g. using regular expressions)?

edit

A regular expression might look like this:

func GetGenericType(x any) string {
    // Get type as a string
    s := reflect.TypeOf(x).String()

    // Regex to run
    r := regexp.MustCompile(`\.(.*)\[`)

    // Return capture
    return r.FindStringSubmatch(s)[1]
}


fmt.Println(GetGenericType(a))
fmt.Println(GetGenericType(b))

// foo
// foo

Copy after login

I also saw this question, but that didn't answer the question because it gave the specific type (i.e. main.foo[string]) instead of the generic type (i.e., foo).

Workaround

Reflection cannot see the name of a "base" generic type because the base type does not exist at runtime.

The relevant paragraph in the

go spec is Instantiation:

Instantiating a type will produce a new non-generic named type ; instantiating a function will produce a new non-generic function.

So when you write:

b := foo[int]{42}
name := reflect.typeof(b).name()
Copy after login

The name of this type is exactly foo[int].

It's worth noting that an identifier without a type parameter list foo is relevant at compile time, as it prevents you from redeclaring it in the same package. Type definition:

Type definition creates a new, different type with the same type The underlying type and operation are given as the type and bound Identifier, type name, give it .

typedef = identifier [ typeparameters ] type .
Copy after login

However, as mentioned above, instantiation results in a new named type that is different from foo; at runtime, you only deal with instantiation when you can use reflection.

In conclusion, I think your regex solution is acceptable until some helper functions are added to stdlib (if any). Reposting it here for clarity:

func getgenerictype(x any) string {
    // get type as a string
    s := reflect.typeof(x).string()

    // regex to run
    r := regexp.mustcompile(`\.(.*)\[`)

    // return capture
    return r.findstringsubmatch(s)[1]
}
Copy after login

Remember the difference between type.string() and type.name(): Any type can have a string representation, but only named types do name. (Obviously, right?). For example, if you write:

b := &foo[int]{42}
Copy after login

Then the type of b is *foo[int], which is an anonymous composite type, name() returns an empty string.

The above is the detailed content of Get the type name of a generic struct without type parameters. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!