Go - get parent struct - go

I'd like to know how to retrieve the parent struct of an instance.
I have no idea how to implement this.
For instance:
type Hood struct {
name string
houses []House
}
type House struct {
name string
people int16
}
func (h *Hood) addHouse(house House) []House {
h.houses = append(h.houses, house)
return h.houses
}
func (house *House) GetHood() Hood {
//Get hood where the house is situated
return ...?
}
Cheers

You should retain a pointer to the hood.
type House struct {
hood *Hood
name string
people int16
}
and when you append the house
func (h *Hood) addHouse(house House) []House {
house.hood = h
h.houses = append(h.houses, house)
return h.houses
}
then you can easily change the GetHood, although a getter may not be required at that point.
func (house *House) GetHood() Hood {
return *house.hood
}

Related

How to define generic function with custom structs without listing all of them?

Let's say I have two different structs:
type One struct {
Id string
// Other fields
}
type Two struct {
Id string
// Other fields
}
Is it possible to define a function that accepts both One and Two without explicitly listing them as options?
E.g. I am looking for something like this:
type ModelWithId struct {
Id string
}
func Test[M ModelWithId](m M) {
fmt.PrintLn(m.Id)
}
one := One { Id: "1" }
Test(one) // Prints 1
I don't want to use funcTest[M One | Two](m M), because I'll likely have 10+ structs and I don't want to come back to the function every time I add a new struct to the codebase.
Generics constraints the type parameter behaviours using methods, so you need to rewrite your code as:
type One struct {
id string
}
func (o *One) Id() string {
return o.id
}
then your use site would become:
type ModelWithId interface {
Id() string
}
func Test[M ModelWithId](m M) {
fmt.Println(m.Id())
}

Method taking interface as a parameter inside interface

I am declcaring an interface in go
type comparable interface {
GetKey() float32
Compare(comparable) int
}
and implementing this interface by creating this structure
type Note struct {
id int
text string
priority float32
}
func (note Note) GetKey() float32 {
return note.priority
}
func (note Note) Compare(note2 Note) int {
if note.priority < note2.priority {
return -1
} else if note.priority > note2.priority {
return 1
} else {
return 0
}
}
But when I am passing note object into a function which accepts comparable interface as a parameter I am getting "Wrong type for method compare" error.
Am I missing something or doing something wrong? Please help
Thanks in advance
You are not implementing comparable since you use Note in compare method not comparable. Compare(note2 Note) is not same as Compare(comparable).
Use comparable in Compare method to implement comaprable interface
func (note Note) Compare(note2 comparable) int {
if note.GetKey()< note2.GetKey() {
return -1
} else if note.GetKey()> note2.GetKey() {
return 1
} else {
return 0
}
}
You declared comparable as having a method with signature Compare(comparable) int.
So func (note Note) Compare(note2 Note) ought to be func (note Note) Compare(note2 comparable), to match the interface.
Otherwise, you're not implementing the same interface. To implement comparable, your Compare method needs to take any comparable, but the one you declared for Note takes only Note, and not any comparable. It's a different method.
Here's a modified-to-work, minimal example based on your code: https://play.golang.org/p/ajH1s5gbGcQ

Instantiation of complex struct

