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,},}}]

我在这里遇到两个问题:

  1. 在我的情况下,这是更改默认键名的最佳方式吗?
  2. 如果变量 postgresService 包含更多值,但我只需要 DATABASE_NAMEDATABASE_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...)
}

对于修改结构体字段,直接赋值是最直接的方式。对于删除切片元素,可以通过创建新切片并只添加需要的元素来实现,或者使用切片截断操作。

回到顶部