Golang中如何修改和删除结构体的值
Golang中如何修改和删除结构体的值 我需要通过Go来修改结构体中键的名称。
我有这个函数
func (p *DbConfig) myfunction(prefix string, namespace string, dbName string, userSecret string) []corev1.EnvVar {
prefix = Underscore(prefix)
namespace = Underscore(namespace)
envs := filter(p.myfunction(prefix), func(item corev1.EnvVar) bool {
if item.Name == "USER" {
return false
}
if item.Name == "PASSWORD" {
return false
}
return true
})
return append(envs, []corev1.EnvVar{
{
Name: prefix + "DB_NAME",
Value: namespace + dbName,
},
{
Name: prefix + "DB_USER",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: userSecret,
},
Key: "POSTGRES_USER",
},
},
},
{
Name: prefix + "DB_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: userSecret,
},
Key: "POSTGRES_PASSWORD",
},
},
},
}...)
}
其中 EnvVar 结构体看起来像
type EnvVar struct {
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"`
ValueFrom *EnvVarSource `json:"valueFrom,omitempty" protobuf:"bytes,3,opt,name=valueFrom"`
}
type EnvVarSource struct {
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" protobuf:"bytes,1,opt,name=fieldRef"`
ResourceFieldRef *ResourceFieldSelector `json:"resourceFieldRef,omitempty" protobuf:"bytes,2,opt,name=resourceFieldRef"`
ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty" protobuf:"bytes,3,opt,name=configMapKeyRef"`
SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty" protobuf:"bytes,4,opt,name=secretKeyRef"`
}
在这里,我需要将包含“CONTAINER”的值更改为容器中使用的正确环境变量。
func containerEnvs(hub *immv1alpha1.ImmHub, instance *immv1alpha1.Container) []corev1.EnvVar {
postgresService := hub.Spec.DbConfig.myfunction("CONTAINER_", hub.Namespace, instance.Spec.dbName, instance.Spec.userSecret)
//在这里我想修改所需结构体的键,以便传递正确的环境变量
postgresService[0].Name = "DATABASE_NAME"
postgresService[1].Name = "DATABASE_USER"
service := []corev1.EnvVar{
{
Name: "DATABASE_NAME",
Value: instance.Spec.dbName,
}
}
return append(service, append(postgresService)...)
}
postgresService 变量的输出看起来像
[{CONTAINER_DB_NAME testdb nil} {CONTAINER_DB_USER &EnvVarSource{FieldRef:nil,ResourceFieldRef:nil,ConfigMapKeyRef:nil,SecretKeyRef:&SecretKeySelector{LocalObjectReference:LocalObjectReference{Name:secret,},Key:POSTGRES_USER,Optional:nil,},}} {CONTAINER_DB_PASSWORD &EnvVarSource{FieldRef:nil,ResourceFieldRef:nil,ConfigMapKeyRef:nil,SecretKeyRef:&SecretKeySelector{LocalObjectReference:LocalObjectReference{Name:secret,},Key:POSTGRES_PASSWORD,Optional:nil,},}}]
我在这里遇到两个问题:
- 在我的情况下,这是更改默认键名的最佳方式吗?
- 如果变量
postgresService包含更多值,但我只需要DATABASE_NAME和DATABASE_USER,我该如何从postgresService中删除其余的值?
更多关于Golang中如何修改和删除结构体的值的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
X_T: 更改结构体中键的名称
这是在编译时定义的。也许你需要的是一个 map。
更多关于Golang中如何修改和删除结构体的值的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中修改结构体字段值可以直接通过赋值操作实现。对于删除结构体切片中的元素,可以使用切片操作。
以下是针对您问题的具体实现:
func containerEnvs(hub *immv1alpha1.ImmHub, instance *immv1alpha1.Container) []corev1.EnvVar {
postgresService := hub.Spec.DbConfig.myfunction("CONTAINER_", hub.Namespace, instance.Spec.dbName, instance.Spec.userSecret)
// 1. 修改结构体字段值
for i := range postgresService {
switch postgresService[i].Name {
case "CONTAINER_DB_NAME":
postgresService[i].Name = "DATABASE_NAME"
case "CONTAINER_DB_USER":
postgresService[i].Name = "DATABASE_USER"
}
}
// 2. 过滤只需要的字段
var filteredEnvs []corev1.EnvVar
for _, env := range postgresService {
if env.Name == "DATABASE_NAME" || env.Name == "DATABASE_USER" {
filteredEnvs = append(filteredEnvs, env)
}
}
// 或者使用预定义的过滤函数
filteredEnvs = filterEnvs(postgresService, []string{"DATABASE_NAME", "DATABASE_USER"})
// 3. 添加额外的环境变量
service := []corev1.EnvVar{
{
Name: "DATABASE_NAME",
Value: instance.Spec.dbName,
},
}
return append(service, filteredEnvs...)
}
// 通用的环境变量过滤函数
func filterEnvs(envs []corev1.EnvVar, keepNames []string) []corev1.EnvVar {
var result []corev1.EnvVar
nameSet := make(map[string]bool)
for _, name := range keepNames {
nameSet[name] = true
}
for _, env := range envs {
if nameSet[env.Name] {
result = append(result, env)
}
}
return result
}
// 如果需要更精确的修改,可以直接定位特定索引
func containerEnvsAlternative(hub *immv1alpha1.ImmHub, instance *immv1alpha1.Container) []corev1.EnvVar {
postgresService := hub.Spec.DbConfig.myfunction("CONTAINER_", hub.Namespace, instance.Spec.dbName, instance.Spec.userSecret)
// 假设知道具体索引位置
if len(postgresService) > 0 {
postgresService[0].Name = "DATABASE_NAME"
}
if len(postgresService) > 1 {
postgresService[1].Name = "DATABASE_USER"
}
// 只保留前两个元素
if len(postgresService) > 2 {
postgresService = postgresService[:2]
}
service := []corev1.EnvVar{
{
Name: "DATABASE_NAME",
Value: instance.Spec.dbName,
},
}
return append(service, postgresService...)
}
对于修改结构体字段,直接赋值是最直接的方式。对于删除切片元素,可以通过创建新切片并只添加需要的元素来实现,或者使用切片截断操作。

