Source File
visiblefields.go
Belonging Package
reflect
// Copyright 2021 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package reflect// VisibleFields returns all the visible fields in t, which must be a// struct type. A field is defined as visible if it's accessible// directly with a FieldByName call. The returned fields include fields// inside anonymous struct members and unexported fields. They follow// the same order found in the struct, with anonymous fields followed// immediately by their promoted fields.//// For each element e of the returned slice, the corresponding field// can be retrieved from a value v of type t by calling v.FieldByIndex(e.Index).func ( Type) []StructField {if == nil {panic("reflect: VisibleFields(nil)")}if .Kind() != Struct {panic("reflect.VisibleFields of non-struct type")}:= &visibleFieldsWalker{byName: make(map[string]int),visiting: make(map[Type]bool),fields: make([]StructField, 0, .NumField()),index: make([]int, 0, 2),}.walk()// Remove all the fields that have been hidden.// Use an in-place removal that avoids copying in// the common case that there are no hidden fields.:= 0for := range .fields {:= &.fields[]if .Name == "" {continue}if != {// A field has been removed. We need to shuffle// all the subsequent elements up..fields[] = *}++}return .fields[:]}type visibleFieldsWalker struct {byName map[string]intvisiting map[Type]boolfields []StructFieldindex []int}// walk walks all the fields in the struct type t, visiting// fields in index preorder and appending them to w.fields// (this maintains the required ordering).// Fields that have been overridden have their// Name field cleared.func ( *visibleFieldsWalker) ( Type) {if .visiting[] {return}.visiting[] = truefor := 0; < .NumField(); ++ {:= .Field().index = append(.index, ):= trueif , := .byName[.Name]; {:= &.fields[]if len(.index) == len(.Index) {// Fields with the same name at the same depth// cancel one another out. Set the field name// to empty to signify that has happened, and// there's no need to add this field..Name = ""= false} else if len(.index) < len(.Index) {// The old field loses because it's deeper than the new one..Name = ""} else {// The old field wins because it's shallower than the new one.= false}}if {// Copy the index so that it's not overwritten// by the other appends..Index = append([]int(nil), .index...).byName[.Name] = len(.fields).fields = append(.fields, )}if .Anonymous {if .Type.Kind() == Pointer {.Type = .Type.Elem()}if .Type.Kind() == Struct {.(.Type)}}.index = .index[:len(.index)-1]}delete(.visiting, )}
The pages are generated with Golds v0.7.6. (GOOS=linux GOARCH=amd64)