I created a struct in a file called availability.go
package restconsume
import (
)
// Availabilityrequest for sabre
type Availabilityrequest struct {
OTAAirLowFareSearchRQ struct {
OriginDestinationInformation []struct {
DepartureDateTime string `json:"DepartureDateTime"`
DestinationLocation struct {
LocationCode string `json:"LocationCode"`
} `json:"DestinationLocation"`
OriginLocation struct {
LocationCode string `json:"LocationCode"`
} `json:"OriginLocation"`
RPH string `json:"RPH"`
} `json:"OriginDestinationInformation"`
POS struct {
Source []struct {
PseudoCityCode string `json:"PseudoCityCode" default:"F9CE"`
RequestorID struct {
CompanyName struct {
Code string `json:"Code" default:"TN"`
} `json:"CompanyName"`
ID string `json:"ID" default:"1"`
Type string `json:"Type" default:"1"`
} `json:"RequestorID"`
} `json:"Source"`
} `json:"POS"`
TPAExtensions struct {
IntelliSellTransaction struct {
RequestType struct {
Name string `json:"Name" default:"200ITINS"`
} `json:"RequestType"`
} `json:"IntelliSellTransaction"`
} `json:"TPA_Extensions"`
TravelPreferences struct {
TPAExtensions struct {
DataSources struct {
ATPCO string `json:"ATPCO" default:"Enable"`
LCC string `json:"LCC" default:"Disable"`
NDC string `json:"NDC" default:"Disable"`
} `json:"DataSources"`
NumTrips struct {
} `json:"NumTrips"`
} `json:"TPA_Extensions"`
} `json:"TravelPreferences"`
TravelerInfoSummary struct {
AirTravelerAvail []struct {
PassengerTypeQuantity []struct {
Code string `json:"Code"`
Quantity int `json:"Quantity"`
} `json:"PassengerTypeQuantity"`
} `json:"AirTravelerAvail"`
SeatsRequested []int `json:"SeatsRequested" default:"1"`
} `json:"TravelerInfoSummary"`
Version string `json:"Version" default:"1"`
} `json:"OTA_AirLowFareSearchRQ"`
}
// AddADepartureDate to set the date you leave
func (a *Availabilityrequest) AddADepartureDate() Availabilityrequest {
a.OTAAirLowFareSearchRQ.OriginDestinationInformation[0].DepartureDateTime = "2020-03-21"
return *a
}
//AddOriginDestination to set the ori and dest
func (a *Availabilityrequest) AddOriginDestination(Origin ,Destination string) {
a.OTAAirLowFareSearchRQ.OriginDestinationInformation[0].DestinationLocation.LocationCode = Destination
a.OTAAirLowFareSearchRQ.OriginDestinationInformation[0].OriginLocation.LocationCode = Origin
}
Now I've imported this package into my main one and having issue instatntiating with only one substruct(TPAExtensions)
main.go
package main
import (
"restconsume"
"fmt"
)
func main() {
var a= new(restconsume.Availabilityrequest)
a = Availabilityrequest{
"OTA_AirLowFareSearchRQ":OTAAirLowFareSearchRQ{
"IntelliSellTransaction": IntelliSellTransaction{
"RequestType": RequestType{
"Name": "200ITINS"},
},
},
}
}
error message
undefined: Availabilityrequest
My question is how could I instantiate this kind of complex struct?
The simplest answer is to not try to use struct literal but rather have a variable of the top-level type to be initialized to an appropriate zero value for its type and then explicitly set only those fields which are needed, like this:
var a Availabilityrequest
a.OTAAirLowFareSearchRQ.TPAExtensions.IntelliSellTransaction.RequestType.Name = "200ITINS"
But honestly, judging from your question, it looks like you're JavaScript programmer trying to attack Go without much prior knowledge about that language. This is a path to suffering.
Please be advised to at least start with the Tour of Go and then read any introductory-level book on Go (I would recommend this one).
"Effective Go" is also a must.

Append to struct slice in golang

