Read and write Yaml files with Go [closed] - go

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 3 years ago.
Improve this question
I have hundreds of yaml files (related to K8s and Helm) with different structures which I use python to edit if needed. I am deciding to learn Go and I wanted to write a new script with go to edit these files but surprisingly I saw that people are creating the yaml structure before reading the yaml file(GO reading YAML file and mapping to slice of structs and Go parse yaml file). What I mean is they create a struct with all the keys in the yaml file with the correct indentation.
I want to know is there a library in Go that you just give it the path to the file and it reads the yaml file dynamically? I want something like python that it reads the file and then you can just access the data similar to a dictionary or data['k1']['k2'] and when you are done with editing just write it back to the file.
Update
I cannot understand what is wrong with asking about libraries? Isn't this what eventually happens? People suggest different solutions and most of them are using different libraries. On the other hand, I am trying to see where and how to use Go, why my question get off-topic?

You can tell the yaml package to unmarshal into an empty interface:
package main
import (
"gopkg.in/yaml.v3"
"reflect"
)
func main() {
var data interface{}
yaml.Unmarshal([]byte("foo: bar"), &data)
println(reflect.TypeOf(data).String())
}
This outputs:
map[string]interface {}
You'll gets a structure consisting of maps, slices or scalar types depending on the input. Due to Go's static type system, you need to use reflection / casts to access the actual values.
Alternatively, you can unmarshal into a Node:
package main
import (
"gopkg.in/yaml.v3"
)
func main() {
var data yaml.Node
yaml.Unmarshal([]byte("foo: bar"), &data)
println(data.Kind)
}
This prints 1, which is a DocumentNode. Non-scalar nodes hold their children in the Content field; you can walk through the structure by checking each Node's Kind and descend for those nodes.

Related

Does Go support functional programming? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
As in java8:
someList.stream().map(e->e.getXXX()).toList()
For example, I have a Student array/slice, and the struct Student contains properties like Id, Name, and so on.
I want to extract all Ids into a NEW array/slice with one-line code like java8 as mentioned above, instead of range. Is there is an example?
Currently there is not an easy, builtin way to do this. Although Go has first-class functions and lexical closure, it's not possible to write a function like map that will operate on arbitrary types in the way you want. (Also, there's no compact lambda syntax, but I consider that a relatively minor issue).
Instead, you have to do one of the following:
Operate on interface{}. While this would let you write a func map([]interface{}, func(interface{})interface{}) []interface{}, you lose compile-time type safety, you lose performance, and a []interface{} is not a []string (or whatever the type is of the field you wanted to fetch), nor can you even type-assert it to one, so working with the result is cumbersome.
Use code-generation. There are libraries out there that will generate map/filter/etc. code for you, specialized to given types, so that none of the disadvantages of #1 apply. And Go ships with a Go parser in the standard library, so most code generators are fairly robust. But code generation is a separate build step, hampers debuggability, and can hurt the clarity of code.
Just live with boilerplate, writing lots of loops, and forget about trying to achieve functional style.
Wait for Go 1.18 to bring generics, which should make libraries of functional idioms a lot more practical.
Most experienced Go users would recommend approach #3, and so do I (reluctantly).

GO solution to structure aliasing? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
So I'm trying to port a package from "C" that implements AVL trees. It's an embedded implementation, so the AVL structure is embedded in the structure the application defines.
All of the internal code in the AVL package uses type casting, so if, for example, you put the AVL header at the beginning of your structure, what you pass to the AVL routine is something like
(struct avl *)&foo
where foo is your application structure.
As I understand it, GO won't let you do this (not without awful perversions which, as I understand it, are not supported, nor safe.)
That said, here's what I came up with: I added a field to the AVL structure as
owner interface{}
I then added a parameter to avl_tree_insert() as
owner interface{}
That parameter is a pointer to the beginning of the application structure, so something like this is done:
avl_tree_insert(root, &mystruct.avl, &mystruct, cmp_func)
avl_tree_insert then stores the owner interface in the corresponding field in its structure. Routines that look up or traverse the tree return, as before, an AVL node pointer, and the client then does
nodep = avlp.owner.(*mystruct)
and is good to go. This all works, but I can't help but wonder if there is a better way? Thanks!
A better way would be to use interfaces:
type AVLTreeNode interface {
// functions related to tree links, etc
}
type nodeImpl struct {
// Implements AVLTreeNode
}
// myNode embeds nodeimpl, so it is an AVLTreeNode
type myNode struct {
nodeImpl
// otherFields
}
This allows you to write tree management functions using AVLTreeNode interface, and then you can use type assertions to access the concrete structure itself.
avl_tree_insert(root, &mystruct, cmp_func)

