Golang递归调用中字符串的构建方法

Golang递归调用中字符串的构建方法 你好,

我写了一段代码,但在将结果字符串追加到字符串切片时遇到了困难。如何完善这段代码?

谢谢

试图实现的目标:

ServiceName
Addresses
Logger/Level
HTTP/Server/Host
HTTP/Server/Port
HTTP/Server/Request/Timeout
HTTP/Server/Request/Size

不完整的代码:

package main

import (
	"fmt"
	"reflect"
)

type Config struct {
	ServiceName string
	Addresses   []string
	Logger      struct {
		Level string
	}
	HTTP struct {
		Server struct {
			Host    string
			Port    int
			Request struct {
				Timeout string
				Size    int
			}
		}
	}
}

func main() {
	walk(Config{}, 0)
}

func walk(input any, level int) {
	source := reflect.ValueOf(input)

	for i := 0; i < source.NumField(); i++ {
		field := source.Field(i)

		if !field.CanInterface() {
			continue
		}

		fmt.Println(source.Type().Field(i).Name)

		if field.Kind() == reflect.Struct {
			walk(field.Interface(), level+4)
		}
	}
}

更多关于Golang递归调用中字符串的构建方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang递归调用中字符串的构建方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在递归构建字符串时,你需要传递并维护当前路径。以下是完善后的代码:

package main

import (
	"fmt"
	"reflect"
	"strings"
)

type Config struct {
	ServiceName string
	Addresses   []string
	Logger      struct {
		Level string
	}
	HTTP struct {
		Server struct {
			Host    string
			Port    int
			Request struct {
				Timeout string
				Size    int
			}
		}
	}
}

func main() {
	var results []string
	walk(Config{}, "", &results)
	
	for _, r := range results {
		fmt.Println(r)
	}
}

func walk(input any, path string, results *[]string) {
	source := reflect.ValueOf(input)

	for i := 0; i < source.NumField(); i++ {
		field := source.Field(i)
		fieldName := source.Type().Field(i).Name

		if !field.CanInterface() {
			continue
		}

		currentPath := fieldName
		if path != "" {
			currentPath = path + "/" + fieldName
		}

		if field.Kind() == reflect.Struct {
			walk(field.Interface(), currentPath, results)
		} else {
			*results = append(*results, currentPath)
		}
	}
}

输出结果:

ServiceName
Addresses
Logger/Level
HTTP/Server/Host
HTTP/Server/Port
HTTP/Server/Request/Timeout
HTTP/Server/Request/Size

如果需要处理切片字段(如Addresses),可以添加以下逻辑:

func walk(input any, path string, results *[]string) {
	source := reflect.ValueOf(input)

	for i := 0; i < source.NumField(); i++ {
		field := source.Field(i)
		fieldName := source.Type().Field(i).Name

		if !field.CanInterface() {
			continue
		}

		currentPath := fieldName
		if path != "" {
			currentPath = path + "/" + fieldName
		}

		switch field.Kind() {
		case reflect.Struct:
			walk(field.Interface(), currentPath, results)
		case reflect.Slice:
			// 对于切片字段,可以选择记录路径或跳过
			*results = append(*results, currentPath)
		default:
			*results = append(*results, currentPath)
		}
	}
}
回到顶部