Skip to content

proposal: reflect: package reflection #61796

Open
@glacials

Description

@glacials

Proposal

I'd like to propose basic package reflection in reflect to support discovery of types, functions, and variables in a package.

Similar to how value reflection allows discovery of methods and fields given a struct value; package reflection should allow discovery of functions, variables, and types given a package.

Problem

This closes a gap that exists today where code using reflect must be "pre-loaded" with the types it should know about, making every new type, function, or variable that "wants" to be reflected first register itself with the reflector. This is not up to the standard of how reflection of structs works, where reflecting code can iterate over every struct field and method.

Example Usage

One possibility is to retrieve a package from an "anchor" type:

import "reflect"
import "time"

t := reflect.TypeOf(time.Time{})
p := t.Package() // Returns a reflect.Package

Another, which uses a modified syntax, allows direct retrieval:

import "reflect"
import "time"

p = reflect.PackageOf(time) // Returns a reflect.Package

Example Interface

A reflect.Package might respond to similar calls as a reflect.Value:

type Package interface {
	// Equal reports true if p is equal to q.
	// For two invalid packages, Equal will report true.
	// Otherwise, Equal will report true if p and q
	// refer to the same package.
	Equal(q Package) bool
	// Function returns a function value corresponding to p's i'th function.
	// Function panics if i is out of range.
	Function(i int) Value
	// FunctionByName returns a function value corresponding to the function
	// of p with the given name.
	// It returns the zero Value if no function was found.
	FunctionByName(name string) Value
	// NumFunction returns the number of functions in the package p.
	NumFunction() int
	// NumType returns the number of types in the package p.
	NumType() int
	// NumVar returns the number of fields in the package p.
	NumVar() int
	// PkgPath returns a defined package's path, that is, the import path
	// that uniquely identifies the package, such as "encoding/base64".
	Path() string
	// String returns a string representation of the package.
	// The string representation may use shortened package names
	// (e.g., base64 instead of "encoding/base64") and is not
	// guaranteed to be unique among types.
	// To test for package identity, compare the Packages directly.
	String() string
	// Type returns a type corresponding to p's i'th type.
	// Type panics if i is out of range.
	Type(i int) Type
	// TypeByName returns a type value corresponding to the type
	// of p with the given name.
	// It returns the zero value if no type was found.
	TypeByName(name string) Type
	// Var returns the i'th variable of the package p.
	// It panics if i is out of range.
	Var(i int) Value
	// VarByName returns the package variable with the given name.
	// It returns the zero Value if no variable was found.
	VarByName(name string) Value
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Incoming

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions