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.
CodePudding user response:
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()
}
