https://github.com/golang/go/blob/master/src/container/list/list.go#L49
I am having hard time why I am getting cannot assign to pointer error in Go.
Here's the code that works: http://play.golang.org/p/P9FjK8A-32 which is same as Go's original container/list code
type List struct {
root Element
len int
}
type Element struct {
next, prev *Element
list *List
Value interface{}
}
The original code has root as a value and reference it everytime it needs to be in pointer type but why not at first place define root as a pointer?
type List struct {
root *Element
len int
}
type Element struct {
next, prev *Element
list *List
Value interface{}
}
This give me an error: http://play.golang.org/p/1gCAR_rcx1 -> invalid memory address or nil pointer dereference
Why am I getting this error?
Why does Go define root as a non-pointer value when it defines next, and prev as pointers?
Thanks
A pointer is nil by default and needs to be initialized.
This:
// Init initializes or clears list l.
func (l *List) Init() *List {
l.root.next = l.root
l.root.prev = l.root
l.len = 0
return l
}
should become this:
// Init initializes or clears list l.
func (l *List) Init() *List {
l.root = new(Element) // necessary to avoid dereferencing a nil pointer
l.root.next = l.root
l.root.prev = l.root
l.len = 0
return l
}
Demo at http://play.golang.org/p/EYSscTMYnn
In the case of the standard library, it is not necessary to have root be a pointer, however, for prev and next it is necessary, otherwise the struct definition would be recursive, which is not allowed, because it would in theory cause a struct of infinite size...
Related
So I have some interfaces and structs:
type Component interface{}
type Position struct{
x float64
}
func Main(){
var components []Components
components = append(components, &Position{1.0})
pos := components[0] // this is a Component, however reflect.TypeOf() returns *Position
*pos = Position{2.0} // this won't compile as golang says you can't dereference a 'Component'
}
How would I modify the actual value (e.g. change 'x') inside the pos variable one I retrieved it? I am storing these pointers in a Component slice as there are various types that implement components.
I have tried doing this:
func Swap(component *Component, value Component){
*component = value
}
however this does not work (it runs however the new value is not udpated). How do I dereference the component and assign its value?
You should use type assertions:
package main
import (
"fmt"
)
type Component interface{}
type Position struct {
x float64
}
func (p Position) String() string {
return fmt.Sprintf("%f", p.x)
}
func main() {
components := []Component{&Position{1.0}}
fmt.Println(components)
pos, ok := components[0].(*Position)
if !ok {
panic("Not a *Position")
}
pos.x = 1000.0
fmt.Println(components)
}
This prints:
[1.000000]
[1000.000000]
If you need to check for multiple types, you could use a type switch.
I have the following structure in Golang
type mystruct struct {
Name string
Power int
}
My purpose is to write a function that takes as input a slice of type *mystuct and returns a slice of type int containing the "Power" property taken from the input slice.
my code is presented below:
package main
import (
"fmt"
)
func main() {
obj := make([]*mystruct, 15)
for i, s := range obj {
s.Power = i
}
fmt.Println(extractpowers(obj))
}
func extractpowers(obj []*mystruct) []int {
powers := make([]int, len(obj))
for i, s := range obj {
powers[i] = s.Power
}
return powers
}
My issue is that the obj := make([]*mystruct, 15) creates a slices of 15 *mystruc pointers initialized to nil; which causes the code within the for loop to raise a panic of type "invalid memory or nil pointer dereference".
My question is what is the proper and fastest way to initialize the slice; (the equivalent of var lst = new List(Of mystruct) in .net)
Regards.
Use a composite literal and take its address in the loop:
for i := range obj {
obj[i] = &mystruct{Power: i}
}
Try it on the Go Playground.
For example
var myStructRef *Vertex
var myStruct Vertex
myStructRef = &Vertex{2, 3}
myStruct = Vertex{2, 3}
fmt.Println(myStructRef)
fmt.Println(myStruct)
changeByReferenceStruct(myStructRef)
changeByValueStruct(myStruct)
fmt.Println(myStructRef)
fmt.Println(myStruct)
And
func changeByValueStruct(myStruct Vertex) {
myStruct.X = 5
fmt.Println(myStruct)
}
func changeByReferenceStruct(myStruct *Vertex) {
myStruct.X = 7
fmt.Println(myStruct)
}
Isn't both myStructRef *Vertex and myStruct Vertex a pointer pointing to the struct itself? Why is there a discrepancy in behavior when I modify the struct in a function?
Is golang creating a new struct in changeByValueStruct when it resolves the parameter?
When you pass a pointer as an argument, what happens under the hood is that a copy of that pointer is created and passed to the underlying function. It should not be confused with pass-by-reference.
Let's look at an example to better grasp it:
package main
import (
"fmt"
)
type Point struct {
x int
y int
}
func (p Point) String() string {
return fmt.Sprintf("(%d, %d)", p.x, p.y)
}
func modifyValue(point Point) {
point.x += 10
}
func modifyPointer(point *Point) {
point.x = 5
point.y = 5
}
func modifyReference(point *Point) {
point = &Point{5, 5}
}
func main() {
p := Point{0, 0}
fmt.Println(p) // prints (0, 0)
modifyValue(p)
fmt.Println(p) // prints (0, 0)
modifyPointer(&p)
fmt.Println(p) // prints (5, 5)
p = Point{0, 0}
modifyReference(&p)
fmt.Println(p) // prints (0, 0)
}
What happens inside the modifyValue function is that a totally different instance of a Point structure is modified, so the value passed when calling the function is unaffected.
In the second example, a pointer to the structure is passed so the fields of the structure can be modified in a way that is visible from outside.
The most interesting point is made by the last function, modifyReference. If you are familiar with the pass by reference paradigm available in other languages you would expect to be able to modify the referenced object altogether, but this doesn't happen. It's because you're modifying a copy of the pointer passed as argument.
You may wonder, if everything is passed by value, when should you pass pointers and when values. Passing values assures the caller function that the passed structure cannot suffer any changes, so when you need this behaviour, go for the value. The downside of this is that a copy of the entire object is made and, if it is too big, memory becomes a concern.
If you're passing a big structure as an argument, using a pointer is better because it saves space, but you lose the guarantee that the object won't suffer any changes.
Passing struct to function argument makes copy of values. And passing pointer of struct doesn't. So passing struct can't update field value.
package main
import (
"fmt"
)
type Foo struct {
value int
}
func PassStruct(foo Foo) {
foo.value = 1
}
func PassStructPointer(foo *Foo) {
foo.value = 1
}
func main() {
var foo Foo
fmt.Printf("before PassStruct: %v\n", foo.value)
PassStruct(foo)
fmt.Printf("after PassStruct: %v\n", foo.value)
fmt.Printf("before PassStructPointer: %v\n", foo.value)
PassStructPointer(&foo)
fmt.Printf("after PassStructPointer: %v\n", foo.value)
}
https://play.golang.org/p/AM__JwyaJa
This is a very straight forward question.
How do you implement Initialize() below with reflect?
Or is this possible?
func Initialize(v interface{}) {
// ... some reflection code
}
type MyType struct {
Name string
}
func main() {
var val *MyType
// val is nil before initialize
Initialize(val)
// val is now &MyType{Name: ""}
// ...
}
```
Here's how to do it:
func Initialize(v interface{}) {
rv := reflect.ValueOf(v).Elem()
rv.Set(reflect.New(rv.Type().Elem()))
}
This function must be called with a pointer to the value to set:
Initialize(&val)
playground example
The code in this answer panics if the argument type is not a pointer to a pointer. Depending on your use, you might want to check the reflect value kind before calling Elem().
I'm confused as to why line 15 is not valid. Why can't a pointer to a big.Int be dereferenced, whilst a pointer to an int can?
package main
import (
"fmt"
"big"
)
func main() {
var c *int = getPtr()
fmt.Println(c)
fmt.Println(*c)
var d *big.Int = big.NewInt(int64(0))
fmt.Println(d)
// does not compile - implicit assignment of big.Int
// field 'neg' in function argument
//fmt.Println(*d)
}
func getPtr() *int {
var a int = 0
var b *int = &a
return b
}
It's because Int is a struct with unexported fields. When you pass a struct by value to a function, you're making a copy of it. The Go spec states that for this to be legal
...either all fields of T must be
exported, or the assignment must be in
the same package in which T is
declared. In other words, a struct
value can be assigned to a struct
variable only if every field of the
struct may be legally assigned
individually by the program.