I know structs are made for the purpose of being immutable but I don’t quietly understand the concept of “when we change a property in struct, the whole struct gets destroyed and created again” so now when we have a simple struct like:
`
enter code here`struct MyStruct { var num: Int }
var sample = MyStruct(num: 1)
var sample2 = sample
sample.num.address (unsafePointer) // address: 0x0000678ed8
Now if we change sample’s num property,
sanple.num = 2
Will its address in memory change? Or the struct just gets recreated at the ‘same’ address in memory? I’m really confused cause the address of properties do not change!!!
Related
I got the Example struct and where my is object allocated?
type Example struct {
field_a int
}
var ex Example = Example{10} // Stack's object or Heap ?
var ex Example = new(Example{10}) // Stack's object or Heap ?
Unlike C or C++, you don't know, golang abstracts the memory allocation.
Moreover, you cannot choose where the memory is allocated.
I am going on a project which process some data, I am wondering that if it is better to use pointer in non-primitive typed fields of struct.
What I've found is that the reason of using pointer is that nil can be used as a zero-value, is this the only reason to use pointer?
For example, I am going to store time.Time in my struct and it cannot be nil, then is it better to use non-pointer field?
So is it okay to use
type A struct {
CreatedAt time.Time
}
rather than
type A struct {
CreatedAt *time.Time
}
when Now is not going to be nil?
Not sure I understand the question. In the case of "Now" I would make it a function of the struct i.e.:
type A struct{}
func (a A) Now() time.Time { return time.Now(); }
otherwise what does Now mean? Now is constantly changing.
There are great blogs on when to use pointers
The short would be it doesn't really depend on if the value can be nil, but more on memory and concurrency. Pointers will be passed as references, so less memory, and faster, but also means that changing in one go routine can be very dangerous because the value could be referenced in another go routine and cause race conditions and unexpected behaviors.
I'm not really a professional or know the ins and outs of Go, so take everything I say with some grain of salt.
But as I am understanding it, you should most likely use pointers.
This is because every time you use a non-pointer type, the whole struct will be part of your struct in memory. As a consequence, you can't share a single instance of a struct between multiple structs - every single one gets a copy of your original struct.
Heres a small example:
// This struct has 2x64 bits in size
type MyStruct struct {
A uint64
B uint64
}
// This struct has 32 + 2x64 bits in size
type MyOtherStruct struct {
C uint32
Parent MyStruct
}
// This struct has 32 + the length of an address bits size
type MyPointerStruct struct {
D uint32
Parent *MyStruct
}
But apart from memory concerns, there is also a performance hit if your inner struct is very big. Because every time you set the inner struct the whole memory has to be copied to your instance.
However you have to be careful if your are dealing with interfaces or structs. At runtime, an interface is represented as a type with two fields: A reference to the actual (runtime) type and one with a reference to the actual instance.
So I - with my unprofessional opinion - would recommend to not use pointers if you have interface types because otherwise the CPU has to deference twice (once to get the interface reference, and then again to get the instance of the interface).
I need to store shared array inside a struct in UPC. Is it possible to do?
Struct fields cannot be shared-qualified, for the same reason they cannot be declared with static or extern - a struct field does not carry independent storage-class information (ie because the fields of a struct are always stored contiguously, and could be used for example to declare a stack variable).
However, a struct may contain an array field, and the struct can then be used to define a shared object, eg:
struct S {
int array[100];
int foo;
};
shared struct S data[THREADS];
...
data[MYTHREAD].array[0] = MYTHREAD;
However note the distribution of data in this example is one struct per thread, the array field is not independently distributed across threads.
A struct may also contain a pointer to a shared array, eg:
#include <upc.h>
struct R {
shared int *sa;
int bar;
};
...
struct R r;
r.sa = upc_all_alloc(THREADS, sizeof(int));
r.sa[MYTHREAD] = MYTHREAD;
in this case the shared array is distributed across threads, but the storage is not embedded in the struct - the struct field is just a pointer-to-shared (and thanks to C rules can be accessed with array syntax).
If I have a struct like this:
type Message struct {
Id int64
Message string
ReplyTo *int64
}
And then if I did create an instance of this struct like this:
var m Message
m.Id = 1
m.Message = "foo bar yo"
var replyTo = int64(64)
m.ReplyTo = &replyTo
Then it would work.
But I was wondering if there was a shortcut for the last step?
I tried doing something like:
m.ReplyTo = &int64{64}
But it did not work.
I don't think you can because the value is a primitive and attempting to do it in one shot like the below would be a syntax error. Its attempting to get an address of a value so it wouldn't be possible. At least I am not aware of a way where its possible.
someInt := &int64(10) // would not compile
The other alternative you have is to write a function to return a pointer to the primitive like the following:
func NewIntPointer(value int) *int {
return &value
}
A tricky way to get int pointer without create new variable.
someIntPtr := &[]int64{10}[0]
I am using this construct to simulate a set
type MyType uint8
map[MyType]interface{}
I then add in all my keys and map them to nil.
I've learnt that it is also possible to use
map[MyType]struct{}
Any benefits of using the empty struct versus interface{}.
Memory usage. For example, types struct{}, interface{}, and bool,
package main
import (
"fmt"
"unsafe"
)
func main() {
var s struct{}
fmt.Println(unsafe.Sizeof(s))
var i interface{}
fmt.Println(unsafe.Sizeof(i))
var b bool
fmt.Println(unsafe.Sizeof(b))
}
Output (bytes for 32-bit architecture):
0
8
1
Output (bytes for 64-bit architecture):
0
16
1
References:
Go Data Structures: Interfaces
The empty struct and empty interface, though syntactically similar, are actually opposites. An empty struct holds no data; an empty interface can hold any type of value. If I see a map[MyType]struct{}, I know immediately that no values will be stored, only keys. If I see a map[MyType]interface{}, my first impression will be that it is a heterogenous collection of values. Even if I see code storing nil in it, I won't know for sure that some other piece of code doesn't store something else in it.
In other words, using struct{} makes your code much more readable. It also saves a little memory, as described in the other answer, but that is just a fringe benefit of using the right tool for the job.
I would like to add additional detail about empty struct , as differences are already covered by andybalholm and peterSO .
Below is the example which shows usability of empty struct .
Creates an instance of rectangle struct by using a pointer address
operator is denoted by & symbol.
package main
import "fmt"
type rectangle struct {
length int
breadth int
color string
}
func main() {
var rect1 = &rectangle{10, 20, "Green"} // Can't skip any value
fmt.Println(rect1)
var rect2 = &rectangle{}
rect2.length = 10
rect2.color = "Red"
fmt.Println(rect2) // breadth skipped
var rect3 = &rectangle{}
(*rect3).breadth = 10
(*rect3).color = "Blue"
fmt.Println(rect3) // length skipped
}
Reference : https://www.golangprograms.com/go-language/struct.html
For a thorough read you can refer : https://dave.cheney.net/2014/03/25/the-empty-struct