Equals keyword ambiguity in golang documentation - go

I am having trouble understanding the Equals keyword in this context. Could someone explain whether it is a type or a function as I am not able to find docs for golang pertaining to this. https://github.com/ory/ladon/blob/9fada03c11c183e37c13f581ee6deca8d8e747f9/condition_string_equal.go#L19-L21

A struct is a user-defined type in golang having a group of fields. So in your case
type StringEqualCondition struct {
Equals string `json:"equals"`
}
StringEqualCondition is a struct having a field named Equals.
It's just a simple variable of type string in the struct.

It's not a keyword, is the variable (struct member, actually) name.
In golang, the format to declare a variable is name type. Thus, on that line, a member named Equals of type string is defined. The capital letter means public visibility.

This isn't the golang documentation, Equals is not a keyword, and it's not a type or a function in the code that you linked; it's the name of a struct field.

Related

cannot use address (type string) as type AccountAddress in assignment

I'm facing an issue while assignment of a string with a type of type AccountAddress [16]uint8.
type AccountAddress [16]uint8
address := c.Param("adress")
var account AccountAddress
account = address
Error cannot use address (type string) as type AccountAddress in assignment
Tried:
var account diemtypes.AccountAddress
account = []uint8(address)
Error cannot use ([]uint8)(address) (type []uint8) as type diemtypes.AccountAddress in assignment
Can anyone please help me in this.
Here you are confusing many basic things thing. Let me clear them on by one
In golang custom types are treated as separate types even both are defined with the same built-in type
For example
type StringType1 string
type StringType2 string
var name1 StringType1="Umar"
var name2 StringType2="Hayat"
fmt.Println("StringType1 : ", name1)
fmt.Println("StringType2 : ", name2)
The output of the above code is https://play.golang.org/p/QDcaM1IolbJ
StringType1 : Umar
StringType2 : Hayat
Here we have two custom types StringType1 and StringType2 both are defined by string`. But we can not assign a variable of these two types to each other directly until we convert them to the required type e.g
name1=name2
Output
cannot use name2 (type StringType2) as type StringType1 in assignment
Similar is the case with your code. You are converting a string to a custom type without applying conversion.
Second you are trying to convert a string to a byte array of fixed length 15 and type uint8. This can be done as mentioned by #Cerise Limon
copy(account[:], c.Param("adress"))
But keep one thing here in mind you are copying string to unit8 type so you should not expect characters in account instead it will be ASCI values of that string character. I hope it will clear all your miss conceptions.
A string can be implicitly converted to a []uint8, but this is a slice and [16]uint8 is an array. Those are distinct and incompatible types. However, you can copy the contents of the slice to an array using copy() function.
See an example here: https://play.golang.org/p/5zHg8Me-3KO

What is the advantage of using a pointer to a string instead of a string in Go [duplicate]

This question already has answers here:
What does the asterisk do in "Go"?
(6 answers)
Closed 5 years ago.
Reviewing some go code I came across this:
Person struct {
Name *string `json:"name"`
}
and then some where I saw:
Animal struct {
Name string `json:"name"`
}
What is the advantage of the pointer here?
The * declares a pointer type. A pointer to a string is sometimes used when decoding JSON to distinguish the following JSON:
JSON value of the Name field
{ } nil
{name: ""} pointer to ""
Without the pointer, it's not possible to distinguish a missing value from a blank value in the decoded result.
If the application does not need to make this distinction, then use the second form shown in the question. It's more convenient.
* means pointer.
In your case, Name is a field of type pointer to string.
See http://www.golang-book.com/books/intro/8
The * is a pointer.
A pointer type denotes the set of all pointers to variables of a given
type, called the base type of the pointer. The value of an
uninitialized pointer is nil.
This is coming from the Go Spec. I would suggest reading it all.

Why can methods in Go only be declared on types defined in the same package?

The Go Tour says the following:
You can only declare a method with a receiver whose type is defined in the same package as the method. You cannot declare a method with a receiver whose type is defined in another package (which includes the built-in types such as int).
Is there a reason for this other than avoiding everyone building their own methods off int and string? I've Googled around, but can't find anything referencing it.
The reason is that if you could define methods on other packages' types, you could modify the behavior of other packages. This is because the method set of a given type can have an effect on how values of that type are used.
Consider, for example, the fmt.Println function. When you pass an argument to fmt.Println, it will print a string representation of that value based on a set of rules. One of those rules is that if the type of the value has a String() string method (that is, it implements the fmt.Stringer interface), then that method will be called in order to obtain the string representation of the value.
Thus, imagine that we have a package, foo, and that package has a type, FooInt, defined as follows:
type FooInt int
Now imagine that this package also has a function, PrintFooInt:
func PrintFooInt(f FooInt) { fmt.Println(f) }
This will print the integer value of f. But let's say that you (in a different package, say main) were able to add methods to FooInt. Then you could do this:
func (f FooInt) String() string { return "foobar!" }
This would actually change the behavior of foo.PrintFooInt, which shouldn't be possible from outside the package.

Empty or not required struct fields

I have two structs that represent models that will be inserted into a mongodb database. One struct (Investment) has the other struct (Group) as one of its fields.
type Group struct {
Base
Name string `json:"name" bson"name"`
}
type Investment struct {
Base
Symbol string `json:"symbol" bson:"symbol" binding:"required"`
Group Group `json:"group" bson:"group"`
Fields bson.M `json:"fields" bson:"fields"`
}
The problem I'm having is that in the Investment model, Group is not required. If there is no group, I think its better for it to not be inserted in the db. Whats the best way to handle a db model such as this in Go?
tl;dr: Use ,omitempty, and if you need to worry about the difference between a zero value and null/not specified, do what the GitHub API does and use a pointer.
Both json and bson support the ,omitempty tag. For json, "empty values are false, 0, any nil pointer or interface value, and any array, slice, map, or string of length zero" (json docs). For bson, ,omitempty means "Only include the field if it's not set to the zero value for the type or to empty slices or maps", and zero values include empty strings and nil pointers (bson docs).
So if you really need a Group struct, you can put a *Group in instead, and it won't be stored when the pointer is nil. If Investment only needs to hold the group's name, it's even simpler: "" as group name keeps a group key from being stored.
bson defaults to using the lowercased field name already so you can omit that from the struct tag when they match. json will default to the Capitalized name, so specify the lowercase name in a tag if you need lowercase.
So, best case, maybe you can just use:
type Investment struct {
Base
Symbol string `json:"symbol" binding:"required"`
Group string `json:"group,omitempty" bson:",omitempty"`
Fields bson.M `json:"fields"`
}
If you ever run into fields where the zero value for the type ("", 0, false, etc.) is distinct from "not specified", you can do what the GitHub API does and put pointers in your structures--essentially an extension of the *Group trick.
Avoid strut fields to marshal if they are empty -
A struct field may be primitive type(string, int, bool etc) or even an another struct type.
So sometimes we don't want a struct's field to
go in json data(may to database insertion or in external api call) if they are empty
Example:
type Investment struct {
Base
Symbol string `json:"symbol" bson:"symbol" binding:"required"`
Group Group `json:"group" bson:"group"`
Fields bson.M `json:"fields" bson:"fields"`
}
If we want that Symbol and Group might contain empty values(0, false, nil pointer, zero size interface/struct) then we can avoid them in json marshaling like below.
type Investment struct {
Base
Symbol string `json:"symbol,omitempty" bson:"symbol,omitempty" binding:"required"`
Group *Group `json:"group,omitempty" bson:"group,omitempty"`
Fields bson.M `json:"fields" bson:"fields"`
}
Her "Group" field is pointer to Group struct and whenever it will point to nil pointer it will be omitted from json marshaling.
And obviously we would be filling values in Group field like below.
// declared investment variable of type Investment struct
investment.Group = &groupData

Strange type definition syntax in Golang (name, then type, then string literal)

I've been trying to find out how to use mgo (MongoDB driver for Go) and I came across this struct declaration:
type Something struct {
Id bson.ObjectId "_id,omitempty"
Name string
}
I don't quite understand the syntax of the first element (Id). I understand that it's being declared as type bson.ObjectId, but what is the string literal doing there?
My question is not about the mgo driver functionality,
but about this strange <name> <type> <string_literal> syntax.
I couldn't find anything on the Go specs, and I don't know how to google this either.
It's explained in the Struct types section of the language specification:
A field declaration may be followed by an optional string literal
tag, which becomes an attribute for all the fields in the corresponding field declaration. The tags are made visible through a
reflection interface but are otherwise ignored.
// A struct corresponding to the TimeStamp protocol buffer.
// The tag strings define the protocol buffer field numbers.
struct {
microsec uint64 "field 1"
serverIP6 uint64 "field 2"
process string "field 3"
}

Resources