Does type casting in go create a new variable? [duplicate] - go

Example:
type MyString string
var s = "very long string"
var ms = MyString(s)
var s2 = string(s)
Are ms or s2 a full copy of s (as it would be done with []byte(s))? Or they are just a string struct copies (which keeps the real value in a pointer)?
What if we are passing this to a function? E.g.:
func foo(s MyString){
...
}
foo(ms(s)) // do we copy s here?

Spec: Conversions:
Specific rules apply to (non-constant) conversions between numeric types or to and from a string type. These conversions may change the representation of x and incur a run-time cost. All other conversions only change the type but not the representation of x.
So converting to and from the underlying type of your custom type does not make a copy of it.
When you pass a value to a function or method, a copy is made and passed. If you pass a string to a function, only the structure describing the string will be copied and passed, since strings are immutable.
Same is true if you pass a slice (slices are also descriptors). Passing a slice will make a copy of the slice descriptor but it will refer to the same underlying array.

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

Struct type first line: _ struct{} [duplicate]

I am working with go, specifically QT bindings. However, I do not understand the use of leading underscores in the struct below. I am aware of the use of underscores in general but not this specific example.
type CustomLabel struct {
core.QObject
_ func() `constructor:"init"`
_ string `property:"text"`
}
Does it relate to the struct tags?
Those are called blank-fields because the blank identifier is used as the field name.
They cannot be referred to (just like any variable that has the blank identifier as its name) but they take part in the struct's memory layout. Usually and practically they are used as padding, to align subsequent fields to byte-positions (or memory-positions) that match layout of the data coming from (or going to) another system. The gain is that so these struct values (or rather their memory space) can be dumped or read simply and efficiently in one step.
#mkopriva's answer details what the specific use case from the question is for.
A word of warning: these blank fields as "type-annotations" should be used sparingly, as they add unnecessary overhead to all (!) values of such struct. These fields cannot be referred to, but they still require memory. If you add a blank field whose size is 8 bytes (e.g. int64), if you create a million elements, those 8 bytes will count a million times. As such, this is a "flawed" use of blank fields: the intention is to add meta info to the type itself (not to its instances), yet the cost is that all elements will require increased memory.
You might say then to use a type whose size is 0, such as struct{}. It's better, as if used in the right position (e.g. being the first field, for reasoning see Struct has different size if the field order is different and also Why position of `[0]byte` in the struct matters?), they won't change the struct's size. Still, code that use reflection to iterate over the struct's fields will still have to loop over these too, so it makes such code less efficient (typically all marshaling / unmarshaling process). Also, since now we can't use an arbitrary type, we lose the advantage of carrying a type information.
This last statement (about when using struct{} we lose the carried type information) can be circumvented. struct{} is not the only type with 0 size, all arrays with 0 length also have zero size (regardless of the actual element type). So we can retain the type information by using a 0-sized array of the type we'd like to incorporate, such as:
type CustomLabel struct {
_ [0]func() `constructor:"init"`
_ [0]string `property:"text"`
}
Now this CustomLabel type looks much better performance-wise as the type in question: its size is still 0. And it is still possible to access the array's element type using Type.Elem() like in this example:
type CustomLabel struct {
_ [0]func() `constructor:"init"`
_ [0]string `property:"text"`
}
func main() {
f := reflect.ValueOf(CustomLabel{}).Type().Field(0)
fmt.Println(f.Tag)
fmt.Println(f.Type)
fmt.Println(f.Type.Elem())
}
Output (try it on the Go Playground):
constructor:"init"
[0]func()
func()
For an overview of struct tags, read related question: What are the use(s) for tags in Go?
You can think of it as meta info of the type, it's not accessible through an instance of that type but can be accessed using reflect or go/ast. This gives the interested package/program some directives as to what to do with that type. For example based on those tags it could generate code using go:generate.
Considering that one of the tags says constructor:"init" and the field's type is func() it's highly probable that this is used with go:generate to generate an constructor function or initializer method named init for the type CustomLabel.
Here's an example of using reflect to get the "meta" info (although as I've already mentioned, the specific qt example is probably meant to be handled by go:generate).
type CustomLabel struct {
_ func() `constructor:"init"`
_ string `property:"text"`
}
fmt.Println(reflect.ValueOf(CustomLabel{}).Type().Field(0).Tag)
// constructor:"init"
fmt.Println(reflect.ValueOf(CustomLabel{}).Type().Field(0).Type)
// func()
https://play.golang.org/p/47yWG4U0uit

How to provide optional parameters in Go?

