I have two structs:
type person struct {
name string
age int
}
type class struct {
students []person
}
Lets say that in the main function, I create and populate two person variables and then I want to add them to a variable with class type. How can I do it?
I.e.
s := person{name: "Sean", age: 50}
t := person{name: "Nicola", age: 35}
how I can put s and t into:
lab:=class ?
The following should achieve what you want:
lab := class{[]person{s, t}}
Test it here.
Before you continue working on your project it's strongly recommended you read the following:
http://tour.golang.org/ (As Volker pointed out before me in the comments)
http://golang.org/doc/effective_go.html (After finishing the tour)
Related
I have an array of animal names in the order that I intend to create each struct 'animal' and store it in farm_animals, a struct of animals.
typedef struct ani animal;
animal* farm_animals[128] = {0};
Although the below code is totally invalid, I have included it here to show exactly what I have thought of achieving in practice. I want to declare a variable of type animal corresponding to a string literal in the array, and then somehow use that literal as the name of the animal and store it in an array.
char* animal_names [] = {"Oliver", "Marcus", "Mike", "John", "Tom", "Daisy", "Lilac", "Rose", "Jim"};
for (int i = 0; i < 9; i++) {
animal animal_names[i];
farm_animals[i] = animal_names[i];
}
I have researched and found many other similar posts which conclude that since C is a compiled not interpreted language, it is not possible to name a variable with the value of a string. However, I was wondering if it is possible to concatenate the string name with a suffix (like the index number) to create an entirely new 'string name' to refer to the animal. I have also though of a macro using an array or the same animal_names array, but this has not been clear for me to implement as a beginner.
I think this sort of idea in C is far-fetched, but I really wonder if there is a way to name these structs using a for loop and array of names, rather than manually creating 100+ structs.
Yes, it is not possible to dynamically name variables in C. If I understand correctly, you want to create an animal type corresponding to a string and then name it that name.
The advantage with using structs is that you can combine related/relevant data into a single variable (the struct) – which itself is a collection of multiple variables.
I would suggest organizing something like this:
typedef struct animal {
char[20] name;
char[20] type;
} animal;
You can replace the character array with a pointer to the string (char*) as well. Also, if you know the type of animals that could be created you can instead create an enum like this:
#define MAX_NAME_LEN 20
#define MAX_NUM_ANIMALS 10
enum animalType {
LION,
ELEPHANT,
FALCON,
PARROT
};
typedef struct animal {
char[MAX_NAME_LEN] name;
enum animalType type;
} animal;
int main(void) {
animal listOfAnimals[MAX_NUM_ANIMALS];
listOfAnimals[0].type = PARROT;
listOfAnimals[0].name = "my parrot";
return 0;
}
So, instead of making 100+ structs, you would make an array of structs and store the type of animal as a data member. Then you could use some mapping mechanism or conditional logic to assign these types to the struct variables as per your needs.
How would I change the position of the json values?
What Im trying to achieve:
[{"key":"f","value":"f"},{"value":"f","key":"f"}]
Problem:
type Struct struct {
Key string `json:"key"`
Value string `json:"value"`
}
func main() {
test := []Struct{ {Key: "test",Value: "wep"}, {Value: "wep",Key: "test"}}
bytes, _ := json.Marshal(test)
fmt.Print(string(bytes))
}
Running this code prints [{"key":"test","value":"wep"},{"key":"test","value":"wep"}]
I have also tried doing something like this but it just printed empty values
type Struct struct {
Key string `json:"key"`
Value string `json:"value"`
Value2 string `json:"value"`
Key2 string `json:"key"`
}
But how would I be able to switch the position of the key and value field around?
type StructA struct {
Key string `json:"key"`
Value string `json:"value"`
}
type StructB struct {
Value string `json:"value"`
Key string `json:"key"`
}
func main() {
test := []interface{}{
StructA{Key: "test", Value: "wep"},
StructB{Value: "wep", Key: "test"},
}
bytes, _ := json.Marshal(test)
fmt.Print(string(bytes))
}
https://play.golang.org/p/72TWDU1BMaL
If you're using json.Marshal provided by official package it's not passible to do that. In stead, you can implement your own MarhalJSON method so that you can decide the position of your struct fields.
To the question "can I make a single struct type serialize its fields in a different order or different occasions ?" :
there isn't a simple way to do this.
Regarding struct fields : the code you write shows the assigning operations in a given order, but once your code is compiled, there is no trace of that order anymore.
If you really need this (side note : I would be curious to know about your use case ?), you could create a custom type, with its own .MarshalJSON() method, which would hold a value indicating "fields should be serialized in this order".
If what you need is to send an array of heterogeneous objects, use separate struct types, and an []interface{} array :
type Obj1 struct{
Key string `json:"name"`
Value string `json:"value"`
}
type Obj2 struct{
Value string `json:"value"`
Key string `json:"name"`
}
func main() {
test := []interface{}{ Obj1{Key: "test",Value: "wep"}, Obj2{Value: "wep",Key: "test"}}
bytes, _ := json.Marshal(test)
fmt.Print(string(bytes))
}
https://play.golang.org/p/TOk28gL0eSK
type Person struct {
ID int `json:"id"`
}
type PersonInfo []Person
type PersonInfo2 []struct {
ID int `json:"id"`
}
Is there have difference between PersonInfo (named slice of named structs) and PersonInfo2 (named slice of unnamed structs)
The main difference is how you have to initialize Person objects outside of the PersonInfo/PersonInfo2 initialization. Since PersonInfo2 is an array of the anonymous struct type we know nothing about this type outside of the PersonInfo2 initialization.
So they can both be initialized like this:
m := PersonInfo{{1}, {2}}
n := PersonInfo2{{1},{2}}
However if we want to append an element of the anonymous struct type we would have to specify the full type:
append(n, struct { ID int `json:"id"` }{3})
If we print these out we can see they appear to be the same:
fmt.Printf("%+v\n%+v", m, n)
Outputs:
[{ID:1} {ID:2}]
[{ID:1} {ID:2}]
However they wont be deeply equal because PersonInfo is an array of type Person and PersonInfo2 is an array of anonymous struct type. So the following:
if !reflect.DeepEqual(m,n) {
print("Not Equal")
}
will print "Not Equal".
Here is a link to see for yourself.
When appending to PersonInfo2 we have to repeat the anonymous struct type for every value we want to append, it is probably better to use PersonInfo as an array of type Person.
Go is using structural typing, that means, as long as the two types have the same underlying type, they are equivalent.
So, for your question: Person and struct{ ID int 'json:"id"'} is equivalent because they have the same underlying type, and therefore, PersonInfo and PersonInfo2 are also equivalent. I took of the json tags to simplify the example.
person1 := Person{1}
pStruct1 := struct{ID int}{2}
pInfo1 := PersonInfo{
person1,
pStruct1,
}
pInfo2 := PersonInfo2{
person1,
pStruct1,
}
fmt.Printf("%+v\n", pInfo1)
fmt.Printf("%+v", pInfo2);
//outputs
//PersonInfo: [{ID:1} {ID:2}]
//PersonInfo2: [{ID:1} {ID:2}]
Code example: https://play.golang.org/p/_wlm_Yfdy2
type PersonInfo is an object of Person, while PersonInfo2 is a class (or type in Golang) by itself. Even though their data structure is similar.
So, when you run DeepEqual() to check the similarity it will turn out to be false.
Example by previous comment:
if !reflect.DeepEqual(m,n) {
print("Not Equal")
}
Hope this helps.
Assume I have an array of structs like so:
struct Record {
let name: String
}
let array = [Record(name: "John"), Record(name: "Jim"), Record(name: "Bob")]
I would like to get the index of each element using UILocalizedIndexedCollation.section(for: collationStringSelector:). The problem is, when I pass:
#selector(getter: record.name)
the following error is returned:
Argument of '#selector' refers to var 'name' that is not exposed to
Objective-C
Is there any way of exposing an instance value in a struct to a #selector? (NB: the struct I am passing is used extensively throughout my app and I don't really want to change it to a class)
Converting the struct variable to an NSString and using one of NSString's methods / variables is a work around that fixed the issue:
let index = UILocalizedIndexedCollation.current().section(for: (record.name as NSString), collationStringSelector: #selector(getter: NSString.uppercased))
I write a program which will analyze code in pascal. I've finished work with text and now I have to save my results in linked lists and I have any concept how to do it. In my program I have following elements:
variables(name, type)
constants(name)
typedef(name and components)
procedures(local variables, constants and types)
function (its var, const and types)
To my mind creating 5 lists won't be efficient solution. Can you give me a tip how to create list for these elements with different quantity of components?
Thanks a lot
It depends on what you mean by "efficient".
If you want to have all the different elements in the same list, you will need to add type information to the elements, and of course spend time filtering out all the wrong elements when looking for something.
It would seem more efficient, then, to have separate collections of various types of element.
You should do something like:
typedef struct Element Element;
struct Element {
Element *next;
};
typedef struct {
char *name;
VariableType type;
} ElementVariable;
/* ... and so on */
Then you can have various linked list headers:
ElementVariable *variables;
ElementConstant *constants;
Since each ElementXXX type begins with an Element, you can write fairly generic linked-list code to deal with all the different types.
I don't know exactly what you want to do with the lists, but here's an idea: Create a tree where siblings act like the regular next item in the liked list and where children provide additional information like entries of compound types or function parameters.
So the struct would look something like this:
struct Entity {
const char *id;
enum Type type;
char is_const;
char is_var;
/* ... whatever ... */
struct Entity *next;
struct Entity *child;
};
So if you have
var x: integer;
procedure proc(var res: integer, x, y: integer); forward;
type date = record
dd, mm, yy: integer;;
end;
your tree would look like this:
[var x: integer]
|
[proc: procedure] -> [var res: integer]
| |
| [x: integer]
| |
| [y: integer]
|
[type date: record] -> [dd: integer]
|
[mm: integer]
|
[yy: integer]
Here, the arrow -> denotes children and the vertical bar | siblings or just the next item in the list.
The elements at the left form your primary list, that include your first-level (global scope) symbols. The next level means the scope of the parent element. For example dd is only known inside the record date. This is essentially a multi-level linked list that is easy to expand for arbitrary numbers of function arguments or record entries.
5 lists aren't necessarily inefficient unless you want to search them all for a name, or something.
An alternative is to make a generic way of storing all your info in one list. You could enumerate what you're storing.