ReadFile returns nil when attempting to read file [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I am getting nil for sampleFlags in my debugger when attempting to read my file test.json. I am not sure if it is a path issue or where the reader pointer is. How FetchFlags is triggered is by a handler in server.go that ultimately calls FetchFlags.
flags.go
package flags
import (
"encoding/json"
"fmt"
"io/ioutil"
)
type Flag struct {
Name string `json:"name"`
Category string `json:"category"`
Label string `json:"label"`
}
func FetchFlags() []Flag {
sampleFlags, _ := ioutil.ReadFile("test.json")
fmt.Printf("File contents: %s", sampleFlags)
var Flags []Flag
_ = json.Unmarshal(sampleFlags, &Flags)
return Flags
}
Structure:
/server
server.go
/package
/flags
flags.go
test.json
/pack_a
/pack_b
You are trying to open file relative to package path. This is a bad design approach. For example depending on compilation method Go may place binaries in $GOROOT/bin directory. And there will not be the test.json file.
Use absolute path for your file or use approaches from How can I open files relative to my GOPATH?.
The path should be relatve to your main.go(or equivalent) file and not your package.
(Absolute path should work as well but I am not 100% sure about that)
If you think about it then you will realize that package/flags is directly or indirectly imported into your main file.
Your code compilation/execution isn't jumping to package/flags, instead that code is imported to your main file.
I would recommend you to use abosulte path or path relative to your main file.

When naming interfaces, is it a good name if the ending is the same as the package name? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Which name is better, repository.UserRepository or repository.User?
I'm thinking about naming recently.
I have referenced several sources and they are talking.
Think about the context and name it.
Here is the link.
https://talks.golang.org/2014/names.slide#2
https://github.com/golang/go/wiki/CodeReviewComments
Additionally, Can you also recommend a project that can be referred to when creating an http server?
according to the golang official ducument
The importer of a package will use the name to refer to its contents, so exported names in the package can use that fact to avoid stutter. (Don't use the import . notation, which can simplify tests that must run outside the package they are testing, but should otherwise be avoided.) For instance, the buffered reader type in the bufio package is called Reader, not BufReader, because users see it as bufio.Reader, which is a clear, concise name. Moreover, because imported entities are always addressed with their package name, bufio.Reader does not conflict with io.Reader.
repository.User may be good then repository.UserRepository
the package in src/encoding/base64 is imported as "encoding/base64" not "encoding/base64Encoding"

Why does the print function only execute once [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
Why does the print function in this code only execute once?
package main
import (
"fmt"
"unsafe"
)
func main() {
b := make([]byte, 10)
s := *(*string)(unsafe.Pointer(&b))
b[0] = 'A'
fmt.Println(s)
fmt.Println("www")
}
As noted in comments above, whether the above works (whatever "works" really means) or not, depends on vagaries of the underlying system. (My second comment was wrong and I have deleted it.) In normal code, avoid unsafe: you need to know a lot about what you are doing with it, to use unsafe safely. Worse, even if you do know what you are doing, and use it safely today, things you do with it now might break in a future Go release.
I asked why you were trying this in the first place:
I just want to try to convert the variable b into a string with zero-copy ...
In this case, since you are creating b, you can just create it as a string in the first place.
More generally, there is an outstanding feature request for this. See (closed) issue 25484 and still-open issue 19367. I think it unlikely that these will be adopted for Go version 1.
Note that if you do make a string header that grants access to the slice data, the underlying bytes in the string are not read-only, unlike normal Go strings.

Resources