I'm coming from a Node.js background, and there a typical pattern is to have a function which takes an options object, i.e. an object where you set properties for optional parameters, such as:
foo({
bar: 23,
baz: 42
});
This is JavaScript's "equivalent" to optional and named parameters.
Now I have learnt that there are no optional parameters in Go, except variadic parameters, but they lack the readability of named parameters. So the usual pattern seems to be to hand over a struct.
OTOH a struct can not be defined with default values, so I need a function to set up the struct.
So I end up with:
Call a function that creates the struct and then fills it with default values.
Overwrite the values I would like to change.
Call the function I actually want to call and hand over the struct.
That's quite complicated and lengthy compared to JavaScript's solution.
Is this actually the idiomatic way of dealing with optional and named parameters in Go, or is there a simpler version?
Is there any way that you can take advantage of zero values? All data types get initialized to a zero value, so that is a form of default logic.
An options object is a pretty common idiom. The etcd client library has some examples (SetOptions,GetOptions,DeleteOptions) similar to the following.
type MyOptions struct {
Field1 int // zero value (default) of int is 0
Field2 string // zero value (default) of string is ""
}
func DoAction(arg1, arg2 string, options *MyOptions){
var defaultValue1 int = 30 // some reasonable default
var defaultValue2 string = "west" // some reasonable default
if options != nil {
defaultValue1 = options.Field1 // override with our values
defaultValue2 = options.Field2
}
doStuffWithValues
An relevant question (and very much in the mindset of Go) would be, do you need this kind of complexity? The flexibility is nice, but most things in the standard library try to only deal with 1 default piece of info/logic at a time to avoid this.

this code uses the address of type?

the code at https://code.google.com/p/goauth2/source/browse/oauth/oauth.go#99 declares this type:
package oauth
...
type Config struct {...}
...
the suggested use of this is following:
var config = &oauth.Config{...}
I do not understand why this code takes the address of this type and why this is even possible in Go. I am a newbie. I thought that types are for the compiler, no? Please help.
The Go Programming Language Specification
Composite literals
Composite literals construct values for structs, arrays, slices, and
maps and create a new value each time they are evaluated. They consist
of the type of the value followed by a brace-bound list of composite
elements. An element may be a single expression or a key-value pair.
Given the declaration
type Point3D struct { x, y, z float64 }
one may write
origin := Point3D{} // zero value for Point3D
Taking the address of a composite literal generates a pointer to a
unique instance of the literal's value.
var pointer *Point3D = &Point3D{y: 1000}
It's an example of the use of a pointer to a composite literal.
This is taking the address of a new instance of the Config type, not the address of the type itself.

Properly distinguish between not set (nil) and blank/empty value

Whats the correct way in go to distinguish between when a value in a struct was never set, or is just empty, for example, given the following:
type Organisation struct {
Category string
Code string
Name string
}
I need to know (for example) if the category was never set, or was saved as blank by the user, should I be doing this:
type Organisation struct {
Category *string
Code *string
Name *string
}
I also need to ensure I correctly persist either null or an empty string to the database
I'm still learning GO so it is entirely possible my question needs more info.
The zero value for a string is an empty string, and you can't distinguish between the two.
If you are using the database/sql package, and need to distinguish between NULL and empty strings, consider using the sql.NullString type. It is a simple struct that keeps track of the NULL state:
type NullString struct {
String string
Valid bool // Valid is true if String is not NULL
}
You can scan into this type and use it as a query parameter, and the package will handle the NULL state for you.
Google's protocol buffers (https://code.google.com/p/goprotobuf/) use pointers to describe optional fields.
The generated objects provide GetFoo methods which take the pain away from testing for nil (a.GetFoo() returns an empty string if a.Foo is nil, otherwise it returns *a.Foo).
It introduces a nuisance when you want to write literal structs (in tests, for example), because &"something" is not valid syntax to generate a pointer to a string, so you need a helper function (see, for example, the source code of the protocol buffer library for proto.String).
// String is a helper routine that allocates a new string value
// to store v and returns a pointer to it.
func String(v string) *string {
return &v
}
Overall, using pointers to represent optional fields is not without drawbacks, but it's certainly a viable design choice.
The standard database/sql package provides a NullString struct (members are just String string and Valid bool). To take care of some of the repetitive work of persistence, you could look at an object-relational manager like gorp.
I looked into whether there was some way to distinguish two kinds of empty string just out of curiosity, and couldn't find one. With []bytes, []byte{} == []byte(nil) currently returns false, but I'm not sure if the spec guarantees that to always remain true. In any case, it seems like the most practical thing to do is to go with the flow and use NullString.

Resources