When should `new` be used in Go? - go

It seems pointless to be used in primitive language constructs, as you can't specify any sort of values
func main() {
y := new([]float)
fmt.Printf("Len = %d", len(*y) ) // => Len = 0
}
For stucts it makes a bit more sense, but what's the difference between saying y := new(my_stuct) and the seemingly more concise y := &my_struct?
And since anything you create is based on those primitives, they will be initialized to the said zero values. So what's the point? When would you ever want to use new()?
Sorry for the very-beginner question, but the documentation isn't always that clear.

You can't use new for slices and maps, as in your code example, but instead you must use the make command: make([]float, 100)
Both new(MyStruct) and &MyStruct{} do to the same thing, because Go will allocate values on the heap if you get their address with &. Sometimes the code just expresses it intent better in one style or the other.
Go does not have built-in support for constructors, so usually you would wrap the call to new into a function, for example NewMyStruct() which does all the necessary initialization. It also makes it possible to initialize private fields or hide the struct behind an interface, to prevent users of the object from directly messing with its internals. Also evolving the structure of the struct is easier that way, when you don't need to change all of its users when adding/removing/renaming/reordering fields.

make does only work for maps, slices and channels and composite literals like type{} work only for structs, arrays, slices, and maps. For other types, you'll have to use new to get a pointer to a newly allocated instance (if you don't want to use a longer var v T; f(&v)).
I guess this is useful if you want to initialize a struct:
typedef foo struct {
bar *int
}
v := foo{bar: new(int)}

Related

How to get a pointer to the underlying value of an Interface{} in Go

I'm interfacing with C code in Go using cgo, and I need to call a C function with a pointer to the underlying value in an Interface{} object. The value will be any of the atomic primitive types (not including complex64/complex128), or string.
I was hoping I'd be able to do something like this to get the address of ptr as an unsafe.Pointer:
unsafe.Pointer(reflect.ValueOf(ptr).UnsafeAddr())
But this results in a panic due to the value being unaddressable.
A similar question to this is Take address of value inside an interface, but this question is different, as in this case it is known that the value will always be one of the types specified above (which will be at most 64 bits), and I only need to give this value to a C function. Note that there are multiple C functions, and the one that will be called varies based off of a different unrelated parameter.
I also tried to solve this using a type switch statement, however I found myself unable to get the address of the values even after the type assertion was done. I was able to assign the values to temporary copies, then get the address of those copies, but I'd rather avoid making these copies if possible.
interface{} has own struct:
type eface struct {
typ *rtype
val unsafe.Pointer
}
You have no access to rtype directly or by linking, on the other hand, even though you'll copy whole rtype, it may be changed (deprecated) at future.
But thing is that you can replace pointer types with unsafe.Pointer (it may be anything else with same size, but pointer is much idiomatic, because each type has own pointer):
type eface struct {
typ, val unsafe.Pointer
}
So, now we can get value contained in eface:
func some_func(arg interface{}) {
passed_value := (*eface)(unsafe.Pointer(&arg)).val
*(*byte)(passed_value) = 'b'
}
some_var := byte('a')
fmt.Println(string(some_var)) // 'a'
some_func(some_var)
fmt.Println(string(some_var)) // 'a', it didn't changed, just because it was copied
some_func(&some_var)
fmt.Println(string(some_var)) // 'b'
You also might see some more usages at my repo:
https://github.com/LaevusDexter/fast-cast
Sorry for my poor English.

Express function that takes any slice

