Golang中如何修改除指定字段外的所有结构体字段(使用内存地址)

Golang中如何修改除指定字段外的所有结构体字段(使用内存地址) 我想让map中的"country"字段保持不变:

type Company struct{ CompanyName, Role, country string }
func changeName(A *map[string]Company) {
   *A = map[string]Company{"dr": {CompanyName: "CompanyBBB", Role: "manager", country: "U"},
      "hamed": {CompanyName: "CompanyBBB", Role: "manager", country: "U"},}
}
func main() {
   var A = map[string]Company{"dr": {CompanyName: "avaze", Role: "manager", country: "I"},
      "hamed": {CompanyName: "avaze", Role: "softwarEngineer", country: "I"},}
   changeName(&A)
   fmt.Println("main (15):::", A)
}

换句话说,我想在"changeName函数"中排除country字段。 有什么解决方案吗?

这是Go Playground链接:

Go Playground - The Go Programming Language

提前感谢。


更多关于Golang中如何修改除指定字段外的所有结构体字段(使用内存地址)的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

你想删除映射元素还是什么?

更多关于Golang中如何修改除指定字段外的所有结构体字段(使用内存地址)的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


不,我希望在初始化后不允许修改"Company"结构体的"country"字段。

停止比较Go和Java 😊

你可以在Go中使用结构体的未导出字段来实现类似行为。

谢谢,acim,我忘记了这个,这就是解决方案。
另外,我是 Golang 这边的 🙂

https://play.golang.org/p/y8SVdrv1yZr

你需要一个指向Company的指针映射,原因如下:https://github.com/golang/go/issues/3117

感谢acim,实际上我将这个与Java进行了比较,Java不允许修改字段,但我认为Golang不具备这种能力。

public class User{
	private String company;
	private String role;
	private String country;

    public User(String company, String role, String country) {
		this.company = company;
		this.role = role;
		this.country = country;
	}

	public void setCompany(String company) {
		this.company = compnay;
	}

	public void setRole(String role) {
		this.role = role;
	}
}

User类在初始化后不允许更改(设置)company字段。

你需要将其封装在另一个包中。例如,你的 main.go 文件可能如下所示:

package main

import (

"fmt"

"path_to_to/types"

)

func main() {

user := types.NewUser("Jack", "Amazon", "guard")

user.SetCompany("Google")

fmt.Printf("%#v\n", user)

}

然后你的 types 包(位于 types 文件夹中)将包含类似以下内容:

package types

type User struct {
	company string
	role    string
	country string
}

func NewUser(company, role, country string) *User {
	return &User{
		company: company,
		role:    role,
		country: country,
	}
}

func (u *User) SetCompany(company string) {
	u.company = company
}

func (u *User) SetRole(role string) {
	u.role = role
}

在Go语言中,要修改结构体除指定字段外的所有字段,可以通过几种方式实现。由于结构体字段country是小写字母开头,它在包外部是不可导出的(即私有字段),这意味着在changeName函数中无法直接访问或修改它。因此,我们需要通过其他方法来更新可导出的字段,同时保持country字段不变。

以下是一个解决方案,通过遍历原始映射,并为每个键创建新的Company结构体实例,仅更新可导出的字段(CompanyNameRole),而保留原始的country值。这种方法利用了结构体的内存地址和指针来高效操作。

解决方案代码示例:

package main

import "fmt"

type Company struct {
    CompanyName, Role, country string
}

func changeName(A *map[string]Company) {
    // 创建一个临时映射来存储更新后的值
    updatedMap := make(map[string]Company)
    for key, value := range *A {
        // 仅更新可导出字段,保留原始 country 值
        updatedMap[key] = Company{
            CompanyName: "CompanyBBB",
            Role:        "manager",
            country:     value.country, // 使用原始 country 值
        }
    }
    *A = updatedMap // 通过指针更新原始映射
}

func main() {
    var A = map[string]Company{
        "dr":    {CompanyName: "avaze", Role: "manager", country: "I"},
        "hamed": {CompanyName: "avaze", Role: "softwarEngineer", country: "I"},
    }
    changeName(&A)
    fmt.Println("main (15):::", A)
}

代码解释:

  • 结构体定义Company结构体中的country字段是小写字母开头,因此在main包外部(如其他包中)不可访问。但在同一包内(如main函数和changeName函数都在main包中),我们可以直接访问它。
  • changeName函数:该函数接收一个指向映射的指针。它遍历原始映射中的每个键值对,为每个键创建一个新的Company实例,其中CompanyNameRole被更新为固定值(“CompanyBBB"和"manager”),而country字段从原始值中复制(value.country)。然后,通过指针更新原始映射。
  • main函数:初始化映射A,调用changeName函数,并打印结果。输出将显示CompanyNameRole已更新,但country字段保持不变(例如,仍为"I")。

输出示例:

运行上述代码后,输出将类似于:

main (15)::: map[dr:{CompanyBBB manager I} hamed:{CompanyBBB manager I}]

这种方法确保了country字段不被修改,同时高效地更新了其他字段。如果结构体有更多字段,可以扩展此逻辑,仅更新需要修改的字段。注意,由于country字段是私有的,如果在其他包中操作,可能需要通过方法或函数来间接访问。

回到顶部