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)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last year.
Improve this question
In OCaml, there is a construct called univ_map.t, which allows you to map from 'a Type_equal.Id.t values to 'as. Here is an example.
Is there a construct that would allow me to do something similar in Rust? I know in OCaml they are implemented with open variants, which I don't believe Rust has.
I'm not familiar with OCaml, but looking at the docs:
Univ_map: Universal/heterogeneous maps [...] useful for storing values of arbitrary type in a single map [...] built on top of Univ.
Univ: An extensible universal variant type. Every type id corresponds to one branch of the variant type.
The closest thing that Rust has that sounds like Univ is the Any trait, which is designed to represent any type (with exceptions). However, there is no standard type for storing a collection of Anys that is accessed by its TypeId. From looking how popular crates handle this, its usually a bespoke wrapper around HashMap<TypeId, Box<dyn Any>> or similar. I hope I've understood correctly.
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
I am currently learning go after C++. I just get stuck every time while facing interface.
e.g:
s := []interface{}{"a", "b", "c"}
How string could be an interface?
I am not getting in what sense interface is introduced in go. There are many more doubts regarding interface.
Answer to the above question and especially providing some learning resources regarding interface would be great.
Thanks in advance :)
By definition, an interface is defined as a set of method signatures. So it is used to indicate which methods should be implemented by another type. If the interface doesn't specify any method signatures in the interface declaration body then any valid type can be of the type of that interface since there are no prerequisites of being that interface.
In your example, the slice contains a type of interface{} meaning any type can be a valid candidate as the slice input.
s := []interface{}{"a", 1, false}
https://tour.golang.org/methods/9 is a good place for exploring and learning go.
You can think of an interface as a container that holds a value and the type of that value.
When you define your own interfaces the compiler will ensure that the values you assign (store in the interface) have methods that match what you specified in your interface definition.
Empty interfaces, interface{}, have no methods and can therefore store any value since there are no expectations for the existence of any particular methods.
If you have not already, check the section on interfaces in A Tour of Go.
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
As far as I can tell, when passing a function as an input into another function it must have an identical contract - not allowing for the ability to leverage interfaces as follows: (runnable example here: https://play.golang.org/p/LXvNgziDdgp)
package main
func main() {
foo(processS1)
}
type I1 interface {
bar()
}
type S1 struct {
}
func (s1 S1) bar() {
}
func processS1(s S1) {
}
func foo(func(I1)) {
}
from a type-system perspective, the assumed issue is that a function type is passed, and not an interface. but, I can't see what the issue would be with allowing the type system to infer the relationship here. I believe I've seen this in other languages.
Any reason as to why Go can't/won't support this?
In short the relationship you've defined there is not valid in any typed language.
You've defined foo as a function that takes a type func(I1). func(S1) is a different type. The complexities of the relationships between these types is more complex than simple inheritance. The golang team has chosen simplicity over solving for function type and signature matching.
One way these complexities become apparent is you've actually defined the relationship backwards. Imagine there was an struct s2 that also implemented I1. Also, s1 had a method baz().
If foo passed in S2{} to the function parameter it would implement I1, but processS1 would call a function that doesn't exist on the passed in struct.
runnable: https://play.golang.org/p/EvwQpCXhqTb
Even if you swapped the types (https://play.golang.org/p/ItUx5pRJ6-g), which would be able to run without panics, it still wouldn't work in golang. As to why golang doesn't try to solve these problems, I'm not sure you'll get a satisfactory answer. The team responds to these kind of questions with general philosophical views such as:
The simplicity of method matching is a feature of the language.
I do think your question here does help justify that view though. It's a complex the problem is hard to reason about. It's easier to just not solve it than add additional complexity.
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.
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 4 years ago.
Improve this question
In some Golang Tips said that: small object should pass by value and big object should pass by reference.
But how big object is small object?
If a struct has 10+ Fields. should it pass by value?
As you see from the discussion it is "hard" to understand when to use a pointer or a reference. If you are learning the Golang I suggest to use this approach to decide when to use pointer or reference:
I need to use a struct only for read purpose
In this case I suggest to use a pointer to a struct, that's for performance reason (copy a struct is a time consuming operation as you can tell, no matter if is a "big" struct or a small one).
I need to use a struct on multiple function each one write something on the struct but the various function should be no influence each other
In this case you should pass the struct as reference.
I need to use a struct on multiple function each one write something on the struct and the various function should be use the result of previous function
In this case you should pass the struct by pointer.
As you can see this approach avoids to think about the "dimension" of the struct and focus on the use of the struct, I think this is a better approach because is not always easy to define the dimension of a struct.