I want to express a function that can take any slice. I thought that I could do this:
func myFunc(list []interface{}) {
for _, i := range list {
...
some_other_fun(i)
...
}
}
where some_other_fun(..) itself takes an interface{} type. However, this doesn't work because you can't pass []DEFINITE_TYPE as []interface{}. See: https://golang.org/doc/faq#convert_slice_of_interface which notes that the representation of an []interface{} is different. This answer sums up why but with respect to pointers to interfaces instead of slices of interfaces, but the reason is the same: Why can't I assign a *Struct to an *Interface?.
The suggestion provided at the golang.org link above suggests rebuilding a new interface slice from the DEFINITE_TYPE slice. However, this is not practical to do everywhere in the code that I want to call this function (This function is itself meant to abbreviate only 9 lines of code, but those 9 lines appear quite frequently in our code).
In every case that I want to invoke the function I would be passing a []*DEFINITE_TYPE which I at first thought would be easier to abstract until, again, I discovered Why can't I assign a *Struct to an *Interface? (also linked above).
Further, everytime I want to invoke the function it is with a different DEFINITE_TYPE so implementing n examples for the n types would not save me any lines of code or make my code any clearer (quite the contrary!).
It is frustrating that I can't do this since the 9 lines are idiomatic in our code and a mistype could easily introduce a bug. I'm really missing generics. Is there really no way to do this?!!
In the case you provided, you would have to create your slice as a slice of interface e.g. s := []interface{}{}. At which point you could literally put any type you wanted into the slice (even mixing types). But then you would have to do all sorts of type assertions and everything gets really nasty.
Another technique that is commonly used by unmarshalers is a definition like this:
func myFunc(list interface{})
Because a slice fits an interface, you can indeed pass a regular slice into this. You would still need to do some validation and type assertions in myFunc, but you would be doing single assertions on the entire list type, instead of having to worry about a list that could possibly contain mixed types.
Either way, due to being a statically typed language, you eventually have to know the type that is passed in via assertions. It's just the way things are. In your case, I would probably use the func signature as above, then use a type switch to handle the different cases. See this document https://newfivefour.com/golang-interface-type-assertions-switch.html
So, something like this:
func myFunc(list interface{}) {
switch v := list.(type) {
case []string:
// do string thing
case []int32, []int64:
// do int thing
case []SomeCustomType:
// do SomeCustomType thing
default:
fmt.Println("unknown")
}
}
No there is no easy way to deal with it. Many people miss generics in Go.
Maybe you can get inspired by sort.Sort function and sort.Interface to find a reasonable solution that would not require copying slices.
Probably the best thing to do is to define an interface that encapsulates what myFunc needs to do with the slice (i.e., in your example, get the nth element). Then the argument to the function is that interface type and you define the interface method(s) for each type you want to pass to the function.
You can also do it with the reflect package, but that's probably not a great idea since it will panic if you pass something other than a slice (or array or string).
func myFunc(list interface{}) {
listVal := reflect.ValueOf(list)
for i := 0; i < listVal.Len(); i++ {
//...
some_other_fun(listVal.Index(i).Interface())
//...
}
}
See https://play.golang.org/p/TyzT3lBEjB.
Now with Go 1.18+, you can use the generics feature to do that:
func myFunc[T any](list []T) {
for _, item := range list {
doSomething(item)
}
}

Can I Use the Address of a returned value? [duplicate]

What's the cleanest way to handle a case such as this:
func a() string {
/* doesn't matter */
}
b *string = &a()
This generates the error:
cannot take the address of a()
My understanding is that Go automatically promotes a local variable to the heap if its address is taken. Here it's clear that the address of the return value is to be taken. What's an idiomatic way to handle this?
The address operator returns a pointer to something having a "home", e.g. a variable. The value of the expression in your code is "homeless". if you really need a *string, you'll have to do it in 2 steps:
tmp := a(); b := &tmp
Note that while there are completely valid use cases for *string, many times it's a mistake to use them. In Go string is a value type, but a cheap one to pass around (a pointer and an int). String's value is immutable, changing a *string changes where the "home" points to, not the string value, so in most cases *string is not needed at all.
See the relevant section of the Go language spec. & can only be used on:
Something that is addressable: variable, pointer indirection, slice indexing operation, field selector of an addressable struct, array indexing operation of an addressable array; OR
A composite literal
What you have is neither of those, so it doesn't work.
I'm not even sure what it would mean even if you could do it. Taking the address of the result of a function call? Usually, you pass a pointer of something to someone because you want them to be able to assign to the thing pointed to, and see the changes in the original variable. But the result of a function call is temporary; nobody else "sees" it unless you assign it to something first.
If the purpose of creating the pointer is to create something with a dynamic lifetime, similar to new() or taking the address of a composite literal, then you can assign the result of the function call to a variable and take the address of that.
In the end you are proposing that Go should allow you to take the address of any expression, for example:
i,j := 1,2
var p *int = &(i+j)
println(*p)
The current Go compiler prints the error: cannot take the address of i + j
In my opinion, allowing the programmer to take the address of any expression:
Doesn't seem to be very useful (that is: it seems to have very small probability of occurrence in actual Go programs).
It would complicate the compiler and the language spec.
It seems counterproductive to complicate the compiler and the spec for little gain.
I recently was tied up in knots about something similar.
First talking about strings in your example is a distraction, use a struct instead, re-writing it to something like:
func a() MyStruct {
/* doesn't matter */
}
var b *MyStruct = &a()
This won't compile because you can't take the address of a(). So do this:
func a() MyStruct {
/* doesn't matter */
}
tmpA := a()
var b *MyStruct = &tmpA
This will compile, but you've returned a MyStruct on the stack, allocated sufficient space on the heap to store a MyStruct, then copied the contents from the stack to the heap. If you want to avoid this, then write it like this:
func a2() *MyStruct {
/* doesn't matter as long as MyStruct is created on the heap (e.g. use 'new') */
}
var a *MyStruct = a2()
Copying is normally inexpensive, but those structs might be big. Even worse when you want to modify the struct and have it 'stick' you can't be copying then modifying the copies.
Anyway, it gets all the more fun when you're using a return type of interface{}. The interface{} can be the struct or a pointer to a struct. The same copying issue comes up.
You can't get the reference of the result directly when assigning to a new variable, but you have idiomatic way to do this without the use of a temporary variable (it's useless) by simply pre-declaring your "b" pointer - this is the real step you missed:
func a() string {
return "doesn't matter"
}
b := new(string) // b is a pointer to a blank string (the "zeroed" value)
*b = a() // b is now a pointer to the result of `a()`
*b is used to dereference the pointer and directly access the memory area which hold your data (on the heap, of course).
Play with the code: https://play.golang.org/p/VDhycPwRjK9
Yeah, it can be annoying when APIs require the use of *string inputs even though you’ll often want to pass literal strings to them.
For this I make a very tiny function:
// Return pointer version of string
func p(s string) *string {
return &s
}
and then instead of trying to call foo("hi") and getting the dreaded cannot use "hi" (type string) as type *string in argument to foo, I just wrap the argument in a call to to p():
foo(p("hi"))
a() doesn't point to a variable as it is on the stack. You can't point to the stack (why would you ?).
You can do that if you want
va := a()
b := &va
But what your really want to achieve is somewhat unclear.
At the time of writing this, none of the answers really explain the rationale for why this is the case.
Consider the following:
func main() {
m := map[int]int{}
val := 1
m[0] = val
v := &m[0] // won't compile, but let's assume it does
delete(m, 0)
fmt.Println(v)
}
If this code snippet actually compiled, what would v point to!? It's a dangling pointer since the underlying object has been deleted.
Given this, it seems like a reasonable restriction to disallow addressing temporaries
guess you need help from More effective Cpp ;-)
Temp obj and rvalue
“True temporary objects in C++ are invisible - they don't appear in your source code. They arise whenever a non-heap object is created but not named. Such unnamed objects usually arise in one of two situations: when implicit type conversions are applied to make function calls succeed and when functions return objects.”
And from Primer Plus
lvalue is a data object that can be referenced by address through user (named object). Non-lvalues include literal constants (aside from the quoted strings, which are represented by their addresses), expressions with multiple terms, such as (a + b).
In Go lang, string literal will be converted into StrucType object, which will be a non-addressable temp struct object. In this case, string literal cannot be referenced by address in Go.
Well, the last but not the least, one exception in go, you can take the address of the composite literal. OMG, what a mess.

