Assuming, that I have a Graph struct, like so:
type Graph struct {
nodes []int
adjList map[int][]int
}
// some methods on the struct
// constructor
func New() *Graph {
g := new(Graph)
g.adjList = make(map[int][]int)
return g
}
Now, I create a new instance of that struct, with: aGraph := New().
How do I access the fields of this particular instance of the Graph struct (aGraph)?
In other words, how do I access aGraph's version of the nodes array, (from within another top-level function for example)?
Any help is extremely appreciated!
Here is one example:
package main
import (
"fmt"
)
// example struct
type Graph struct {
nodes []int
adjList map[int][]int
}
func New() *Graph {
g := new(Graph)
g.adjList = make(map[int][]int)
return g
}
func main() {
aGraph := New()
aGraph.nodes = []int {1,2,3}
aGraph.adjList[0] = []int{1990,1991,1992}
aGraph.adjList[1] = []int{1890,1891,1892}
aGraph.adjList[2] = []int{1890,1891,1892}
fmt.Println(aGraph)
}
Output:&{[1 2 3 4 5] map[0:[1990 1991 1992] 1:[1890 1891 1892] 2:[1790 1791 1792]]}
Related
I have been using Petgraph recently to make simple graphs with Structs for nodes and custom edges, but I have come across a problem which I am unsure if it comes from the library or Rust.
I have a graph, in which I have multiple nodes, each nodes have a name. I then put all of the index of the node (with type NodeIndex) in a vector, since Petgraph doesn't have a function to give all the nodes from a graph. I want to then create a function that given a string, it returns the index of the node that matches the name.
My problem is that somehow the type in the vector containing the nodes seems to change. I store it as NodeIndex yet the types somehow change by themselves to u32 without me changing anything. Since it changes automatically, I can't pass the values inside Petgraph functions since they require NodeIndex as inputs and not u32.
The code following is what I have so far and the problem arises in the function find_node_index_with_name where the types seem to change even though I pass a vector of NodeIndex as input so when I iterate over it, I should also get NodeIndex back.
use petgraph::adj::NodeIndex;
use petgraph::stable_graph::StableGraph;
use petgraph::dot::Dot;
#[derive(Clone,Debug,Default)]
struct ControlBloc
{
name:String,
value:u32,
}
fn create_bloc(name:String,value:u32) -> ControlBloc
{
ControlBloc
{
name,
value,
}
}
fn find_node_index_with_name(gr:StableGraph<ControlBloc,u32> , nodes:Vec<NodeIndex> , name_search:String) -> Option<NodeIndex>
{
for i in 0..nodes.len()
{
if gr.node_weight(nodes[i]).unwrap().name == name_search
{
return nodes[i];
}
}
return None;
}
fn main() {
let mut graph = StableGraph::<ControlBloc,u32>::new();
let m = create_bloc(String::from("Main"),10);
let b1 = create_bloc(String::from("sub1"),20);
let b2 = create_bloc(String::from("sub2"),30);
let main = graph.add_node(m);
let sub1 = graph.add_node(b1);
let sub2 = graph.add_node(b2);
let all_nodes = vec![main,sub1,sub2];
println!("{:?}",find_node_index_with_name(graph, all_nodes, String::from("Main")));
}
I am a bit stumped as to why the types change.
Thank you for any inputs!
graph.add_node() returns a petgraph::graph::NodeIndex.
But you used petgraph::adj::NodeIndex which appears to be a different type (don't ask me why), thus the type mismatch.
I took the liberty to change a bit your code in order to use references where you used owned values.
use petgraph::graph::NodeIndex; // graph not adj
use petgraph::stable_graph::StableGraph;
#[derive(Clone, Debug, Default)]
struct ControlBloc {
name: String,
value: u32,
}
fn create_bloc(
name: String,
value: u32,
) -> ControlBloc {
ControlBloc { name, value }
}
fn find_node_index_with_name(
gr: &StableGraph<ControlBloc, u32>,
nodes: &[NodeIndex],
name_search: &str,
) -> Option<NodeIndex> {
nodes
.iter()
.map(|n| *n)
.find(|n| gr.node_weight(*n).unwrap().name == name_search)
/*
for i in 0..nodes.len() {
if gr.node_weight(nodes[i]).unwrap().name == name_search {
return Some(nodes[i]);
}
}
None
*/
}
fn main() {
let mut graph = StableGraph::<ControlBloc, u32>::new();
let m = create_bloc(String::from("Main"), 10);
let b1 = create_bloc(String::from("sub1"), 20);
let b2 = create_bloc(String::from("sub2"), 30);
let main = graph.add_node(m);
let sub1 = graph.add_node(b1);
let sub2 = graph.add_node(b2);
let all_nodes = vec![main, sub1, sub2];
for n in ["Main", "sub1", "sub2"] {
println!("{:?}", find_node_index_with_name(&graph, &all_nodes, n));
}
}
/*
Some(NodeIndex(0))
Some(NodeIndex(1))
Some(NodeIndex(2))
*/
I'd like to be able to have a sum type that is either of two enums' members but am not sure if I'm doing this correctly. The idea would be for Token to be either a Coordinate or AA and for the process_line to return an array of Tokens. Pretty basic. But do I have to wrap a Token(...) around every Coordinate or AA that I initialize for them to be such?
struct Coordinate {
x: f64,
y: f64,
z: f64
}
enum AminoAcid {
VAL, GLN ,ARG,
LEU, THR ,TYR,
SER, PRO ,CYS,
GLY, ALA ,MET
}
enum Token {
Coordinate(Coordinate),
AminoAcid(AminoAcid)
}
// Want a function that returns a list of legal tokens given a &line.
fn _process_line(line:&str)->Vec<Token>{
let token = Token::AminoAcid(AminoAcid::ARG);
return vec![token];
}
For example, in typescript I could do
type A = "Fur" | "Silver" | "Glass"
type B = "Leather" | "Wood" | "Bronze"
type Material = A | B;
var x: Material = "Wood" // is okay
whereas here I am having to do the whole Material("Wood") type of thing with
let token = Token::AminoAcid(AminoAcid::ARG);
let token = AminoAcid::ARG; // it would have been great to just have this, is this possible?
You can implement From for each inner type. By implementing it you can call Into::into on your inner types instances to get the outter enum representation:
struct Coordinate{
x:f64, y:f64, z:f64
}
enum AminoAcid {
VAL, GLN ,ARG,
LEU, THR ,TYR,
SER, PRO ,CYS,
GLY, ALA ,MET
}
enum Token {
Coordinate(Coordinate),
AminoAcid(AminoAcid)
}
impl From<Coordinate> for Token {
fn from(coord: Coordinate) -> Self {
Self::Coordinate(coord)
}
}
impl From<AminoAcid> for Token {
fn from(aminoacid: AminoAcid) -> Self {
Self::AminoAcid(aminoacid)
}
}
// Want a function that returns a list of legal tokens given a &line.
fn _process_line(line:&str)->Vec<Token>{
return vec![AminoAcid::ARG.into()];
}
Playground
How do I access field c inside struct of type B_ inside enum of type A in this case?
enum A {
B(B_),
D(D_)
}
enum D_ { D_1, D_2 }
struct B_ {
c: Vec<i32>,
}
Obvious stuff like this doesn't work:
let y = A::B;
y.c = Vec::new();
I think the first problem is that what you really want is y to be of type A, so it cannot have a field named c in the first place. y can be A::B or A::D. Only if y is an A::B variant, then you can get the B_ object inside the variant and then get the c.
The second problem in your code is that you are not initializing y to be an A::B variant. The expression A::B is of type fn(B_) -> A {A::B} which is a kind of constructor function (automagically generated by the compiler) for A enums.
The following code initialize y correctly and get c:
enum A {
B(B_),
D(D_)
}
enum D_ { D_1, D_2 }
struct B_ {
c: Vec<i32>,
}
fn main() {
let y = A::B( B_ { c : Vec::new() });
// Check if y is an A::B, so we can get the B_ object inside
// by deconstruction. Then we can get c.
if let A::B(b_) = y {
println!("{:?}", b_.c);
}
}
Maybe you thought that A::B is a kind of B type defined "inside" A, which is not how enums work is Rust.
I am new to Go (coming from python) and I am having a bit of a hard time here. I am trying to allow any type of slice into my struct/func and it just contains a count of the length of that slice.
import "go/types"
type Response struct {
Count int `json:"count"`
Results []types.Struct `json:"results`
}
func NewResponse(results []types.Struct) (r *Response) {
r.Count = len(results)
r.Results = results
return
}
you can use interface{} as any type.
type Response struct {
Count int `json:"count"`
Results []interface{} `json:"results`
}
UPDATE
len(rsp.results) should work.
http://play.golang.org/p/RA2zVzWl2q
Arbitrary types are totally legit in Go. In your case, it might be appropriate to use []interface{} as the type of Results. When ever the types need to be known, use type switch.
package main
import (
"fmt"
)
type Response struct {
Count int `json:"count"`
Results []interface{} `json:"results`
}
func NewResponse(results []interface{}) (r *Response) {
r.Count = len(results)
r.Results = results
return
}
func AssertResultType(results []interface{}) {
for _, v := range results {
switch v := v.(type) {
default:
fmt.Printf("unexpected type %T\n", v) //t has unexpected type
case bool:
fmt.Printf("boolean %t\n", v) // t has type bool
case int:
fmt.Printf("integer %d\n", v) // t has type int
case string:
fmt.Printf("string %q\n", v) // t has type string
}
}
}
func main() {
args := []interface{}{1, "hello", true, "foo", 21}
r := NewResponse(args)
AssertResultType(r.Results)
}
In case of JSON, *json.RawMessage can be marshaled to type []byte
type Response struct {
Count int `json:"count"`
Results *json.RawMessage `json:"results`
}
type A struct {
B struct {
Some string
Len int
}
}
Simple question. How to initialize this struct? I would like to do something like this:
a := &A{B:{Some: "xxx", Len: 3}}
Expectedly I'm getting an error:
missing type in composite literal
Sure, I can create a separated struct B and initialize it this way:
type Btype struct {
Some string
Len int
}
type A struct {
B Btype
}
a := &A{B:Btype{Some: "xxx", Len: 3}}
But it not so useful than the first way. Is there a shortcut to initialize anonymous structure?
The assignability rules are forgiving for anonymous types which leads to another possibility where you can retain the original definition of A while allowing short composite literals of that type to be written. If you really insist on an anonymous type for the B field, I would probably write something like:
package main
import "fmt"
type (
A struct {
B struct {
Some string
Len int
}
}
b struct {
Some string
Len int
}
)
func main() {
a := &A{b{"xxx", 3}}
fmt.Printf("%#v\n", a)
}
Playground
Output
&main.A{B:struct { Some string; Len int }{Some:"xxx", Len:3}}
do it this way:
type Config struct {
Element struct {
Name string
ConfigPaths []string
}
}
config = Config{}
config.Element.Name = "foo"
config.Element.ConfigPaths = []string{"blah"}
This is simpler imo:
type A struct {
B struct {
Some string
Len int
}
}
a := A{
struct {
Some string
Len int
}{"xxx", 3},
}
fmt.Printf("%+v", a)