I tried hard to find example as mine, but although bunch of questions are very similar, I wasnt able to understand what I am doing wrong.
I am very new to golang, and I am trying to implement game of life.
here is part of my code
// Species struct
type Species struct {
xPos int32
yPos int32
isAlive bool
willChangeState bool
rect sdl.Rect
neighbours []Species
}
type Ecosystem struct {
community []Species
}
func (ecos *Ecosystem) addSpecies(sp Species) {
ecos.community = append(ecos.community, sp)
}
func (s *Species) addNeigbour(neigbour Species) {
s.neighbours = append(s.neighbours, neigbour)
}
I want to distribute neighbours as in this function
func (ecos *Ecosystem) distributeNeighbours() {
for _, species := range ecos.community {
for _, potentionalNeighbour := range ecos.community {
if math.Abs(float64(species.xPos-potentionalNeighbour.xPos)) <= speciesSize && math.Abs(float64(species.yPos-potentionalNeighbour.yPos)) <= speciesSize {
if species.xPos == potentionalNeighbour.xPos && species.yPos == potentionalNeighbour.yPos {
continue
}
species.addNeigbour(potentionalNeighbour)
}
}
fmt.Println(len(species.neighbours)) // works here
}
for _, s := range ecos.community {
fmt.Println(len(s.neighbours)) //prints 0
}
}
So I guess I have to manage it with pointers - some issue like species in first loop is copy of that species in community, so original species does not gain any neigbours. But I dont know how to fix it.
Try slice of pointer, like this:
// Species struct
type Species struct {
xPos int32
yPos int32
isAlive bool
willChangeState bool
rect sdl.Rect
neighbours []*Species
}
type Ecosystem struct {
community []*Species
}

How in Swift specify type constraint to be enum?

I want to specify a type constraint that the type should be a raw value enum:
enum SomeEnum: Int {
case One, Two, Three
}
class SomeProtocol<E: enum<Int>> { // <- won't compile
func doSomething(e: E) {
compute(e.toRaw())
}
}
How can I do it in Swift? (I used the F# syntax for example)
enum SomeEnum: Int {
case One, Two, Three
}
class SomeClass<E: RawRepresentable where E.RawValue == Int>{
func doSomething(e: E) {
print(e.rawValue)
}
}
class SomeEnumClass : SomeClass<SomeEnum> {
}
or directly
class SomeOtherClass{
func doSomething<E: RawRepresentable where E.RawValue == Int>(e: E) {
print(e.rawValue)
}
}
UPDATE for swift3:
enum SomeEnum: Int {
case One, Two, Three
}
class SomeClass<E: RawRepresentable> where E.RawValue == Int {
func doSomething(e: E) {
print(e.rawValue)
}
}
class SomeEnumClass : SomeClass<SomeEnum> {
}
resp.
class SomeOtherClass{
func doSomething<E: RawRepresentable>(e: E) where E.RawValue == Int {
print(e.rawValue)
}
}
While you can place enums into a generic type without contraints (<T>), it's not possible to create constraints for all enums or all structs. All the constraints are based on interfaces (subclassing, protocols). Unfortunately, there is nothing in common between two random structs or two random enums.
Structs and enums can't inherit from other structs/enums so the only constraints for enums must be based on protocols.
protocol EnumProtocol {
func method()
}
enum TestEnum : Int, EnumProtocol {
case A
case B
func method() {
}
}
enum TestEnum2 : Int, EnumProtocol {
case C
func method() {
}
}
class EnumGeneric <T : EnumProtocol> {
func method(a: T) {
a.method()
}
}
let test = EnumGeneric<TestEnum>()
test.method(TestEnum.A)
Also note that all enums "inheriting" from a primitive type like Int conform to RawRepresentable, so you could
class EnumGeneric <T : RawRepresentable> {
func method(a: T) {
println("\(a.toRaw())");
}
}
but that won't work for enums declared as enum TestEnum {
AFAIK, Swift does not support type constraint to be specified with enums.
Cited from Swift Manual
Type Constraint Syntax
You write type constraints by placing a single class or protocol
constraint after a type parameter’s name, separated by a colon, as
part of the type parameter list. The basic syntax for type constraints
on a generic function is shown below (although the syntax is the same
for generic types):
Strictly limited to a class or protocol unless there's some hidden features which is not mentioned in manual. As far as I tested, struct or enum are all prohibited by the compiler.
enum Test1 : Int
{
case AAA = 0
}
func test1f<T:Test1>(a: Test1) {} // error: Inheritance from non-protocol, non-class type 'Test1'
struct Test2
{
var aaa:Int = 0
}
func test2f<T:Test2>(a: Test2) {} // error: Inheritance from non-protocol, non-class type 'Test1'
class Test3
{
}
func test3f<T:Test3>(a: Test3) {} // OK

Resources