map[T]struct{} and map[T]bool in golang

What's the difference? Is map[T]bool optimized to map[T]struct{}? Which is the best practice in Go?
Perhaps the best reason to use map[T]struct{} is that you don't have to answer the question "what does it mean if the value is false"?
From "The Go Programming Language":
The struct type with no fields is called the empty struct, written
struct{}. It has size zero and carries no information but may be
useful nonetheless. Some Go programmers use it instead of bool as the
value type of a map that represents a set, to emphasize that only the
keys are significant, but the space saving is marginal and the syntax
more cumbersome, so we generally avoid it.
If you use bool testing for presence in the "set" is slightly nicer since you can just say:
if mySet["something"] {
/* .. */
}
Difference is in memory requirements. Under the bonnet empty struct is not a pointer but a special value to save memory.
An empty struct is a struct type like any other. All the properties you are used to with normal structs apply equally to the empty struct. You can declare an array of structs{}s, but they of course consume no storage.
var x [100]struct{}
fmt.Println(unsafe.Sizeof(x)) // prints 0
If empty structs hold no data, it is not possible to determine if two struct{} values are different.
Considering the above statements it means that we may use them as method receivers.
type S struct{}
func (s *S) addr() { fmt.Printf("%p\n", s) }
func main() {
var a, b S
a.addr() // 0x1beeb0
b.addr() // 0x1beeb0
}

GoLang conventions - create custom type from slice

Is it a good idea to create own type from a slice in Golang?
Example:
type Trip struct {
From string
To string
Length int
}
type Trips []Trip // <-- is this a good idea?
func (trips *Trips) TotalLength() int {
ret := 0
for _, i := range *trips {
ret += i.Length
}
return ret
}
Is it somehow a convention in Golang to create types like Trips in my example? Or it is better to use []Trip in the whole project? Any pros and cons?
There's no convention, as far as I am aware of. It's OK to create a slice type if you really need it. In fact, if you ever want to sort your data, this is pretty much the only way: create a type and define the sort.Interface methods on it.
Also, in your example there is no need to take the address of Trips since slice is already a "fat pointer" of a kind. So you can simplify your method to:
func (trips Trips) TotalLength() (tl int) {
for _, l := range trips {
tl += l.Length
}
return tl
}
If this is what your type is (a slice), it's just fine. It gives you an easy access to underlying elements (and allows for range iteration) while providing additional methods.
Of course you probably should only keep essential set of methods on this type and not bloating it with everything that would take []Trip as an argument. (For example I would suggest having DrawTripsOnTheGlobe(t Trips) rather than having it as a Trips' method.)
To calm your mind there are plenty of such slice-types in standard packages:
http://golang.org/pkg/net/#IP
http://golang.org/pkg/sort/#Float64Slice
http://golang.org/pkg/sort/#IntSlice
http://golang.org/pkg/encoding/json/#RawMessage

Resources