0

I want to append to slice in map which is defined as map[any]any

I am having type conversion issues and don't know how to treat result[index][ABSPath] as slice so I can append data to it

Here is the example code:

package main

import (
    "fmt"
    "io/fs"
    "os"
    "strings"
)

func contains(target []map[any]any, key string) (int, bool) {

    for index, entry := range target {
        if _, exists := entry[key]; exists {
            return index, true
        }
    }
    return -1, false
}

func getPath(path string, filename string) string {
    return path[0:strings.Index(path, filename)]
}

func main() {

    path := os.Args[1]
    handle := os.DirFS(path)
    result := make([]map[any]any, 0)

    _ = fs.WalkDir(handle, ".", func(path string, d fs.DirEntry, err error) error {
        ABSPath := getPath(path, d.Name())
        if index, exists := contains(result, ABSPath); exists {
                        // this line fails
            result[index][ABSPath] = append(result[index][ABSPath], d.Name())
        } else {
        
            result = append(result, map[any]any{ABSPath: []string{d.Name()}})
        }
        return nil
    })

    fmt.Println(result)
}

I am new in golang and not sure how to solve this problem. This is the error I am getting: # learning/test/1 ./main.go:43:36: first argument to append must be a slice; have result[index][ABSPath] (map index expression of type any)

Note: I already tested and know that making result := make([]map[string][]string, 0) will solve the issue, however for learning purposes, I want to do it with "any".

ANSWER for others having similar problem: I have solved this issue by doing slice conversion as below:

result[index][ABSPath] = append(result[index][ABSPath].([]string), d.Name())
John Doe
  • 17
  • 1
  • 2
    1. Stop that any business, this is not helpful in Go! Really! You seem to work with ints and strings so use ints and strings or redesign. 2. You have to type assert to a slice as `any` is not a slice and you cannot append to it. 3. `append(result[index][ABSPath].([]string), d.Name())` should do. 4. Did I mention you should stop that any crap? See why? 5. Newcomers often think `any` means "any type" like in "whatever it is" or "?". It's not. `any` is a dedicated type like int16, map[string]func()int or []slice. Like you cannot use int16 where a []string is required you cannot use any. – Volker Jun 07 '23 at 10:56
  • Thank you for your reply, I also realized that this is error prone code, but wanted to learn other deep corners of Golang. BTW, after brute-forcing different ways, I also finally found that ([]string) will do the trick. :) – John Doe Jun 07 '23 at 11:02
  • @Volker I am curious to know; will this type of conversion affect speed of program ? Like interface{} -> []string – John Doe Jun 07 '23 at 11:05
  • 2
    @JohnDoe: `.([]string)` is not a conversion, it is a [type assertion](https://go.dev/ref/spec#Type_assertions). It is not going to affect the speed of your program. – JimB Jun 07 '23 at 13:06
  • A type assertion is not a type conversions. I'd like to advice to learn the language fundamentals first. In your case: Think about each of the operations you do, which part of the hardware they affect and how fast these operations are (in order of magnitude). I'd like to recommend to stop worrying about "speed" of "crappy" code and focus on high quality code first. Note that using `any` is not a deep corner and you'll learn almost nothing here. – Volker Jun 07 '23 at 13:06
  • Thanks for your recommendations! Appreciate it! – John Doe Jun 07 '23 at 19:20

0 Answers0