英文:
Append string to string builder passed to a method and return updated string builder back?
问题
我正在从C#
转向Golang
,并尝试做一些在C#中有效的操作。我试图通过将字符串附加到resourceBuilder
字符串构建器来填充它。
但是,我将resourceBuilder
字符串构建器传递给AppendResource
方法,并将字符串附加到传递给AppendResource
方法的同一个字符串构建器,但当调用返回到Build
方法时,我发现它没有附加到其中的所有内容。我确定我做错了什么,但我无法找出问题所在。
func Build(queryMap map[string][]QueryFilter, clientId int64, template []string) string {
var resourceBuilder strings.Builder
for _, propertyName := range template {
queryFilters := queryMap[propertyName]
AppendResource(queryFilters, resourceBuilder)
}
fmt.Println("output: ", resourceBuilder.String())
return resourceBuilder.String()
}
func AppendResource(resourcesOpt []QueryFilter, resourceBuilder strings.Builder) {
for _, qf := range resourcesOpt {
if len(resourceBuilder.String()) == 0 {
resourceBuilder.WriteString(qf.Resource.ResourceType)
resourceBuilder.WriteString("-")
resourceBuilder.WriteString(strconv.Itoa(qf.Resource.ResourceId))
} else {
resourceBuilder.WriteString("+")
resourceBuilder.WriteString(qf.Resource.ResourceType)
resourceBuilder.WriteString("-")
resourceBuilder.WriteString(strconv.Itoa(qf.Resource.ResourceId))
}
}
}
如果我在C#中做同样的事情,那么resourceBuilder
字符串构建器会在我的Build
方法中正确更新。我是否做错了什么?
英文:
I am transitioning from C#
to Golang
and I am trying to do things what used to work in C#. I am trying to populate resourceBuilder
string builder by appending string to it.
But I am passing resourceBuilder
string builder to AppendResource
method and appending strings to the same string builder passed to AppendResource
method but when the call comes back to Build
method, I don't see it has everything appended to it. I am sure something wrong I am doing but I cannot figure it out.
func Build(queryMap map[string][]QueryFilter, clientId int64, template []string) string {
var resourceBuilder strings.Builder
for _, propertyName := range template {
queryFilters := queryMap[propertyName]
AppendResource(queryFilters, resourceBuilder)
}
fmt.Println("output: ", resourceBuilder.String())
return resourceBuilder.String()
}
func AppendResource(resourcesOpt []QueryFilter, resourceBuilder strings.Builder) {
for _, qf := range resourcesOpt {
if len(resourceBuilder.String()) == 0 {
resourceBuilder.WriteString(qf.Resource.ResourceType)
resourceBuilder.WriteString("-")
resourceBuilder.WriteString(strconv.Itoa(qf.Resource.ResourceId))
} else {
resourceBuilder.WriteString("+")
resourceBuilder.WriteString(qf.Resource.ResourceType)
resourceBuilder.WriteString("-")
resourceBuilder.WriteString(strconv.Itoa(qf.Resource.ResourceId))
}
}
}
If I do same thing in C# then resourceBuilder
string builder gets updated properly in my Build
method. Is there anything wrong I am doing.
答案1
得分: 1
问题在于你通过值传递了Builder,所以你创建了一个副本。方法对副本进行更改,所以调用方法看不到更改。
你可以通过传递指针(*strings.Builder
)来修复它,但我不会将Builder传递给第二个方法。在我看来,这会导致更复杂且不太可重用的代码。除非这段代码在某个超高性能关键代码段中,轻微的性能提升不值得。
以下是我编写的代码:
func Build(queryMap map[string][]QueryFilter, clientId int64, template []string) string {
var resourceBuilder strings.Builder
for _, propertyName := range template {
queryFilters := queryMap[propertyName]
resourceBuilder.WriteString(GetResourceString(queryFilters))
}
fmt.Println("output: ", resourceBuilder.String())
return resourceBuilder.String()
}
func GetResourceString(resourcesOpt []QueryFilter) string {
var resourceBuilder strings.Builder
for i, qf := range resourcesOpt {
resourceBuilder.WriteString(qf.Resource.ResourceType)
resourceBuilder.WriteString("-")
resourceBuilder.WriteString(strconv.Itoa(qf.Resource.ResourceId))
if i > 0 {
resourceBuilder.WriteString("+")
}
}
return resourceBuilder.String()
}
英文:
The issue is that you are passing the Builder by value, so you are creating a copy of it. The method makes changes to the copy, so the calling method never sees the changes.
You could fix it by passing a pointer (*strings.Builder
), but I wouldn't pass the Builder into the second method at all. In my mind, it makes for more complicated and less reusable code. Unless this code is in some ultra-performance critical section of code the slight performance boost wouldn't be worth it.
This is how I would code it:
func Build(queryMap map[string][]QueryFilter, clientId int64, template []string) string {
var resourceBuilder strings.Builder
for _, propertyName := range template {
queryFilters := queryMap[propertyName]
resourceBuilder.WriteString(GetResourceString(queryFilters))
}
fmt.Println("output: ", resourceBuilder.String())
return resourceBuilder.String()
}
func GetResourceString(resourcesOpt []QueryFilter) string {
var resourceBuilder strings.Builder
for i, qf := range resourcesOpt {
resourceBuilder.WriteString(qf.Resource.ResourceType)
resourceBuilder.WriteString("-")
resourceBuilder.WriteString(strconv.Itoa(qf.Resource.ResourceId))
if i > 0 {
resourceBuilder.WriteString("+")
}
}
return resourceBuilder.String()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论